博客專欄

        EEPW首頁 > 博客 > 14種異常檢測方法匯總(附代碼)!(1)

        14種異常檢測方法匯總(附代碼)!(1)

        發布人:計算機視覺工坊 時間:2022-09-26 來源:工程師 發布文章
        作者丨Ai

        來源丨尤而小屋編輯丨Peter

        今天給大家分享一篇關于異常檢測的文章,重點介紹了14種公開網絡上一些常見的異常檢測方法(附資料來源和代碼)。

        圖片

        一、基于分布的方法1. 3sigma

        基于正態分布,3sigma準則認為超過3sigma的數據為異常點。圖片圖1: 3sigma

        def three_sigma(s):
            mu, std = np.mean(s), np.std(s)
            lower, upper = mu-3*std, mu+3*std
            return lower, upper
        2. Z-score

        Z-score為標準分數,測量數據點和平均值的距離,若A與平均值相差2個標準差,Z-score為2。當把Z-score=3作為閾值去剔除異常點時,便相當于3sigma。

        def z_score(s):
          z_score = (s - np.mean(s)) / np.std(s)
          return z_score
        3. boxplot

        箱線圖時基于四分位距(IQR)找異常點的。圖片圖2: boxplot

        def boxplot(s):
            q1, q3 = s.quantile(.25), s.quantile(.75)
            iqr = q3 - q1
            lower, upper = q1 - 1.5*iqr, q3 + 1.5*iqr
            return lower, upper
        4. Grubbs假設檢驗

        資料來源:

        [1] 時序預測競賽之異常檢測算法綜述 - 魚遇雨欲語與余,知乎:https://zhuanlan.zhihu.com/p/336944097[2] 剔除異常值柵格計算器_數據分析師所需的統計學:異常檢測 - weixin_39974030,CSDN:https://blog.csdn.net/weixin_39974030/article/details/112569610

        Grubbs’Test為一種假設檢驗的方法,常被用來檢驗服從正態分布的單變量數據集(univariate data set)Y中的單個異常值。若有異常值,則其必為數據集中的最大值或最小值。原假設與備擇假設如下:

        • H0: 數據集中沒有異常值

        • H1: 數據集中有一個異常值

        使用Grubbs測試需要總體是正態分布的。算法流程:1. 樣本從小到大排序2. 求樣本的mean和dev3. 計算min/max與mean的差距,更大的那個為可疑值4. 求可疑值的z-score (standard score),如果大于Grubbs臨界值,那么就是outlierGrubbs臨界值可以查表得到,它由兩個值決定:檢出水平α(越嚴格越小),樣本數量n,排除outlier,對剩余序列循環做 1-4 步驟 [1]。詳細計算樣例可以參考。

        from outliers import smirnov_grubbs as grubbs
        print(grubbs.test([891019], alpha=0.05))
        print(grubbs.min_test_outliers([891019], alpha=0.05))
        print(grubbs.max_test_outliers([891019], alpha=0.05))
        print(grubbs.max_test_indices([8910509], alpha=0.05))

        局限:1、只能檢測單維度數據2、無法精確的輸出正常區間3、它的判斷機制是“逐一剔除”,所以每個異常值都要單獨計算整個步驟,數據量大吃不消。4、需假定數據服從正態分布或近正態分布

        二、基于距離的方法1. KNN

        資料來源:

        [3] 異常檢測算法之(KNN)-K Nearest Neighbors - 小伍哥聊風控,知乎:https://zhuanlan.zhihu.com/p/501691799

        依次計算每個樣本點與它最近的K個樣本的平均距離,再利用計算的距離與閾值進行比較,如果大于閾值,則認為是異常點。優點是不需要假設數據的分布,缺點是僅可以找出全局異常點,無法找到局部異常點。

        from pyod.models.knn import KNN

        # 初始化檢測器clf
        clf = KNN( method='mean', n_neighbors=3, )
        clf.fit(X_train)
        # 返回訓練數據上的分類標簽 (0: 正常值, 1: 異常值)
        y_train_pred = clf.labels_
        # 返回訓練數據上的異常值 (分值越大越異常)
        y_train_scores = clf.decision_scores_
        三、基于密度的方法1. Local Outlier Factor (LOF)

        資料來源:

        [4] 一文讀懂異常檢測 LOF 算法(Python代碼)- 東哥起飛,知乎:https://zhuanlan.zhihu.com/p/448276009

        LOF是基于密度的經典算法(Breuning et. al. 2000),通過給每個數據點都分配一個依賴于鄰域密度的離群因子 LOF,進而判斷該數據點是否為離群點。它的好處在于可以量化每個數據點的異常程度(outlierness)。圖片圖3:LOF異常檢測數據點  的局部相對密度(局部異常因子)為點  鄰域內點的平均局部可達密度跟數據 點  的局部可達密度的比值, 即:數據點P的局部可達密度=P最近鄰的平均可達距離的倒數。距離越大,密度越小。點P到點O的第k可達距離=max(點O的k近鄰距離,點P到點O的距離)。圖片圖4:可達距離點O的k近鄰距離=第k個最近的點跟點O之間的距離。整體來說,LOF算法流程如下:

        • 對于每個數據點,計算它與其他所有點的距離,并按從近到遠排序;

        • 對于每個數據點,找到它的K-Nearest-Neighbor,計算LOF得分。

        from sklearn.neighbors import LocalOutlierFactor as LOF

        X = [[-1.1], [0.2], [100.1], [0.3]]
        clf = LOF(n_neighbors=2)
        res = clf.fit_predict(X)
        print(res)
        print(clf.negative_outlier_factor_)
        2. Connectivity-Based Outlier Factor (COF)

        資料來源:

        [5] Nowak-Brzezińska, A., & Horyń, C. (2020). Outliers in rules-the comparision of LOF, COF and KMEANS algorithms. *Procedia Computer Science*, *176*, 1420-1429.[6] 機器學習_學習筆記系列(98):基於連接異常因子分析(Connectivity-Based Outlier Factor)  - 劉智皓 (Chih-Hao Liu)

        COF是LOF的變種,相比于LOF,COF可以處理低密度下的異常值,COF的局部密度是基于平均鏈式距離計算得到。在一開始的時候我們一樣會先計算出每個點的k-nearest neighbor。而接下來我們會計算每個點的Set based nearest Path,如下圖:圖片圖5:Set based nearest Path假使我們今天我們的k=5,所以F的neighbor為B、C、D、E、G。而對于F離他最近的點為E,所以SBN Path的第一個元素是F、第二個是E。離E最近的點為D所以第三個元素為D,接下來離D最近的點為C和G,所以第四和五個元素為C和G,最后離C最近的點為B,第六個元素為B。所以整個流程下來,F的SBN Path為{F, E, D, C, G, C, B}。而對于SBN Path所對應的距離e={e1, e2, e3,…,ek},依照上面的例子e={3,2,1,1,1}。所以我們可以說假使我們想計算p點的SBN Path,我們只要直接計算p點和其neighbor所有點所構成的graph的minimum spanning tree,之后我們再以p點為起點執行shortest path算法,就可以得到我們的SBN Path。而接下來我們有了SBN Path我們就會接著計算,p點的鏈式距離:有了ac_distance后,我們就可以計算COF:

        # https://zhuanlan.zhihu.com/p/362358580
        from pyod.models.cof import COF
        cof = COF(contamination = 0.06,  ## 異常值所占的比例
                  n_neighbors = 20,      ## 近鄰數量
                )
        cof_label = cof.fit_predict(iris.values) # 鳶尾花數據
        print("檢測出的異常值數量為:",np.sum(cof_label == 1))
        3. Stochastic Outlier Selection (SOS)

        資料來源:

        [7] 異常檢測之SOS算法 - 呼廣躍,知乎:https://zhuanlan.zhihu.com/p/34438518

        將特征矩陣(feature martrix)或者相異度矩陣(dissimilarity matrix)輸入給SOS算法,會返回一個異常概率值向量(每個點對應一個)。SOS的思想是:當一個點和其它所有點的關聯度(affinity)都很小的時候,它就是一個異常點。圖片圖6:SOS計算流程SOS的流程:

        1. 計算相異度矩陣D;

        2. 計算關聯度矩陣A;

        3. 計算關聯概率矩陣B;

        4. 算出異常概率向量。

        相異度矩陣D是各樣本兩兩之間的度量距離, 比如歐式距離或漢明距離等。關聯度矩陣反映的是 度量距離方差, 如圖7, 點  的密度最大, 方差最小;  的密度最小, 方差最大。而關聯概率 矩陣  (binding probability matrix)就是把關聯矩陣(affinity matrix)按行歸一化得到的, 如圖 8 所 示。圖片圖7:關聯度矩陣中密度可視化圖片圖8:關聯概率矩陣得到了binding probability matrix,每個點的異常概率值就用如下的公式計算,當一個點和其它所有點的關聯度(affinity)都很小的時候,它就是一個異常點。

        # Ref: https://github.com/jeroenjanssens/scikit-sos
        import pandas as pd
        from sksos import SOS
        iris = pd.read_csv("http://bit.ly/iris-csv")
        X = iris.drop("Name", axis=1).values
        detector = SOS()
        iris["score"] = detector.predict(X)
        iris.sort_values("score", ascending=False).head(10)
        四、基于聚類的方法1. DBSCAN

        DBSCAN算法(Density-Based Spatial Clustering of Applications with Noise)的輸入和輸出如下,對于無法形成聚類簇的孤立點,即為異常點(噪聲點)。

        • 輸入:數據集,鄰域半徑Eps,鄰域中數據對象數目閾值MinPts;

        • 輸出:密度聯通簇。

        圖片圖9:DBSCAN處理流程如下:

        1. 從數據集中任意選取一個數據對象點p;

        2. 如果對于參數Eps和MinPts,所選取的數據對象點p為核心點,則找出所有從p密度可達的數據對象點,形成一個簇;

        3. 如果選取的數據對象點 p 是邊緣點,選取另一個數據對象點;

        4. 重復以上2、3步,直到所有點被處理。

        # Ref: https://zhuanlan.zhihu.com/p/515268801
        from sklearn.cluster import DBSCAN
        import numpy as np
        X = np.array([[12], [22], [23],
                      [87], [88], [2580]])
        clustering = DBSCAN(eps=3, min_samples=2).fit(X)

        clustering.labels_
        array([ 0,  0,  0,  1,  1-1])
        # 0,,0,,0:表示前三個樣本被分為了一個群
        # 1, 1:中間兩個被分為一個群
        # -1:最后一個為異常點,不屬于任何一個群


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。

        物聯網相關文章:物聯網是什么




        關鍵詞: AI

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 银川市| 阿荣旗| 金平| 新平| 韩城市| 湾仔区| 巴东县| 台南市| 米脂县| 美姑县| 南和县| 安吉县| 南丹县| 西峡县| 桃园市| 高雄市| 安西县| 疏附县| 大同市| 嘉鱼县| 永新县| 偃师市| 徐州市| 长子县| 永善县| 海门市| 龙陵县| 吉安县| 弥勒县| 东海县| 深圳市| 政和县| 玛曲县| 隆尧县| 黄平县| 阿拉善盟| 旬阳县| 法库县| 吕梁市| 清丰县| 定远县|