Detección de novedades con Local Outlier Factor (LOF)

El algoritmo Local Outlier Factor (LOF) es un método de detección de anomalías no supervisado que calcula la desviación de la densidad local de un punto de datos dado con respecto a sus vecinos. Considera como valores atípicos las muestras que tienen una densidad sustancialmente inferior a la de sus vecinos. Este ejemplo muestra cómo utilizar LOF para la detección de novedades. Ten en cuenta que cuando se usa LOF para la detección de novedades no DEBES utilizar predict, decision_function y score_samples en el conjunto de entrenamiento ya que esto conduciría a resultados erróneos. Sólo debes utilizar estos métodos en datos nuevos no vistos (que no están en el conjunto de entrenamiento). Consulta el Manual de usuario: para obtener detalles sobre la diferencia entre la detección de valores atípicos y la detección de novedades y cómo utilizar LOF para la detección de valores atípicos.

El número de vecinos considerado, (parámetro n_neighbors) suele ser 1) mayor que el número mínimo de muestras que debe contener un conglomerado, de modo que otras muestras puedan ser valores atípicos locales en relación con este conglomerado, y 2) menor que el número máximo de muestras cercanas que pueden ser potencialmente valores atípicos locales. En la práctica, esta información no suele estar disponible, y tomar n_neighbors=20 parece funcionar bien en general.

Novelty Detection with LOF
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from sklearn.neighbors import LocalOutlierFactor

print(__doc__)

np.random.seed(42)

xx, yy = np.meshgrid(np.linspace(-5, 5, 500), np.linspace(-5, 5, 500))
# Generate normal (not abnormal) training observations
X = 0.3 * np.random.randn(100, 2)
X_train = np.r_[X + 2, X - 2]
# Generate new normal (not abnormal) observations
X = 0.3 * np.random.randn(20, 2)
X_test = np.r_[X + 2, X - 2]
# Generate some abnormal novel observations
X_outliers = np.random.uniform(low=-4, high=4, size=(20, 2))

# fit the model for novelty detection (novelty=True)
clf = LocalOutlierFactor(n_neighbors=20, novelty=True, contamination=0.1)
clf.fit(X_train)
# DO NOT use predict, decision_function and score_samples on X_train as this
# would give wrong results but only on new unseen data (not used in X_train),
# e.g. X_test, X_outliers or the meshgrid
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
n_error_test = y_pred_test[y_pred_test == -1].size
n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size

# plot the learned frontier, the points, and the nearest vectors to the plane
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.title("Novelty Detection with LOF")
plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)
a = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='darkred')
plt.contourf(xx, yy, Z, levels=[0, Z.max()], colors='palevioletred')

s = 40
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white', s=s, edgecolors='k')
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='blueviolet', s=s,
                 edgecolors='k')
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='gold', s=s,
                edgecolors='k')
plt.axis('tight')
plt.xlim((-5, 5))
plt.ylim((-5, 5))
plt.legend([a.collections[0], b1, b2, c],
           ["learned frontier", "training observations",
            "new regular observations", "new abnormal observations"],
           loc="upper left",
           prop=matplotlib.font_manager.FontProperties(size=11))
plt.xlabel(
    "errors novel regular: %d/40 ; errors novel abnormal: %d/40"
    % (n_error_test, n_error_outliers))
plt.show()

Tiempo total de ejecución del script: (0 minutos 0.713 segundos)

Galería generada por Sphinx-Gallery