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

參數(shù)計算
假設(shè)我們有一個數(shù)據(jù)集 $x^{(1)}, x^{(2)}, ... , x^{(m)}$,其中 $x^{(i)} \in R$。且 $x^{(i)}$ 滿足高斯分布,記作 $x^{(i)} \sim N(\mu, \sigma^2)$,如何算出高斯分布的參數(shù) $\mu, \sigma^2$ 呢?
算法可以用下面的公式給出:

這個實際上就是概率論里的極大似然法來估計參數(shù)。另外需要提一點,計算方差 $\sigma^2$ 的公式里,一些概率論書本里分母是用 $m-1$,但機器學(xué)習(xí)領(lǐng)域喜歡直接用 $m$ ,雖然這是兩個不同版本的公式,但在實際應(yīng)用中,如果樣例個數(shù)足夠多,即 m 很大的話,實際計算結(jié)果差別不大。
異常檢測算法
假設(shè)我們有一個數(shù)據(jù)集 $x^{(1)}, x^{(2)}, ... , x^{(m)}$,其中 $x^{(i)} \in R^n$,其中每個特征都獨立地滿足高斯分布,即 $x_j^{(i)} \sim N(\mu_j, \sigma_j^2)$。那么高斯分布的概率密度函數(shù)為:

其中 $\prod$ 是連乘符號,表示其后的式子相乘。
利用高斯分布進(jìn)行異常檢測的算法可以完整地描述如下:
- 特征選擇。選擇那些能鑒別出異常的特征 $x_j$。
- 針對每個特征,計算出其高斯分布參數(shù) $\mu_j, \sigma_j^2$。計算公式為:

- 給定一個新的實例 $x$,計算其出現(xiàn)的概率 $p(x)$。計算公式為:

- 選定一個較小的常數(shù) $\epsilon$,如果 $p(x) \le \epsilon$ 則表示新的實例 $x$ 是異常的。
異常檢測算法的性能評價
怎么樣評價一個異常檢測算法的性能是否達(dá)到要求呢?
假設(shè)我們拿飛機引擎制造作為例子,我們有 10,000 個正常的引擎數(shù)據(jù),20 個異常的引擎數(shù)據(jù)。這樣我們把數(shù)據(jù)分成三份:
- 訓(xùn)練數(shù)據(jù)集:6,000 個正常的引擎數(shù)據(jù)
- 交叉驗證數(shù)據(jù)集:2,000 個正常的引擎數(shù)據(jù);10 個異常引擎數(shù)據(jù)
- 測試數(shù)據(jù)集:2,000 個正常的引擎數(shù)據(jù);10 個異常的引擎數(shù)據(jù)
接下來我們開始來評估算法的性能
- 使用訓(xùn)練數(shù)據(jù)集來建立 $p(x)$ 模型
- 使用下面的模型來預(yù)測交叉驗證數(shù)據(jù)集和測試數(shù)據(jù)集里的樣例

- 使用交叉驗證數(shù)據(jù)集來計算查準(zhǔn)率,召回率以及$F_1Score$

- 使用交叉驗證數(shù)據(jù)集來選擇合適的 $\epsilon$,來讓 $F_1Score$ 的值最大
- 最后使用測試數(shù)據(jù)集來計算模型的最終性能 $F_1Score$
TruePosition: 真陽性,即真實結(jié)果是真,算法的預(yù)測結(jié)果也是真
FalsePositive: 假陽性,即真實結(jié)果是假,算法的預(yù)測結(jié)果是真
FalseNegative: 假陰性,即真實結(jié)果是真,算法的預(yù)測結(jié)果是假
異常檢測與監(jiān)督學(xué)習(xí)的區(qū)別
上一節(jié)介紹的飛機引擎異常檢測算法里,我們有正常的數(shù)據(jù),有異常的數(shù)據(jù),為什么不直接用邏輯回歸或神經(jīng)網(wǎng)絡(luò)算法來對一個新引擎進(jìn)行直接預(yù)測呢?實際上異常檢測和監(jiān)督學(xué)習(xí)有其不同的適用范圍。
異常檢測適用范圍
- 正向樣本 (y = 1) 非常少 (0 - 20),但負(fù)向樣本 (y = 0) 很多
- 有太多的異常類型,算法很難從正常的數(shù)據(jù)樣例里學(xué)習(xí)到異常的特征
- 未來新出來的異常數(shù)據(jù)和我們訓(xùn)練樣例里現(xiàn)有的異常數(shù)據(jù)根本不一樣,即沒見過的異常樣例
如果滿足這三個條件中的任何一個,都需要考慮使用異常檢測算法,而不是監(jiān)督學(xué)習(xí)相關(guān)的算法。監(jiān)督學(xué)習(xí)算法適用于有大量的正向樣本,也有大量的負(fù)向樣本,有足夠的正向樣本讓算法來學(xué)習(xí)其特征,未來新出現(xiàn)的正向數(shù)據(jù)可能和訓(xùn)練樣例里的某個正向樣本類似。
由此可見異常檢測和監(jiān)督學(xué)習(xí)相關(guān)算法的適用范圍是不一樣的。下面是一些例子
| 異常檢測 | 監(jiān)督學(xué)習(xí) |
|---|---|
| 信用卡詐騙 | 垃圾郵件識別 |
| 制造業(yè)異常產(chǎn)品檢測 | 天氣預(yù)報 (晴/雨 等) |
| 數(shù)據(jù)中心機器異常檢測 | 癌癥檢測 |
異常檢測中的特征選擇
非高斯分布特征的轉(zhuǎn)換
使用高斯分布來作為異常檢測模型時,有個前提,即每個特征都需要獨立地呈現(xiàn)高斯分布。如果我們獲得的特征數(shù)據(jù)可視化后發(fā)現(xiàn)他不是一個高斯分布的鐘形圖形怎么辦呢?我們可以用 octave 的 hist 命令來畫出特征的柱狀圖,然后對特征進(jìn)行轉(zhuǎn)換,比如畫出 $log(x)$ 的圖形,或畫出 $x^{0.5}$ 或 $x^{0.1}$ 的柱狀圖??磮D形的形狀來判斷是否符合高斯分布。然后選擇轉(zhuǎn)換后的特征來加入我們的異常檢測算法中來。

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