異常檢測

異常檢測

異常檢測(Anomaly Detection):異常檢測就是從數據集中檢測出異常樣本,是一種無監督學習。

引例

飛機製造商在飛機引擎從生產線上流出時,會考慮進行異常檢測,以防止不合格引擎對整機造成的巨大影響,而爲了進行異常檢測,通常就需要採集一些特徵,比如會採集如下特徵:

  1. x1 =引擎運轉時產生的熱量
  2. x2 =引擎的振盪頻率

對於一系列的數據集(特徵向量集合):x(1),,x(m)x(1),,x(m) , 這些數據都是正常樣本,我們將其繪製到二維平面上:


飛機引擎數據集

如果一個新的測試樣本居於樣本布密度較大的地方如:

正常飛機引擎

那麼我們有很大的把握認爲這個測試樣本是正常的。
反之如果一個新的測試樣本遠離分佈集中的地方如:

異常飛機引擎

那麼我們也有很大的把握認爲這個測試樣本是正常的。

小結:
如果我們擁有一個測試集x(1),,x(m) ,我們根據已知的數據集建立模型p(x) ,該模型可以將正常樣本與異常樣本分離。


斷言

建立模型

高斯分佈(正態分佈)

正態分佈可以表示成XN(μ,δ2) ,表示X 服從均值爲μ ,方差爲δ2 的正態分佈。

P(x;μ,δ2)=12πδexp((xμ)22δ2)

參數估計:
若有x(1),,x(m)x(i)N(μ,δ2)
μ=1mΣmi=1x(i)δ2=1mΣmi=1(x(i)μ)2

證明可以中最大似然估計。

異常檢測算法

訓練集:x(1),,x(m)x(i)N(μi,δ2i)
建立模型:

P(X)=P(x(1);μ1,δ21),...,P(x(m);μm,δ2m)=Πmi=1P(x(i);μi,δ2i)                       

參數擬合:
μj=1mΣmi=1x(i)jδ2j=1mΣmi=1(x(i)jμj)2

計算P(X)
P(X)=Πnj=112πδjexp((xjμj)22δ2j)

判斷P(X) 是否小於ϵ ,若小於ϵ 則爲異常。

異常檢測算法的評估

  1. 對數據按6:2:2比例進行分配,分別爲訓練集,交叉驗證集,測試集,訓練集中全是無標籤數據,異常數據在交叉驗證集與測試集中按比例進行分配
  2. 通過訓練集對參數進行擬合
  3. 對交叉驗證集和測試集中的數據進行測試
  4. 由於異常樣本的數量非常的少,導致預測十分偏斜,可以通過考察準確率,召回率,F1值來評估模型的效果。
  5. 通過交叉驗證集來調節參數ϵ

異常檢測與監督學習

因爲我們可能已經知道了訓練數據是否爲異常數據,那麼就難免有個疑惑我們爲什麼不用監督學習的算法比如logistics regression來做呢?
下面我們來比較一下異常檢測與監督學習

項目 異常檢測 邏輯迴歸
樣本 異常樣本數量少(0~20),大量負樣本 正負樣本數量都很多
應用 欺詐檢測,工業製造,數據中心的監測機器 垃圾郵件分類,天氣預報,癌症判斷

注:大量的正樣本可以讓算法學習到正樣本的特徵,並且肯能出現的正樣本與訓練集中的正樣本相似,而異常可能是從未出現過的異常。

數據處理

通常我們先畫出特徵值的柱狀圖,看其是否接近與高斯分佈,若不是我們可以對特徵值進行相關的處理,使其接近於高斯分佈,例如取對數,取冪等等。特徵值的分佈越接近高斯分佈則算法的效果越好。

多元高斯分佈

我們不再單獨考慮每個特徵值的高斯分佈而是考慮特徵向量X 的高斯分佈

P(X;μ,Σ)=1(2π)2n|Σ|12exp(12(Xμ)τΣ1(Xμ))

算法流程

參數擬合

μ=1mΣmi=1x(i)Σ=1mΣmi=1(x(i)μ)(x(i)μ)τ

剩下的流程同高斯分佈相同。

高斯分佈與多元高斯分佈比較

高斯分佈 多元高斯分佈
需要手動創建新的特徵去捕獲不正常變量值的組合 自動捕獲不同特徵變量之間的相關性
運算亮小,適應n很大的情況,即使m很小也可以運行的很好 計算量大,m必須大於n,通常當m>=10時才考慮

注:如果發現Σ 是不可逆的一般有兩種情況

  • m< n
  • 有冗餘變量(變量間存在線性相關的關係)

MatlabCode

參數擬合Code

function [mu sigma2] = estimateGaussian(X)
%ESTIMATEGAUSSIAN This function estimates the parameters of a 
%Gaussian distribution using the data in X
%   [mu sigma2] = estimateGaussian(X), 
%   The input X is the dataset with each n-dimensional data point in one row
%   The output is an n-dimensional vector mu, the mean of the data set
%   and the variances sigma^2, an n x 1 vector
% 

% Useful variables
[m, n] = size(X);

% You should return these values correctly
mu = zeros(n, 1);
sigma2 = zeros(n, 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the mean of the data and the variances
%               In particular, mu(i) should contain the mean of
%               the data for the i-th feature and sigma2(i)
%               should contain variance of the i-th feature.
%
for i=1:n
    mu(i)=sum(X(:,i))/m;
end;

for i=1:n
    sigma2(i)=sum((X(:,i)-mu(i)).^2)/m;
end;  
% =============================================================
end

更新ϵ

function [bestEpsilon bestF1] = selectThreshold(yval, pval)
%SELECTTHRESHOLD Find the best threshold (epsilon) to use for selecting
%outliers
%   [bestEpsilon bestF1] = SELECTTHRESHOLD(yval, pval) finds the best
%   threshold to use for selecting outliers based on the results from a
%   validation set (pval) and the ground truth (yval).
%

bestEpsilon = 0;
bestF1 = 0;
F1 = 0;

stepsize = (max(pval) - min(pval)) / 1000;
for epsilon = min(pval):stepsize:max(pval)

    % ====================== YOUR CODE HERE ======================
    % Instructions: Compute the F1 score of choosing epsilon as the
    %               threshold and place the value in F1. The code at the
    %               end of the loop will compare the F1 score for this
    %               choice of epsilon and set it to be the best epsilon if
    %               it is better than the current choice of epsilon.
    %               
    % Note: You can use predictions = (pval < epsilon) to get a binary vector
    %       of 0's and 1's of the outlier predictions
    predicted = (pval<epsilon);
    truepostive = sum((predicted==1)&(yval==1));
    falsepostive = sum((predicted==1)&(yval==0));
    falsenegative = sum((predicted==0)&(yval==1));
    pre = truepostive/(truepostive+falsepostive);
    rec = truepostive/(truepostive+falsenegative);
    F1 = 2*pre*rec/(pre+rec);
    % =============================================================

    if F1 > bestF1
       bestF1 = F1;
       bestEpsilon = epsilon;
    end
end

end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章