Local Outlier Factor Score — Machine Learning/Anomaly Detection
Machine_Learning/Anomaly_Detection/Local_Outlier_Factor_Score · 1 input / 2 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Local Outlier Factor Score
Machine Learning / Anomaly Detection
Scores how much sparser a sample's neighbourhood is than its neighbours' own neighbourhoods – the density-ratio form of novelty detection:
LOF(u) = mean(lrdi) / lrd(u) over the k nearest training points, with lrd(u) = 1 / mean(max(kdisti, di)).
This is LocalOutlierFactor(novelty=True).score_samples negated,
with _fit_X, _distances_fit_X_[:, -1] and
_lrd pasted in. Around 1 means the sample sits in as dense a
region as the points around it; well above 1 means it does not, which is the
whole idea. Unlike a distance threshold, it adapts to regions of different
density – a point far from a sparse cluster is not automatically odd.
Ports
- u – the sample, a column [d,1] matching the d columns of Training Set.
- lof – a scalar [1,1]: the factor itself. Report it, plot it, or threshold it downstream; it is a ratio, so it carries no units.
- outlier – a scalar [1,1]: 1 when lof exceeds Novelty Threshold, otherwise 0. The decision, kept beside the evidence, exactly as One Class SVM Score does.
Parameters
- Training Set – the [N,d] matrix, one training sample per row, which is sklearn's orientation.
- K Distances – an [N,1] column: each training row's
distance to its own k-th nearest neighbour, as fitted. In sklearn this is
_distances_fit_X_[:, -1]. - Local Reachability Densities – an [N,1] column: each
training row's fitted
_lrd. - Neighbors – k, a whole number ≥ 1. It must be the same k the fit used, or the two baked columns describe a different model than the one being evaluated – nothing can detect that mismatch for you.
- Novelty Threshold – the operating point for outlier. 1 is the neutral value; 1.5 is a common starting point.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The training set, both fitted columns, k and the threshold are baked in at export time.
No backend divides at run time. The reciprocal that defines lrd(u)
cancels against the mean it is divided by, leaving
(Σ lrd)(Σ reach) / k² with 1/k²
folded into a constant – two sums and two multiplies.
The three HDL targets are simulation-only real
arithmetic, quantizing only at the port boundary, because the reachability
distance is summed rather than merely ranked and so cannot stay squared.
The same escape hatch Mahalanobis Distance takes, and for the same
reason. The seven software targets are exact.
Simulink bridge
None. Local Outlier Factor belongs to the Statistics and Machine
Learning Toolbox, which is not installed here, and its interface takes a fitted
model object rather than parameters – which no parameter rule could carry
even if it were present. The bridge reports the block rather than dropping it
silently, and it has no parity testbench, which is the documented
consequence of Support::None rather than a gap.
Notes
- Algebraic and stateless: the score depends only on the current sample.
- The fit is baked, not recomputed. k-distances and local reachability densities are properties of the training set measured against itself, so deriving them here would mean re-running the whole fit every sample. Paste them from the fitted model.
- k must match the fit. The two columns were computed at a particular k; evaluating at a different one silently mixes two models. Nothing in the block can detect that, which is why it is said here.
- The selection is KNN Classifier's, verbatim: rank by counting, ties broken toward the lower training row, ranking done on squared distances so it needs no roots.
- Cost is O(N²·d) per sample, inherent to ranking without a stored order – fine for the small baked sets this family targets.
Code facts#
| Fact | Value |
|---|---|
| registered type | Machine_Learning/Anomaly_Detection/Local_Outlier_Factor_Score |
| family | Machine_Learning/Anomaly_Detection |
| solver environment class | ICoreBlock_0_Machine_Learning_1_Anomaly_Detection_2_Local_Outlier_Factor_Score |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Anomaly_Detection/Local_Outlier_Factor_Score/ICoreBlock_0_Machine_Learning_1_Anomaly_Detection_2_Local_Outlier_Factor_Score.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Anomaly_Detection/Local_Outlier_Factor_Score/ICoreBlock_0_Machine_Learning_1_Anomaly_Detection_2_Local_Outlier_Factor_Score.h |
| default size on canvas | 150 × 80 px |
| ports at insert | 1 in, 2 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | u |
| 2 | out | ICoreDouble | lof |
| 3 | out | ICoreDouble | outlier |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Training Set | [0 0; 0.2 0.1; 0.1 0.25; -0.15 0.2; 0.3 -0.2; -0.25 -0.1] | — |
K Distances | [0.35; 0.3; 0.32; 0.36; 0.42; 0.4] | — |
Local Reachability Densities | [3.1; 3.4; 3.2; 2.9; 2.5; 2.7] | — |
Neighbors | 3 | — |
Novelty Threshold | 1.5 | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no Simulink equivalent available here: Local Outlier Factor belongs to the Statistics and Machine Learning Toolbox, which is not installed on this machine, and its interface takes a fitted MODEL OBJECT rather than parameters -- which no ParamRule could carry even if it were present. There is therefore no parameter set to map onto and no reference to run a parity testbench against
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0every stimulus in the sample errored — cross-checks skipped
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Local Outlier Factor — density-ratio novelty against a baked training set d_i = ||u - X_i|| N_k(u) = the k nearest, ranked on d^2 reach_i = max(kdist_i, d_i) LOF = (SUM lrd_i)(SUM reach_i) / k^2
The divisions cancel (see the header), so 1/k^2 is a baked constant and no backend divides at run time. Selection is KNN_Classifier's rank-by-counting, on SQUARED distances, so it costs no roots; the roots appear only in reach_i, which is summed rather than ranked and therefore cannot be left squared.
Sample results#
No stimulus produced a sampled output in this rig — Invalid input size at: ICore Blocks/Home/Local Outlier Factor Score. That is a fact about the single-block rig, not a verdict on the block: an offline batch fit, a block whose output only appears at onSolverFinish, or one that needs a driven environment cannot be exercised alone.
Category unsampled · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60
Sample data: docs/generated/samples/Machine_Learning__Anomaly_Detection__Local_Outlier_Factor_Score.json