Python学习笔记:盖帽法处理异常值

一、盖帽法介绍

数据分析中,异常值比较难于界定,一般数据异常值包括几种情况:

  • 单值异常:结合实际业务进行判断(例如:年龄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分位数盖帽法

原文地址:https://www.cnblogs.com/hider/p/14733463.html