缺失值处理的方法



  • 决定处理方法的核心问题:数据缺失的原因是什么?手里的样本是大样本还是小样本?

    删除记录

    删除缺失值对应的行或列

    • 行或列缺失占比较大时考虑这个选项
    • 某一特征缺失20%以上,需要考虑删除整列
    • 无法使用合适的方法进行缺失值插补

    插补

    以均值/众数/中位数等填充缺失值

    • 注意:解决数据右偏问题后(例如用log(1+x)处理某特征),再填充。
    • 内涵假设:缺失数据的分布与未缺失数据分布相同。当缺失数据为随机缺失时有效

    聚类填充:根据其它特征进行聚类,然后填充最有可能的值

    • 最近邻插补:在样本中找到与缺失样本最接近的样本的该属性值进行插补
    • 核心假设: 缺失数据的分布与与其同类的数据相同。
    • 举例:苹果的糖分含量用苹果的数据估计,香蕉的糖分含量用香蕉的数据估计

    根据实际意义以指定值填充

    插值法(利用已知点建立合适的插值函数$f(x)$,未知值由对应点$x_i$求出的函数值$f(x_i)$近似代替)

    • 拉格朗日插值法
    • 牛顿插值法
    • 其他插值法:Hermite插值、分段插值、样条插值法等
    import pandas as pd
    from scipy.interpolate import lagrange
    
    #自定义列向量拉格朗日插值函数
    #s 为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
    def ployinterp_column(s, n, k=5):
        y = s[list(range(n-k, n))+list(range(n+1, n+1+k))]#取数
        y = y[y.notnull()] #剔除空值
        return lagrange(y.index, list(y))(n) # 插值并返回插值结果
    
    #逐个元素判断是否需要插值
    for i in data.columns:
        for j in range(len(data)):
            if (data[i].isnull())[j]: #如果为空即插值
                data[i][j] = ployinterp_column(data[i], j)
    

    填充了缺失值后, 再加一列indicator

    • 内涵假设:缺失数据是有某一特征的数据,所以这部分数据的行为和其它数据不一样

    直接把缺失值所在的列当做y, 缺失值所在的行当做测试集,其它行当做训练集

    • 需要足够有效样本

    不处理

    不处理可能很多模型跑不通,还不知道为啥会有不处理选项


登录后回复