1. 主要內(nèi)容包括:
- Feature Bagging
- 孤立森林
2. 學(xué)習(xí)背景:
在實(shí)際場景中月趟,很多數(shù)據(jù)集都是多維度的。隨著維度的增加恢口,數(shù)據(jù)空間的大惺ǘ贰(體積)會以指數(shù)級別增長,使數(shù)據(jù)變得稀疏弧蝇,這便是維度詛咒的難題碳褒。
維度詛咒不止給異常檢測帶來了挑戰(zhàn),對距離的計(jì)算看疗,聚類都帶來了難題沙峻。例如基于鄰近度的方法是在所有維度使用距離函數(shù)來定義局部性,但是两芳,在高維空間中摔寨,所有點(diǎn)對的距離幾乎都是相等的(距離集中),這使得一些基于距離的方法失效怖辆。在高維場景下是复,一個(gè)常用的方法是子空間方法。
3. 解決方式
集成是子空間思想中常用的方法之一竖螃,可以有效提高數(shù)據(jù)挖掘算法精度淑廊。集成方法將多個(gè)算法或多個(gè)基檢測器的輸出結(jié)合起來。
集成學(xué)習(xí)的基本思想是利用不同算法在不同子集的表現(xiàn)特咆,將其集成起來使得輸出更加魯棒季惩。
3.1 feature bagging
Bagging方法通常考慮的是同質(zhì)弱學(xué)習(xí)器腻格,相互獨(dú)立地并行學(xué)習(xí)這些弱學(xué)習(xí)器画拾,并按照某種確定性的平均過程將它們組合起來。
Feature Bagging菜职,基本思想與bagging相似青抛,只是對象是feature。feature bagging屬于集成方法的一種酬核。集成方法的設(shè)計(jì)有以下兩個(gè)主要步驟:
3.1.1 選擇基檢測器
feature bagging常用lof算法為基算法蜜另,下圖是feature bagging的通用算法:
3.1.2 分?jǐn)?shù)標(biāo)準(zhǔn)化和組合方法
把來自各種檢測器的分?jǐn)?shù)轉(zhuǎn)換成可以有意義的組合的歸一化值。分?jǐn)?shù)標(biāo)準(zhǔn)化之后愁茁,還要選擇一個(gè)組合函數(shù)將不同基本檢測器的得分進(jìn)行組合蚕钦,最常見的選擇包括平均和最大化組合函數(shù)亭病。
下圖是兩個(gè)feature bagging兩個(gè)不同的組合分?jǐn)?shù)方法:
-
廣度優(yōu)先
-
累積求和
3.2 孤立森林算法(Isolation Forests)
特點(diǎn)
- 時(shí)間效率高
- 有效處理高維數(shù)據(jù)和海量數(shù)據(jù)鹅很,無須標(biāo)注樣本,在工業(yè)應(yīng)用廣泛罪帖。
算法思想
孤立森林屬于非參數(shù)和無監(jiān)督的算法促煮,通過用一個(gè)隨機(jī)超平面來切割數(shù)據(jù)空間來查找異常點(diǎn)邮屁,切一次可以生成兩個(gè)子空間。然后繼續(xù)用隨機(jī)超平面來切割每個(gè)子空間并循環(huán)菠齿,直到每個(gè)子空間只有一個(gè)數(shù)據(jù)點(diǎn)為止佑吝。直觀上來講,很快被孤立的點(diǎn)就是異常點(diǎn)绳匀。
構(gòu)造方法
- 從訓(xùn)練數(shù)據(jù)中隨機(jī)選擇一個(gè)樣本子集芋忿,放入樹的根節(jié)點(diǎn)
- 隨機(jī)指定一個(gè)屬性,隨機(jī)產(chǎn)生一個(gè)切割點(diǎn)V疾棵,即屬性A的最大值和最小值之間的某個(gè)數(shù)
- 根據(jù)屬性A對每個(gè)樣本進(jìn)行分類戈钢,把A小于V的樣本放在當(dāng)前節(jié)點(diǎn)的左子樹中,否否則放于右子樹中是尔。依次生成隨機(jī)二叉樹
- 重復(fù)前一步驟殉了,直到子樹中只有一個(gè)數(shù)據(jù),停止生成拟枚。
孤立森林檢測異常的假設(shè)
異常點(diǎn)一般都是非常稀有的薪铜,在樹中會很快被劃分到葉子節(jié)點(diǎn),因此可以用葉子節(jié)點(diǎn)到根節(jié)點(diǎn)的路徑長度來判斷一條記錄是否是異常的恩溅。在訓(xùn)練時(shí)隔箍,每棵樹的訓(xùn)練樣本是隨機(jī)抽樣的。從孤立森林的樹的構(gòu)造過程看脚乡,它不需要知道樣本的標(biāo)簽鞍恢,而是通過閾值來判斷樣本是否異常。因?yàn)楫惓|c(diǎn)的路徑比較短每窖,正常點(diǎn)的路徑比較長帮掉,孤立森林根據(jù)路徑長度來估計(jì)每個(gè)樣本點(diǎn)的異常程度。
路徑長度計(jì)算方法
4. 總結(jié)
- feature bagging可以降低方差
- 孤立森林的優(yōu)勢在于:計(jì)算成本相比基于距離或基于密度的算法更兄系洹蟆炊;具有線性的時(shí)間復(fù)雜度;在處理大數(shù)據(jù)集上有優(yōu)勢瀑志;孤立森林不適用于超高維數(shù)據(jù)涩搓,因?yàn)楣膭?lì)森林每次都是隨機(jī)選取維度,如果維度過高劈猪,則會存在過多噪音昧甘。
5.思考題
- 為什么feature bagging可以降低方差?
因?yàn)樽兞恐g具備相關(guān)性战得,不是完全獨(dú)立的充边。 - feature bagging存在哪些缺陷,有什么可以優(yōu)化的idea?
要訓(xùn)練多個(gè)弱學(xué)習(xí)器,計(jì)算開銷大浇冰。優(yōu)化:在隨機(jī)采樣訓(xùn)練若學(xué)習(xí)器前贬媒,對樣本訓(xùn)練集進(jìn)行KNN聚類,篩選明顯存在異常值的樣本集肘习,再進(jìn)行弱學(xué)習(xí)器的訓(xùn)練际乘。
6. 實(shí)驗(yàn)
feature bagging
import pyod.utils.data as data
from pyod.models.feature_bagging import FeatureBagging
import matplotlib.pyplot as plt
import numpy as np
x,y= data.generate_data(n_train=100,n_features=2,contamination=0.1,train_only=True,behaviour='new')
xn=[]
xa=[]
for i in range(100):
if(y[i]==0):
xn.append(x[i])
else:
xa.append(x[i])
xn=np.array(xn)
xa = np.array(xa)
plt.figure()
plt.scatter(xn[:,0],xn[:,1])
plt.scatter(xa[:,0],xa[:,1], color = 'red')
plt.show()
clf = FeatureBagging()
clf.fit(x)
y_pred = clf.labels_
nr_pred = [] #預(yù)測正常正確
ar_pred = [] #預(yù)測異常正確
ne_pred = [] #預(yù)測正常錯(cuò)誤
ae_pred = [] #預(yù)測異常錯(cuò)誤
for i in range(100):
if(y_pred[i]==0 and y[i]==0):
nr_pred.append(x[i])
if(y_pred[i]==1 and y[i]==1):
ar_pred.append(x[i])
if(y_pred[i]==0 and y[i]==1):
ne_pred.append(x[i])
if y_pred[i]==1 and y[i]==0:
ae_pred.append(x[i])
ne_pred=np.array(ne_pred).reshape(-1,2)
nr_pred = np.array(nr_pred).reshape(-1,2)
ae_pred = np.array(ae_pred).reshape(-1,2)
ar_pred = np.array(ar_pred).reshape(-1,2)
plt.figure()
plt.scatter(nr_pred[:,0],nr_pred[:,1],marker='.',c='blue')
plt.scatter(ar_pred[:,0],ar_pred[:,1], marker='.',c = 'red')
plt.scatter(ne_pred[:,0],ne_pred[:,1],marker='*',c='blue')
plt.scatter(ae_pred[:,0],ae_pred[:,1], marker='*',c = 'red')
plt.show()
檢測結(jié)果如上圖所示:
圖一中藍(lán)色是正常數(shù)據(jù)點(diǎn),紅色是異常數(shù)據(jù)點(diǎn)漂佩。
圖二中點(diǎn)是預(yù)測正確的點(diǎn)脖含,星號是預(yù)測錯(cuò)誤的點(diǎn)。
孤立森林實(shí)驗(yàn)
import pyod.utils.data as data
from pyod.models.iforest import IForest
import matplotlib.pyplot as plt
import numpy as np
'''生成同樣example'''
x,y= data.generate_data(n_train=100,n_features=2,contamination=0.1,train_only=True,behaviour='new')
xn=[]
xa=[]
for i in range(100):
if(y[i]==0):
xn.append(x[i])
else:
xa.append(x[i])
xn=np.array(xn)
xa = np.array(xa)
plt.figure()
plt.scatter(xn[:,0],xn[:,1])
plt.scatter(xa[:,0],xa[:,1], color = 'red')
plt.show()
clf = IForest()
clf.fit(x)
y_pred = clf.labels_
nr_pred = [] #預(yù)測正常正確
ar_pred = [] #預(yù)測異常正確
ne_pred = [] #預(yù)測正常錯(cuò)誤
ae_pred = [] #預(yù)測異常錯(cuò)誤
for i in range(100):
if(y_pred[i]==0 and y[i]==0):
nr_pred.append(x[i])
if(y_pred[i]==1 and y[i]==1):
ar_pred.append(x[i])
if(y_pred[i]==0 and y[i]==1):
ne_pred.append(x[i])
if y_pred[i]==1 and y[i]==0:
ae_pred.append(x[i])
ne_pred=np.array(ne_pred).reshape(-1,2)
nr_pred = np.array(nr_pred).reshape(-1,2)
ae_pred = np.array(ae_pred).reshape(-1,2)
ar_pred = np.array(ar_pred).reshape(-1,2)
plt.figure()
plt.scatter(nr_pred[:,0],nr_pred[:,1],marker='.',c='blue')
plt.scatter(ar_pred[:,0],ar_pred[:,1], marker='.',c = 'red')
plt.scatter(ne_pred[:,0],ne_pred[:,1],marker='*',c='blue')
plt.scatter(ae_pred[:,0],ae_pred[:,1], marker='*',c = 'red')
plt.show()
檢測結(jié)果如上圖所示:
圖一中藍(lán)色是正常數(shù)據(jù)點(diǎn)投蝉,紅色是異常數(shù)據(jù)點(diǎn)器赞。
圖二中點(diǎn)是預(yù)測正確的點(diǎn),星號是預(yù)測錯(cuò)誤的點(diǎn)墓拜。