異常檢測 - 基於統計學的方法
阿新 • • 發佈:2021-01-16
技術標籤:AnomalyDetection資料分析python機器學習統計學
github 地址:連結
目錄
1異常檢測—基於統計學的方法
1.1引數方法
假定正常的資料物件被一個以 Θ \Theta Θ為引數的引數分佈產生。該引數分佈的概率密度函式 f ( x , Θ ) f(x,\Theta) f(x,Θ)給出物件 x x x被該分佈產生的概率。該值越小, x x
x越可能是異常點。
-
基於正態分佈的一元異常點檢測
- x ( i ) ∼ N ( μ , σ 2 ) x^{(i)}\sim N(\mu, \sigma^2) x(i)∼N(μ,σ2)
- p ( x ) = 1 2 π σ e x p ( − ( x − μ ) 2 2 σ 2 ) p(x)=\frac 1{\sqrt{2\pi}\sigma}exp(-\frac{(x-\mu)^2}{2\sigma^2}) p(x)=2π σ1exp(−2σ2(x−μ)2)
- 黃色線條是N(o,1)標準正態分佈的概率密度函式圖,我們看到,越靠近均值0的部分,概率密度越大,說明資料落在此點範圍內的可能性更大
- 藍色線條是N(0,0.5)分佈,可以看到,分佈方差 σ \sigma σ越大,資料集中程度越大
- 引數方法,就是先假設原始資料,服從一個分佈函式,然後通過最大似然估計等方法,通過實際樣本的資料,計算出這個分佈的引數( μ , σ \mu,\sigma μ,σ),從而給定新資料的時候,可以根據通過分佈函式p(x),計算出一個概率值,從而判斷新資料是否是異常樣本
-
分量彼此獨立的多元分佈
-
p
(
x
)
=
∏
j
=
1
n
p
(
x
j
;
μ
j
,
σ
j
2
)
=
∏
j
=
1
n
1
2
π
σ
j
e
x
p
(
−
(
x
j
−
μ
j
)
2
2
σ
j
2
)
p(x)=\prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2)=\prod_{j=1}^n\frac 1{\sqrt{2\pi}\sigma_j}exp(-\frac{(x_j-\mu_j)^2}{2\sigma_j^2})
-
p
(
x
)
=
∏
j
=
1
n
p
(
x
j
;
μ
j
,
σ
j
2
)
=
∏
j
=
1
n
1
2
π
σ
j
e
x
p
(
−
(
x
j
−
μ
j
)
2
2
σ
j
2
)
p(x)=\prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2)=\prod_{j=1}^n\frac 1{\sqrt{2\pi}\sigma_j}exp(-\frac{(x_j-\mu_j)^2}{2\sigma_j^2})
-
分量存在相關關係的多元高斯分佈
- p ( x ) = 1 ( 2 π ) n 2 ∣ Σ ∣ 1 2 exp ( − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ) p(x)=\frac{1}{(2 \pi)^{\frac{n}{2}}|\Sigma|^{\frac{1}{2}}} \exp \left(-\frac{1}{2}(x-\mu)^{T} \Sigma^{-1}(x-\mu)\right) p(x)=(2π)2n∣Σ∣211exp(−21(x−μ)TΣ−1(x−μ))
1.2非引數方法
非引數方法,就是不假設資料服從某個分佈,而是通過樣本的實際分佈來作為整體的分佈,然後當給定新樣本後,我們根據此分佈,來判斷新樣本的出現概率,並根據此概率值,決策此樣本是否是異常樣本
- 如上圖的直方圖所示,可以看到直方圖的高度越高,說明在此區間內的樣本量越大,因此可以將方塊的面積,作為概率密度,面積的倒數就可以作為異常度
- 新樣本落在面積比較小的方塊內,異常度就越大
- 難點就在於方塊(箱)的數量選擇,太多,則異常點易落入正常範圍,太少,則正常值易誤判為異常值。
2HBOS方法實踐
HBOS方法簡介:連結
注意:前提假設是樣本的特徵之間相互獨立
2.1pyod中hbos函式簡介
pyod使用簡介:連結
classpyod.models.hbos.HBOS(n_bins=10, alpha=0.1, tol=0.5, contamination=0.1)
- 引數介紹
- n_bins 分割槽也就是分箱的數量
- alpha 正則化引數
- tol 決定樣本落在箱外概率的一個引數
- contamination 資料集的異常值比例
- 屬性
- bin_edges_ 箱子的劃分邊界
- hist_ 直方圖的密度
- 其他引數同一般模型
2.2hbos例項
2.2.1生成資料
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import matplotlib.font_manager
from pyod.utils.data import generate_data,get_outliers_inliers
# 生成二維隨機資料
X_train, Y_train = generate_data(n_train=200,train_only=True, n_features=2)
# 拆分出異常資料和正常資料
x_outliers, x_inliers = get_outliers_inliers(X_train,Y_train)
# 繪製生成的資料圖
F1 = X_train[:,[0]].reshape(-1,1)
F2 = X_train[:,[1]].reshape(-1,1)
plt.scatter(F1,F2)
plt.xlabel('F1')
plt.ylabel('F2')
plt.show()
2.2.2使用HBOS進行預測
from pyod.models.hbos import HBOS
outlier_fraction = 0.1#異常值比例
abod = HBOS(contamination=outlier_fraction)#生成模型
abod.fit(X_train)#訓練模型
score = abod.decision_scores_# 注意異常得分是負的
score = score * -1
score.shape
(200,)
2.2.3預測結果
y_pred = abod.predict(X_train)# 預測訓練樣本的標籤
from sklearn.metrics import classification_report
print(classification_report(y_true=Y_train,y_pred=y_pred))
precision recall f1-score support
0.0 0.99 1.00 1.00 180
1.0 1.00 0.95 0.97 20
accuracy 0.99 200
macro avg 1.00 0.97 0.99 200
weighted avg 1.00 0.99 0.99 200
2.2.4生成熱力圖
n_inliers = len(x_inliers)
n_outliers = len(x_outliers)
#生成熱力圖的座標點
xx , yy = np.meshgrid(np.linspace(-10, 10, 200), np.linspace(-10, 10, 200))
# 根據百分比生成
threshold = -abod.threshold_
# 得到每個座標點的異常值得分
Z = abod.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1
Z = Z.reshape(xx.shape)
plt.figure(figsize=(10, 10))
#將正常樣本區域繪製成藍色
plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 10),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='orange')
#繪製正常點(白色)
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.legend(
[a.collections[0], b, c],
['learned decision function', 'true inliers', 'true outliers'],
prop=matplotlib.font_manager.FontProperties(size=10),
loc='lower right')
plt.title('HBOS')
plt.xlim((-10, 10))
plt.ylim((-10, 10))
plt.show()