孤立森林(Isolation Forest)


 

 著名的,人手一本的西瓜書(就是這本)的作者周志華老師,於2008年在第八屆IEEE數據挖掘國際會議上提出孤立森林(Isolation Forest) 算法,

先簡單解釋一下什么是孤立森林: 「假設我們用一個隨機超平面來切割(split)數據空間(data space), 切一次可以生成兩個子空間(想象拿刀切蛋糕一分為二)。之后我們再繼續用一個隨機超平面來切割每個子空間,循環下去,直到每子空間里面只有一個數據點為止。直觀上來講,我們可以發現那些密度很高的簇是可以被切很多次才會停止切割,但是那些密度很低的點很容易很早的就停到一個子空間里了

和隨機森林一樣,孤立森林由 iTree(isolation tree) 組成,iTree樹和隨機森林的決策樹不太一樣,構建過程只是一個完全隨機的過程,並且是不放回抽樣。下面詳細解釋一下構建過程:

現有數據集中有n條數據,先從這n條數據中抽取一批樣本(一般是無放回抽樣),假設樣本個數 ψ 。隨機選擇一個特征作為起始節點,並在該特征的值域里隨機選擇一個值,對ψ個樣本進行二叉划分,將樣本中小於該取值的樣本划到左分支,樣本中大於該取值的划到右分支。然后在左右兩個分支重復這樣的二叉划分操作。直到達到滿足如下條件

(1)樹達到了限制的高度;
(2)節點上只有一個樣本;
(3)節點上的樣本所有特征都相同。

算法簡介

孤立森林算法屬非監督學習算法,不需要定義參數模型和進行歷史訓練樣本,通過采用多次迭代的方式構建二叉搜索樹(Binary Search Tree),然后將這些二叉樹組成森林,默認二叉搜索樹的高度為 8,樹的高度限制 l 與子樣本數量ψ的關系為  l=ceiling(log2(ψ)),它近似等於樹的平均高度。每 t=100 棵樹組成一個森林,每次最多生成 ψ= 256 個森林。算法主要構建思想如下:

  • 構建二叉樹 iTree,首先從訓練數據中隨機選擇 X 個樣本,若 iTree 已經 達到限定高度或者僅剩一個樣本,則算法收斂。否則,遞歸構建二叉搜索樹,將小於當前根結點的樣本放入左子結點,將大於當前根結點的樣本放入右子結點。
Algorithm iTree(X,e,h):

Input: X-input data; e-current height; h-height limit; 
Output: an iTree;
if e >= h OR |X| <= 1 then 
    return exNode{Size <- |X|}
else
    //隨機選擇一個樣本 q
    l <- filter(X, q<p)
    r <- filter(X, q>p)
    return inNode{Left <- iTree(l, e+1, h), Right <- iTree(r, e+1, h), SplitAttr q, SplitValue p}
end if
  • 構建二叉樹森林 iForest,根據樣本數據容量迭代重復步驟(1)過程創建二叉搜索樹 iTree,並將生成的 iTree 組成二叉樹森林。

  • 計算森林中二叉樹的路徑長度,當二叉樹森林 iForest 構建完成后,就可以對樣本進行預測了,預測過程就是對二叉搜索樹進行遞歸中序遍歷,記錄從根結點到葉子結點的路徑長度 h(x)。

Algorithm pathLength(x,T,e): 

Input: x-an instance;
       T-an iTree,
       e-current path length;
Output: path length of x;
if T is an external node then
    return e+c(T.size) //c(n) 為二叉樹森林平均路徑長度 
end if
//遞歸中序遍歷二叉搜索樹 iTree 
a <- T.splitAttr
if x.a < T.splitValue then
    return pathLength(x, T.left, e+1) 
else {x.a >= T.splitValue}
    return pathLength(x, T.right, e+1) 
end if
  • 計算離群點偏離值,當森林中所有樣本路徑長度 h(x) 計算完畢后,通過運用統計學的方法計算得出所有數據樣本期望值 E(h(x)) 和方差 S(h(x)),進而得到偏離期望和方差的異常數據點。

常見機器學習聚類算法通常根據空間距離或者密度來尋找異常數據,孤立森林算法獨辟蹊徑,采用構建二叉樹森林再進行中序遍歷計算葉子結點平均高度的方式來尋找異常數據,算法實現了對於海量數據的異常檢測僅需 O(n) 的線性時間復雜度,能夠在短暫的批處理時間間隔內有效檢測出離群數據點。

   假設X中有n個點,那這n個點如果用一個二分樹來搜索,平均搜索不成功的路徑就等於這n個點的平均路徑長度c(n)=2H(n−1)−(2(n−1)/n)。所以用c(n)來歸一化E(h(x))。那么這里存在一個疑問,為什么用c(n)來歸一化,而不是這么多樹真實的,每個點的平均路徑長度來歸一化呢?難道是為了節省計算力?不知道有沒有小伙伴明白?請賜教。
   異常程度便可表示為:
              

下圖給出了sE(h(x))的關系

 


由上圖可以得到一些結論:

  1. 當E(h(x))→c(n)時,s→0.5,即樣本x的路徑平均長度與樹的平均路徑長度相近時,則不能區分是不是異常。
  2. 當E(h(x))→0 時,s→1,即x的異常分數接近1時,被判定為異常。
  3. 當E(h(x))→n−1 時,s→0,被判定為正常。

可以看出當其趨於0.5時,表示很可能是正常值,當其趨於1時,很可能是異常值。這里意思是如果某個點的平均路徑和n個點(數據集中的點數)的平均路徑趨於相同,則不太可能是異常點,只有當其大大小於n個點的平均路徑時,才可能是異常值。

注意:
* 訓練樣本中異常樣本的比例比較高,可能最終的效果會受影響 * 異常檢測跟具體的應用場景緊密相關,算法檢測出的“異常”不一定是我們實際想要的,所以,在特征選擇時,要注意過濾不太相關的特征。 個人覺得較好的實踐是,在預處理時把不關注的特征normalize。
參考資料:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM