1. 程式人生 > >異常檢測(三)——Local Outlier Factor(LOF)

異常檢測(三)——Local Outlier Factor(LOF)

在中等高維資料集上執行異常值檢測的另一種有效方法是使用區域性異常因子(Local Outlier Factor ,LOF)演算法。

1、演算法思想

LOF通過計算一個數值score來反映一個樣本的異常程度。這個數值的大致意思是:一個樣本點周圍的樣本點所處位置的平均密度比上該樣本點所在位置的密度。比值越大於1,則該點所在位置的密度越小於其周圍樣本所在位置的密度,這個點就越有可能是異常點。關於密度等理論概念,詳見下面第二部分。

2、LOF的具體理論

關於LOF的理論,可以參考這篇文章,寫的非常詳細具體!

3、LocalOutlierFactor主要引數和函式介紹

class sklearn.neighbors.
LocalOutlierFactor(n_neighbors=20algorithm=’auto’leaf_size=30metric=’minkowski’p=2metric_params=Nonecontamination=0.1n_jobs=1)
1)主要引數       n_neighbors :                  設定k,default=20       contamination :                  設定樣本中異常點的比例,default=0.12)主要屬性:       negative_outlier_factor_ : numpy array, shape (n_samples,)
                 和LOF相反的值,值越小,越有可能是異常點。(注:上面提到LOF的值越接近1,越可能是正常樣本,LOF的值越大於1,則越可能是異常樣本)。這裡就正好反一下。
3)主要函式:        fit_predict(X)
                  X : array-like, shape (n_samples, n_features                  返回一個數組,-1表示異常點,1表示正常點。

4、LOF例項(sklearn)

# !/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import LocalOutlierFactor
from scipy import stats

# 構造訓練樣本
n_samples = 200  #樣本總數
outliers_fraction = 0.25  #異常樣本比例
n_inliers = int((1. - outliers_fraction) * n_samples)
n_outliers = int(outliers_fraction * n_samples)

rng = np.random.RandomState(42)
X = 0.3 * rng.randn(n_inliers // 2, 2)
X_train = np.r_[X + 2, X - 2]   #正常樣本
X_train = np.r_[X_train, np.random.uniform(low=-6, high=6, size=(n_outliers, 2))]  #正常樣本加上異常樣本

# fit the model
clf = LocalOutlierFactor(n_neighbors=35, contamination=outliers_fraction)
y_pred = clf.fit_predict(X_train)
scores_pred = clf.negative_outlier_factor_
threshold = stats.scoreatpercentile(scores_pred, 100 * outliers_fraction)  # 根據異常樣本比例,得到閾值,用於繪圖

# plot the level sets of the decision function
xx, yy = np.meshgrid(np.linspace(-7, 7, 50), np.linspace(-7, 7, 50))
Z = clf._decision_function(np.c_[xx.ravel(), yy.ravel()])  # 類似scores_pred的值,值越小越有可能是異常點
Z = Z.reshape(xx.shape)

plt.title("Local Outlier Factor (LOF)")
# plt.contourf(xx, yy, Z, cmap=plt.cm.Blues_r)

plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), threshold, 7), cmap=plt.cm.Blues_r)  # 繪製異常點區域,值從最小的到閾值的那部分
a = plt.contour(xx, yy, Z, levels=[threshold], linewidths=2, colors='red')  # 繪製異常點區域和正常點區域的邊界
plt.contourf(xx, yy, Z, levels=[threshold, Z.max()], colors='palevioletred')  # 繪製正常點區域,值從閾值到最大的那部分

b = plt.scatter(X_train[:-n_outliers, 0], X_train[:-n_outliers, 1], c='white',
                    s=20, edgecolor='k')
c = plt.scatter(X_train[-n_outliers:, 0], X_train[-n_outliers:, 1], c='black',
                    s=20, edgecolor='k')
plt.axis('tight')
plt.xlim((-7, 7))
plt.ylim((-7, 7))
plt.legend([a.collections[0], b, c],
           ['learned decision function', 'true inliers', 'true outliers'],
           loc="upper left")
plt.show()
結果:

參考文獻:

http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.LocalOutlierFactor.html#sklearn.neighbors.LocalOutlierFactor
http://scikit-learn.org/stable/auto_examples/neighbors/plot_lof.html
http://scikit-learn.org/stable/auto_examples/covariance/plot_outlier_detection.html
https://blog.csdn.net/wangyibo0201/article/details/51705966