博客專欄

EEPW首頁 > 博客 > 14種異常檢測(cè)方法匯總(附代碼)?。?)

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

發(fā)布人:計(jì)算機(jī)視覺工坊 時(shí)間:2022-09-26 來源:工程師 發(fā)布文章
作者丨Ai

來源丨尤而小屋編輯丨Peter

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

圖片

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

基于正態(tài)分布,3sigma準(zhǔn)則認(rèn)為超過3sigma的數(shù)據(jù)為異常點(diǎn)。圖片圖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為標(biāo)準(zhǔn)分?jǐn)?shù),測(cè)量數(shù)據(jù)點(diǎn)和平均值的距離,若A與平均值相差2個(gè)標(biāo)準(zhǔn)差,Z-score為2。當(dāng)把Z-score=3作為閾值去剔除異常點(diǎn)時(shí),便相當(dāng)于3sigma。

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

箱線圖時(shí)基于四分位距(IQR)找異常點(diǎn)的。圖片圖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假設(shè)檢驗(yàn)

資料來源:

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

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

  • H0: 數(shù)據(jù)集中沒有異常值

  • H1: 數(shù)據(jù)集中有一個(gè)異常值

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

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、只能檢測(cè)單維度數(shù)據(jù)2、無法精確的輸出正常區(qū)間3、它的判斷機(jī)制是“逐一剔除”,所以每個(gè)異常值都要單獨(dú)計(jì)算整個(gè)步驟,數(shù)據(jù)量大吃不消。4、需假定數(shù)據(jù)服從正態(tài)分布或近正態(tài)分布

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

資料來源:

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

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

from pyod.models.knn import KNN

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

資料來源:

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

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

  • 對(duì)于每個(gè)數(shù)據(jù)點(diǎn),計(jì)算它與其他所有點(diǎn)的距離,并按從近到遠(yuǎn)排序;

  • 對(duì)于每個(gè)數(shù)據(jù)點(diǎn),找到它的K-Nearest-Neighbor,計(jì)算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] 機(jī)器學(xué)習(xí)_學(xué)習(xí)筆記系列(98):基於連接異常因子分析(Connectivity-Based Outlier Factor)  - 劉智皓 (Chih-Hao Liu)

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

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

資料來源:

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

將特征矩陣(feature martrix)或者相異度矩陣(dissimilarity matrix)輸入給SOS算法,會(huì)返回一個(gè)異常概率值向量(每個(gè)點(diǎn)對(duì)應(yīng)一個(gè))。SOS的思想是:當(dāng)一個(gè)點(diǎn)和其它所有點(diǎn)的關(guān)聯(lián)度(affinity)都很小的時(shí)候,它就是一個(gè)異常點(diǎn)。圖片圖6:SOS計(jì)算流程SOS的流程:

  1. 計(jì)算相異度矩陣D;

  2. 計(jì)算關(guān)聯(lián)度矩陣A;

  3. 計(jì)算關(guān)聯(lián)概率矩陣B;

  4. 算出異常概率向量。

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

# 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)的輸入和輸出如下,對(duì)于無法形成聚類簇的孤立點(diǎn),即為異常點(diǎn)(噪聲點(diǎn))。

  • 輸入:數(shù)據(jù)集,鄰域半徑Eps,鄰域中數(shù)據(jù)對(duì)象數(shù)目閾值MinPts;

  • 輸出:密度聯(lián)通簇。

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

  1. 從數(shù)據(jù)集中任意選取一個(gè)數(shù)據(jù)對(duì)象點(diǎn)p;

  2. 如果對(duì)于參數(shù)Eps和MinPts,所選取的數(shù)據(jù)對(duì)象點(diǎn)p為核心點(diǎn),則找出所有從p密度可達(dá)的數(shù)據(jù)對(duì)象點(diǎn),形成一個(gè)簇;

  3. 如果選取的數(shù)據(jù)對(duì)象點(diǎn) p 是邊緣點(diǎn),選取另一個(gè)數(shù)據(jù)對(duì)象點(diǎn);

  4. 重復(fù)以上2、3步,直到所有點(diǎn)被處理。

# 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:表示前三個(gè)樣本被分為了一個(gè)群
# 1, 1:中間兩個(gè)被分為一個(gè)群
# -1:最后一個(gè)為異常點(diǎn),不屬于任何一個(gè)群


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。

物聯(lián)網(wǎng)相關(guān)文章:物聯(lián)網(wǎng)是什么




關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉