高斯分布是自然界最常見的分布形態,用它來做異常檢測是非常合適的模型。槍打出頭鳥,那些分布在兩端的小概率事件,要么好的出奇(右邊),要么差得離譜(左邊)。據說認真看完這篇文章并點贊的人基本上是分布在右側。
忍不住再吐槽一下簡書,每次文章發在我博客上,一條命令
make github
就搞定,可是發在簡書,莫名其妙地要再花十分鐘來截圖,上傳圖片。雖然簡書大部分時候是個很好的寫作平臺,但作為經常寫公式的人真是傷不起。所幸本系列文章所剩不多了,還是寫點省心的吧,寫得又累又沒人看。
異常檢測模型和實例
給定一組數據 $x^{(1)}, x^{(2)}, ... , x^{(m)}$,我們建立一個模型 $p(x)$,當有一個新的實例 $x_{test}$ 時,如果 $p(x_{test}) \le \epsilon$ 我們就認為 $x_{test}$ 是異常的。
異常檢測在網站防盜等領域有廣泛的應用,比如我們可以提取用戶的一些特征,$x_1$ 代表用戶的登錄次數,$x_2$ 表示用戶游覽的頁面個數,$x_3$ 表示用戶的打字速度,$x_4$ 表示用戶的交易次數等等,建立完特征,根據用戶的歷史數據建立一個模型,當某次用戶的行為偏離這個模型較遠時,這個用戶的帳戶可能是被盜了。
另外一個應用領域是在工業制造。比如某個制造飛機引擎的公司,從飛機引擎提取出一系列的特征值,并且訓練出一個模型。當新制造出來的引擎符合這個模型時,就可認為是良品,如果偏離這個模型較遠時,就可以認為可能有缺陷,需要進一步的檢測。
異常檢測還在數據中心有廣泛的應用,比如可以從一臺服務器上提取出一系列特征,如內存占用,CPU 使用率,網絡吞吐量,磁盤訪問頻率等等。利用這些特征建立一個模型。當某個服務器偏離這個模型較遠時,可能這臺機器快要死機了,就可以進一步查看這臺機器的情況以便做出相應的處理。
高斯分布
高斯分布也稱為正態分布。高斯分布有兩個參數,一個是平均值 $\mu$,另外一個是方差 $\sigma^2$ ($\sigma$ 稱為標準差),給定一個數值 X 作為橫軸,它出現在不同位置的概率作為 Y 軸,在二維坐標上畫出的圖形是一個“鐘形”的圖形。

用數據公式給出高斯分布的公式如下:
參數計算
假設我們有一個數據集 $x^{(1)}, x^{(2)}, ... , x^{(m)}$,其中 $x^{(i)} \in R$。且 $x^{(i)}$ 滿足高斯分布,記作 $x^{(i)} \sim N(\mu, \sigma^2)$,如何算出高斯分布的參數 $\mu, \sigma^2$ 呢?
算法可以用下面的公式給出:
這個實際上就是概率論里的極大似然法來估計參數。另外需要提一點,計算方差 $\sigma^2$ 的公式里,一些概率論書本里分母是用 $m-1$,但機器學習領域喜歡直接用 $m$ ,雖然這是兩個不同版本的公式,但在實際應用中,如果樣例個數足夠多,即 m 很大的話,實際計算結果差別不大。
異常檢測算法
假設我們有一個數據集 $x^{(1)}, x^{(2)}, ... , x^{(m)}$,其中 $x^{(i)} \in R^n$,其中每個特征都獨立地滿足高斯分布,即 $x_j^{(i)} \sim N(\mu_j, \sigma_j^2)$。那么高斯分布的概率密度函數為:
其中 $\prod$ 是連乘符號,表示其后的式子相乘。
利用高斯分布進行異常檢測的算法可以完整地描述如下:
- 特征選擇。選擇那些能鑒別出異常的特征 $x_j$。
- 針對每個特征,計算出其高斯分布參數 $\mu_j, \sigma_j^2$。計算公式為:
- 給定一個新的實例 $x$,計算其出現的概率 $p(x)$。計算公式為:
- 選定一個較小的常數 $\epsilon$,如果 $p(x) \le \epsilon$ 則表示新的實例 $x$ 是異常的。
異常檢測算法的性能評價
怎么樣評價一個異常檢測算法的性能是否達到要求呢?
假設我們拿飛機引擎制造作為例子,我們有 10,000 個正常的引擎數據,20 個異常的引擎數據。這樣我們把數據分成三份:
- 訓練數據集:6,000 個正常的引擎數據
- 交叉驗證數據集:2,000 個正常的引擎數據;10 個異常引擎數據
- 測試數據集:2,000 個正常的引擎數據;10 個異常的引擎數據
接下來我們開始來評估算法的性能
- 使用訓練數據集來建立 $p(x)$ 模型
- 使用下面的模型來預測交叉驗證數據集和測試數據集里的樣例
- 使用交叉驗證數據集來計算查準率,召回率以及$F_1Score$
- 使用交叉驗證數據集來選擇合適的 $\epsilon$,來讓 $F_1Score$ 的值最大
- 最后使用測試數據集來計算模型的最終性能 $F_1Score$
TruePosition: 真陽性,即真實結果是真,算法的預測結果也是真
FalsePositive: 假陽性,即真實結果是假,算法的預測結果是真
FalseNegative: 假陰性,即真實結果是真,算法的預測結果是假
異常檢測與監督學習的區別
上一節介紹的飛機引擎異常檢測算法里,我們有正常的數據,有異常的數據,為什么不直接用邏輯回歸或神經網絡算法來對一個新引擎進行直接預測呢?實際上異常檢測和監督學習有其不同的適用范圍。
異常檢測適用范圍
- 正向樣本 (y = 1) 非常少 (0 - 20),但負向樣本 (y = 0) 很多
- 有太多的異常類型,算法很難從正常的數據樣例里學習到異常的特征
- 未來新出來的異常數據和我們訓練樣例里現有的異常數據根本不一樣,即沒見過的異常樣例
如果滿足這三個條件中的任何一個,都需要考慮使用異常檢測算法,而不是監督學習相關的算法。監督學習算法適用于有大量的正向樣本,也有大量的負向樣本,有足夠的正向樣本讓算法來學習其特征,未來新出現的正向數據可能和訓練樣例里的某個正向樣本類似。
由此可見異常檢測和監督學習相關算法的適用范圍是不一樣的。下面是一些例子
異常檢測 | 監督學習 |
---|---|
信用卡詐騙 | 垃圾郵件識別 |
制造業異常產品檢測 | 天氣預報 (晴/雨 等) |
數據中心機器異常檢測 | 癌癥檢測 |
異常檢測中的特征選擇
非高斯分布特征的轉換
使用高斯分布來作為異常檢測模型時,有個前提,即每個特征都需要獨立地呈現高斯分布。如果我們獲得的特征數據可視化后發現他不是一個高斯分布的鐘形圖形怎么辦呢?我們可以用 octave 的 hist
命令來畫出特征的柱狀圖,然后對特征進行轉換,比如畫出 $log(x)$ 的圖形,或畫出 $x^{0.5}$ 或 $x^{0.1}$ 的柱狀圖??磮D形的形狀來判斷是否符合高斯分布。然后選擇轉換后的特征來加入我們的異常檢測算法中來。

異常檢測的錯誤分析
假如我們有一個異常檢測算法,算出正常樣本的概率很大,但算出異常樣本的概率也很大。這樣就沒有辦法區分出異常樣本了。這個時候,一個可行的方法是去查看這個概率很大的異常樣本,看能不能得到一些啟發,以便讓我們發現一些新的特征,用這個特征可以把這種異常樣本區分出來。
特征選擇的一般性原則
選擇那些在異常時,特征值會變得很大或很小的特征來作為異常檢測的特征。比如,我們要檢測數據中心中的計算機工作是否正常,我們有下面幾個特征:
- CPU 使用率
- 網絡吞吐量
- 磁盤訪問速度
- 內存使用情況
一般情況下,CPU 使用率和網絡吞量是成正比的,即用戶訪問越多,CPU 使用率就越高。當 CPU 使用率很高,但網絡吞吐量比較小時,這個時候這個機器可能就出現異常了,比如進入了死循環了。如果我們想檢測出這種異常,可以選擇 CPU 使用率 / 網絡吞吐量 來作為一個新的特征,加入我們的異常檢測算法里。