前言:
LOF:Local outlier factor,即局部異常因子。LOF主要是通過比較每個點p和其鄰域點的密度來判斷該點是否為異常點,如果點p的密度越低,越可能被認定是異常點。至于密度,是通過點之間的距離來計算的,點之間距離越遠,密度越低,距離越近,密度越高,完全符合我們的理解。而且,因為lof對密度的計算是通過點的k鄰域來計算,而不是全局計算,因此得名為“局部”異常因子。即LOF是基于密度分析,通過局部的數據密度來檢測異常。
原理
LOF算法,是基于密度的離群點檢測方法中一個比較有代表性的算法。該算法會給數據集中的每個點計算一個離群因子LOF,通過判斷LOF是否接近于1來判定是否是離群因子。若LOF遠大于1,則認為是離群因子,接近于1,則是正常點。
為了敘述LOF算法,首先引入以下概念:
(1)對象p的k距離(距離對象p最近的第k個對象的距離)
對于正整數k,對象p的k距離可記作k-distance§。在樣本空間中,存在對象o,它與對象p之間的距離記做d(p,o)。如果滿足以下兩個條件,我們則認為k-distance§=d(p,o):
1)在樣本空間中,至少存在k個對象q,使得d(p,q)<=d(d,o);
2)在樣本空間中,至多存在k-1個對象q,使得d(p,q)<d(p,o)。
k?distance§=max||p?o||(樣本o和p的最大距離即p的k鄰域的最大距離)
顯然易見,如果使用k?distance§來量化對象p的局部空間區域范圍,那么對于對象密度較大的區域,k?distance§值較小,而對象密度較小的區域,k?distance§值較大。
(2)對象p的第k距離領域
已經對象p的第k距離,那么,與對象p之間距離小于等于k?distance§的對象集合稱為對象p的第k距離領域,記作:Nk§
該領域其實是以p為中心, k?distance§為半徑的區域內所有對象的集合(不包括p本身)。由于可能同時存在多個第k距離的數據,因此該集合至少包括k個對象。可以想象,離群度越大的對象的范圍往往比較大,而離群度比較小的對象范圍小。
(3)對象p相對于對象o的可達距離
公式:reachdist(p,o)=max{k?distance(o),||p?o||}
公式的理解可以參考下圖,對于兩個不同的點p1和p2,它們的可達距離計算是不一樣的,對p1來說,因為p1 在 o 的 k 鄰域內(可以看出這里的k=3),所以它們的距離就是 k-distance(o) 的距離,也就是等于圓的半徑;而對于p2,很明顯它不在o的k鄰域內,所以它的可達距離就是實際距離,也就是這兩點之間的距離。
(4)局部可達密度
對象p的局部可達密度定義為p的k最近鄰點的平均可達距離的倒數(實質也就是p的第k距離鄰域內所有可達距離的平均值的導數。越大越好,代表數據聚的越緊湊)
(5)局部離群點因子
如果這個比值越接近1,說明p和其K距離鄰域內的點密度差不多,p可能和其K距離鄰域內的點同屬一簇;如果這個比值越小于1,說明p的密度高于其鄰域內其他點的密度,p為密集點;如果這個比值越大于1,說明p的密度小于其鄰域內其他點的密度,p越可能是異常點。通過這種方式就能在樣本空間數據分布不均勻的情況下也可以準確發現離群點。
可以想象下,一個離群點p,它的lrdk(o)是遠大于lrdk§的,通過特例很容易看出,這樣該算法就可以很好的理解了
優缺點
優點:
LOF算法是一種非監督算法
LOF算法是一種基于密度的算法
LOF算法適合于對不同密度的數據的異常檢測
缺點:
檢測的數據必須有明顯的密度差異
計算比較復雜
應用場景有限
調參
LOF(self, n_neighbors=20, algorithm='auto', leaf_size=30,metric='minkowski', p=2, metric_params=None,contamination=0.1, n_jobs=1)n_neighbors:(int,optional (default = 20 )) - 默認情況下用于kneighbors查詢的鄰居數。如果n_neighbors大于提供的樣本數,則將使用所有樣本。Algorithm:({‘auto’ ,‘ball_tree’ ,‘kd_tree’ ,‘brute’} ,可選) -
用于計算最近鄰居的算法:
'ball_tree’將使用BallTree
'kd_tree’將使用KDTree
'brute’將使用蠻力搜索。
'auto’將嘗試根據傳遞給fit()方法的值來確定最合適的算法。
注意:在稀疏輸入上擬合將使用強力來覆蓋此參數的設置。leaf_size:(int,optional (default = 30 )) - 傳遞給BallTree或KDTree的葉子大小。
這可能會影響構造和查詢的速度,以及存儲樹所需的內存。最佳值取決于問題的性質。Metric:(字符串或可調用,默認’minkowski’) -用于距離計算的度量。
from scikit-learn: [‘cityblock’, ‘cosine’, ‘euclidean’, ‘l1’, ‘l2’, ‘manhattan’]
from scipy.spatial.distance: [‘braycurtis’, ‘canberra’, ‘chebyshev’, ‘correlation’, ‘dice’, ‘hamming’, ‘jaccard’, ‘kulsinski’, ‘mahalanobis’, ‘matching’, ‘minkowski’, ‘rogerstanimoto’, ‘russellrao’, ‘seuclidean’, ‘sokalmichener’, ‘sokalsneath’, ‘sqeuclidean’, ‘yule’]p:(整數,可選(默認值= 2 )) - 來自sklearn.metrics.pairwise.pairwise_distances的Minkowski度量的參數。
當p = 1時,這相當于使用manhattan_distance(l1)。
對于p = 2使用euclidean_distance(l2)。
對于任意p,使用minkowski_distance(l_p)
總結
經實踐,發現該算法在面對數據量較大的場景時,執行效率較低。作為基于密度的算法,效果比KNN要好,面對適當的場景,可以嘗試法使用。