一、蓋帽法介紹
數據分析中,異常值比較難於界定,一般數據異常值包括幾種情況:
- 單值異常:結合實際業務進行判斷(例如:年齡age ≥ 120歲)
- 相關性異常:一般收入隨年齡的增長呈現類線性增長趨勢,如果異常情況,需進行剔除
- 突發異常:激增異常,添加啞變量(有待理解?)區分(異常值 vs 強影響點)
異常值的處理可以通過蓋帽法進行處理。
如果一個置信區間左右兩邊各有3個標准差,即區間置信度為99%時,一般建議三倍標准差以外刪除;
而如果一個置信區間左右兩邊各有2個標准差,即區間置信度為95%時,此時到底取兩個還是三個標准差則取決於模型對於異常的敏感程度。
- 回歸模型對異常值敏感度不高
- 聚類分析(k-means)、時間序列對聚類敏感度高,需剔除異常值
二、實操
在機器學習中,常常利用95分位數蓋帽法處理離散值。
# 蓋帽法
def blk(floor, root):
def f(x):
if x < floor:
x = floor
elif x > root:
x = root
return x
return f
# 清洗數據
data["col"] = data["col"].map(blk(0, root=data["col"].quantile(0.99)))
# 缺失值填充
data["col"] = data["col"].fillna(0)
三、高階用法
下面函數可以直接針對數據表和特征列進行處理,不用一一處理。
# 蓋帽法
# 傳入數據表和待處理特征列
def train_add_hat(x, features):
import numpy as np
import pandas as pd
df = x.copy() # 復制表
q95_dict = {} # 空字典
for col in features: # 遍歷特征列
q95 = np.percentile(df[col], 95) # 95分位數
q95_dict[col] = q95 # append至字典
b = np.array(df[col]) # 轉為數組
c = list(map(lambda x:q95 if x > q95 else x, b)) # map一一處理
df = df.drop(col, axis=1) # 刪除列
df[col] = c # 新增列
# 返回處理后的數據表和處理字典
return df, q95_dict
# 使用同一標准處理測試集
def add_hat(x, features, q95_dict):
import numpy as np
import pandas as pd
df = x.copy()
len_d = len(df.index) # 測試集大小
for col in features:
q95 = q95_dict[col]
b = np.array(df[col])
c = list(map(lambda x:q95 if x > q95 else x, b))
df = df.drop(col, axis=1)
df[col] = c
return df
參考鏈接1:蓋帽處理異常值
參考鏈接2:機器學習處理離散值方法之 95分位數蓋帽法