異常檢測 | 使用孤立森林 sklearn.ensemble.IsolationForest 分析異常流量


孤立森林

Isolation Forest(sklearn.ensemble.IsolationForest):一種適用於 連續數據 的 無監督 異常檢測方法。與隨機森林類似,都是高效的集成算法,相較於LOF,K-means等傳統算法,該算法魯棒性高且對數據集的分布無假設。

Isolation Forest算法做非監督式的異常點檢測分析,對數據特征的要求寬松:

  • 該算法對特征的要求低,不需要做離散化,不需要數值標准化

  • 不需要考慮特征間的關系(例如共線性)等,不需要額外做特征過濾和篩選

 

附:SKlearn 中其他用於異常檢測的方法

  • one-class SVM(svm.OneClassSVM)

  • LocalOutlierFactor(sklearn.neighbors.LocalOutlierFactor)

  • EllipticEnvelope(covariance.EllipticEnvelope)

 

本案例中

需求:分析一下通過不同渠道來到網站的訪客里面是否有異常流量

數據特點:(綜合數據特點,選擇Isolation Forest算法做非監督式的異常點檢測分析

  數據是不帶標記的數據,只能用無監督式分析方法

  特征維度較高,有的特征是分類型變量,有的特征是數值型變量

 

代碼示例

1 數據預處理

1.1 填充缺失值、去除無關項(如 用戶id,可能影響結果)

  【此處,處理好的數據集是 df

  不是主要代碼,略

 

1.2 將 分類特征 轉換為 數值型

  【此處,處理好的數據集是feature_merge

  方法請移步 https://www.cnblogs.com/ykit/p/12440945.html

 

2 異常診斷

2.1 異常點檢測

from sklearn.ensemble import IsolationForest

# 創建模型,n_estimators:int,可選(默認值= 100),集合中的基本估計量的數量
model_isof = IsolationForest(n_estimators=20)
# 計算有無異常的標簽分布
outlier_label = model_isof.fit_predict(feature_merge)

得到 array 類型的 標簽數據

2.2 異常結果匯總 

# 將array 類型的標簽數據轉成 DataFrame
outlier_pd = pd.DataFrame(outlier_label, columns=['outlier_label'])

# 將標簽數據與原來的數據合並
data_merge = pd.concat((df, outlier_pd), axis=1)

查看一下異常流量和正常流量的數量

 

 2.3 統計每個渠道的異常情況

# 創建用於返回數據集的函數
def cal_sample(df):
    return df.groupby(['source'], as_index=False)['visitNumber'].count().sort_values(['source'], ascending=False)

# 取出異常樣本
outlier_source = data_merge[data_merge['outlier_label']==-1]
outlier_source_sort = cal_sample(outlier_source)

# 取出正常樣本
normal_source = data_merge[data_merge['outlier_label']==1]
normal_source_sort = cal_sample(normal_source)

 

 2.4 計算異常比例

# 將並異常流量與正常流量為一個 DataFrame
source_merge = pd.merge(outlier_source_sort,
                        normal_source_sort, on='source', how='outer')

# 修改列名
source_merge = source_merge.rename(
    columns={'visitNumber_x': 'outlier_count', 'visitNumber_y': 'normal_count'})

# 計算異常比例
source_merge['total_count'] = source_merge['outlier_count'] + \
    source_merge['normal_count']
source_merge['outlier_rate'] = source_merge['outlier_count'] / \
    source_merge['total_count']

 

 

bingo~

本文僅用於學習


免責聲明!

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



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