{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Novelty detection with Local Outlier Factor (LOF)\n\nThe Local Outlier Factor (LOF) algorithm is an unsupervised anomaly detection\nmethod which computes the local density deviation of a given data point with\nrespect to its neighbors. It considers as outliers the samples that have a\nsubstantially lower density than their neighbors. This example shows how to\nuse LOF for novelty detection. Note that when LOF is used for novelty\ndetection you MUST not use predict, decision_function and score_samples on the\ntraining set as this would lead to wrong results. You must only use these\nmethods on new unseen data (which are not in the training set). See\n`User Guide <outlier_detection>`: for details on the difference between\noutlier detection and novelty detection and how to use LOF for outlier\ndetection.\n\nThe number of neighbors considered, (parameter n_neighbors) is typically\nset 1) greater than the minimum number of samples a cluster has to contain,\nso that other samples can be local outliers relative to this cluster, and 2)\nsmaller than the maximum number of close by samples that can potentially be\nlocal outliers.\nIn practice, such information is generally not available, and taking\nn_neighbors=20 appears to work well in general.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Authors: The scikit-learn developers\n# SPDX-License-Identifier: BSD-3-Clause\n\nimport matplotlib\nimport matplotlib.lines as mlines\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom sklearn.neighbors import LocalOutlierFactor\n\nnp.random.seed(42)\n\nxx, yy = np.meshgrid(np.linspace(-5, 5, 500), np.linspace(-5, 5, 500))\n# Generate normal (not abnormal) training observations\nX = 0.3 * np.random.randn(100, 2)\nX_train = np.r_[X + 2, X - 2]\n# Generate new normal (not abnormal) observations\nX = 0.3 * np.random.randn(20, 2)\nX_test = np.r_[X + 2, X - 2]\n# Generate some abnormal novel observations\nX_outliers = np.random.uniform(low=-4, high=4, size=(20, 2))\n\n# fit the model for novelty detection (novelty=True)\nclf = LocalOutlierFactor(n_neighbors=20, novelty=True, contamination=0.1)\nclf.fit(X_train)\n# DO NOT use predict, decision_function and score_samples on X_train as this\n# would give wrong results but only on new unseen data (not used in X_train),\n# e.g. X_test, X_outliers or the meshgrid\ny_pred_test = clf.predict(X_test)\ny_pred_outliers = clf.predict(X_outliers)\nn_error_test = y_pred_test[y_pred_test == -1].size\nn_error_outliers = y_pred_outliers[y_pred_outliers == 1].size\n\n# plot the learned frontier, the points, and the nearest vectors to the plane\nZ = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])\nZ = Z.reshape(xx.shape)\n\nplt.title(\"Novelty Detection with LOF\")\nplt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)\na = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors=\"darkred\")\nplt.contourf(xx, yy, Z, levels=[0, Z.max()], colors=\"palevioletred\")\n\ns = 40\nb1 = plt.scatter(X_train[:, 0], X_train[:, 1], c=\"white\", s=s, edgecolors=\"k\")\nb2 = plt.scatter(X_test[:, 0], X_test[:, 1], c=\"blueviolet\", s=s, edgecolors=\"k\")\nc = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c=\"gold\", s=s, edgecolors=\"k\")\nplt.axis(\"tight\")\nplt.xlim((-5, 5))\nplt.ylim((-5, 5))\nplt.legend(\n    [mlines.Line2D([], [], color=\"darkred\"), b1, b2, c],\n    [\n        \"learned frontier\",\n        \"training observations\",\n        \"new regular observations\",\n        \"new abnormal observations\",\n    ],\n    loc=(1.05, 0.4),\n    prop=matplotlib.font_manager.FontProperties(size=11),\n)\nplt.xlabel(\n    \"errors novel regular: %d/40 ; errors novel abnormal: %d/40\"\n    % (n_error_test, n_error_outliers)\n)\nplt.tight_layout()\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.14"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}