2.7. 新奇與離群值偵測#

許多應用程式需要能夠判斷新的觀測值是否屬於與現有觀測值相同的分佈(它是內部值),或者應該被視為不同(它是離群值)。 通常,此能力用於清理真實資料集。 必須做出兩個重要的區分

離群值偵測:

訓練資料包含離群值,這些離群值定義為遠離其他觀測值的觀測值。 因此,離群值偵測估計器會嘗試擬合訓練資料最集中的區域,而忽略偏差觀測值。

新奇偵測:

訓練資料未受離群值污染,我們有興趣偵測觀測值是否為離群值。 在這種情況下,離群值也稱為新奇值。

離群值偵測和新奇偵測都用於異常偵測,其中人們有興趣偵測異常或不尋常的觀測值。 因此,離群值偵測也稱為非監督式異常偵測,而新奇偵測則稱為半監督式異常偵測。 在離群值偵測的環境中,離群值/異常值無法形成密集叢集,因為可用的估計器假設離群值/異常值位於低密度區域。 相反地,在新奇偵測的環境中,只要新奇值/異常值位於訓練資料的低密度區域,它們就可以形成密集叢集,在此環境中被視為正常。

scikit-learn 專案提供了一組機器學習工具,可用於新奇偵測或離群值偵測。 此策略是透過從資料中以非監督方式學習的物件來實作

estimator.fit(X_train)

然後可以使用 predict 方法將新的觀測值分類為內部值或離群值

estimator.predict(X_test)

內部值標記為 1,而離群值標記為 -1。 predict 方法使用估計器計算的原始評分函數的閾值。 這個評分函數可以透過 score_samples 方法存取,而閾值可以透過 contamination 參數控制。

decision_function 方法也是從評分函數定義的,以便負值是離群值,而非負值是內部值

estimator.decision_function(X_test)

請注意,neighbors.LocalOutlierFactor 預設不支援 predictdecision_functionscore_samples 方法,而僅支援 fit_predict 方法,因為此估計器最初旨在用於離群值偵測。 訓練樣本的異常分數可以透過 negative_outlier_factor_ 屬性存取。

如果您真的想將 neighbors.LocalOutlierFactor 用於新奇偵測,即預測標籤或計算新的未見資料的異常分數,您可以在擬合估計器之前將 novelty 參數設定為 True 來實例化估計器。 在這種情況下,fit_predict 不可用。

警告

使用局部離群值因子進行新奇偵測

novelty 設定為 True 時,請注意您只能對新的未見資料使用 predictdecision_functionscore_samples,而不能對訓練樣本使用,因為這會導致錯誤的結果。 也就是說,predict 的結果將與 fit_predict 的結果不同。 訓練樣本的異常分數始終可以透過 negative_outlier_factor_ 屬性存取。

neighbors.LocalOutlierFactor 的行為總結在下表中。

方法

離群值偵測

新奇偵測

fit_predict

確定

不可用

predict

不可用

僅在新資料上使用

decision_function

不可用

僅在新資料上使用

score_samples

使用 negative_outlier_factor_

僅在新資料上使用

negative_outlier_factor_

確定

確定

2.7.1. 離群值偵測方法概述#

scikit-learn 中離群值偵測演算法的比較。 局部離群值因子 (LOF) 沒有顯示黑色決策邊界,因為當它用於離群值偵測時,它沒有適用於新資料的 predict 方法。

../_images/sphx_glr_plot_anomaly_comparison_001.png

ensemble.IsolationForestneighbors.LocalOutlierFactor 在這裡考慮的數據集上表現相當不錯。svm.OneClassSVM 已知對離群值敏感,因此在離群值偵測方面表現不佳。儘管如此,在高維度或在沒有對內圍數據分佈做任何假設的情況下進行離群值偵測是非常具挑戰性的。svm.OneClassSVM 仍然可以用於離群值偵測,但需要微調其超參數 nu 以處理離群值並防止過度擬合。linear_model.SGDOneClassSVM 提供了一個線性 One-Class SVM 的實現,其複雜度與樣本數量呈線性關係。此實現使用核近似技術來獲得與 svm.OneClassSVM 類似的結果,後者預設使用高斯核。最後,covariance.EllipticEnvelope 假設數據呈高斯分佈並學習一個橢圓。有關不同估計器的更多詳細資訊,請參閱範例 比較玩具數據集上的異常偵測演算法以進行離群值偵測 和以下章節。

範例

2.7.2. 新奇偵測#

考慮一個由 \(n\) 個來自相同分佈的觀測值組成的數據集,該分佈由 \(p\) 個特徵描述。現在考慮我們向該數據集添加一個觀測值。新的觀測值與其他觀測值如此不同,以至於我們懷疑它是否正常嗎?(也就是說,它是否來自相同的分佈?)或者相反,它是否與其他觀測值如此相似,以至於我們無法將其與原始觀測值區分開來?這是新奇偵測工具和方法要解決的問題。

一般而言,它是關於學習一個粗略、接近的邊界,該邊界劃定了以嵌入式 \(p\) 維空間繪製的初始觀測值分佈的輪廓。然後,如果進一步的觀測值落在邊界劃定的子空間內,則認為它們來自與初始觀測值相同的群體。否則,如果它們落在邊界之外,我們可以說它們是不正常的,並且對我們的評估有給定的信心。

Schölkopf 等人為此目的引入了 One-Class SVM,並在 支援向量機 模組中以 svm.OneClassSVM 物件的形式實現。它需要選擇一個核和一個標量參數來定義邊界。通常選擇 RBF 核,儘管沒有確切的公式或演算法來設定其頻寬參數。這是 scikit-learn 實現中的預設值。nu 參數,也稱為 One-Class SVM 的邊際,對應於在邊界外發現新的但正常的觀測值的機率。

參考文獻

範例

../_images/sphx_glr_plot_oneclass_001.png

2.7.2.1. 擴展 One-Class SVM#

One-Class SVM 的線上線性版本實現在 linear_model.SGDOneClassSVM 中。此實現隨著樣本數量的增加呈線性擴展,並且可以與核近似一起使用,以近似核化的 svm.OneClassSVM 的解,後者的複雜度在樣本數量上最多是二次方的。有關更多詳細資訊,請參閱 線上 One-Class SVM 章節。

範例

2.7.3. 離群值偵測#

離群值偵測類似於新奇偵測,因為目標是將常規觀測值的核心與一些稱為離群值的污染觀測值分開。然而,在離群值偵測的情況下,我們沒有乾淨的數據集來表示可以用於訓練任何工具的常規觀測值群體。

2.7.3.1. 擬合橢圓包絡線#

執行離群值偵測的一種常見方法是假設常規數據來自已知分佈(例如,數據呈高斯分佈)。從這個假設出發,我們通常嘗試定義數據的「形狀」,並且可以將遠離擬合形狀的觀測值定義為離群觀測值。

scikit-learn 提供了一個物件 covariance.EllipticEnvelope,它將穩健的共變數估計擬合到數據,從而將橢圓擬合到中心數據點,忽略中心模式外的點。

例如,假設內圍數據呈高斯分佈,它將以穩健的方式估計內圍位置和共變數(即不受離群值的影響)。從此估計獲得的馬氏距離用於導出離群程度的衡量標準。此策略如下所示。

../_images/sphx_glr_plot_mahalanobis_distances_001.png

範例

參考文獻

  • Rousseeuw, P.J., Van Driessen, K. “最小共變數行列式估計器的快速演算法” Technometrics 41(3), 212 (1999)

2.7.3.2. 隔離森林#

在高維數據集中執行離群值偵測的一種有效方法是使用隨機森林。ensemble.IsolationForest 通過隨機選擇一個特徵,然後在所選特徵的最大值和最小值之間隨機選擇一個分割值來「隔離」觀測值。

由於遞歸分割可以用樹狀結構表示,因此隔離樣本所需的分割次數等效於從根節點到終止節點的路徑長度。

此路徑長度,在這種隨機樹的森林中取平均值,是正常性的度量和我們的決策函數。

隨機分割會產生異常的明顯較短路徑。因此,當隨機樹的森林共同產生特定樣本的較短路徑長度時,它們很可能就是異常值。

ensemble.IsolationForest 的實現基於 tree.ExtraTreeRegressor 的集成。根據 Isolation Forest 的原始論文,每棵樹的最大深度設定為 \(\lceil \log_2(n) \rceil\),其中 \(n\) 是用於建立樹的樣本數量(有關更多詳細資訊,請參閱 (Liu et al., 2008))。

此演算法如下所示。

../_images/sphx_glr_plot_isolation_forest_003.png

>>> from sklearn.ensemble import IsolationForest
>>> import numpy as np
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [0, 0], [-20, 50], [3, 5]])
>>> clf = IsolationForest(n_estimators=10, warm_start=True)
>>> clf.fit(X)  # fit 10 trees  
>>> clf.set_params(n_estimators=20)  # add 10 more trees  
>>> clf.fit(X)  # fit the added trees  

範例

參考文獻

2.7.3.3. 局部離群因子#

../_images/sphx_glr_plot_lof_outlier_detection_001.png

範例

參考文獻

2.7.4. 使用局部離群因子的新穎性偵測#

lof = LocalOutlierFactor(novelty=True)
lof.fit(X_train)

警告

novelty 設定為 True 時,請注意您只能對新的未見資料使用 predictdecision_functionscore_samples,而不能對訓練樣本使用,因為這會導致錯誤的結果。 也就是說,predict 的結果將與 fit_predict 的結果不同。 訓練樣本的異常分數始終可以透過 negative_outlier_factor_ 屬性存取。

../_images/sphx_glr_plot_lof_novelty_detection_001.png