缺失值处理的方法
-
决定处理方法的核心问题:数据缺失的原因是什么?手里的样本是大样本还是小样本?
删除记录
删除缺失值对应的行或列
- 行或列缺失占比较大时考虑这个选项
- 某一特征缺失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, 缺失值所在的行当做测试集,其它行当做训练集
- 需要足够有效样本
不处理
不处理可能很多模型跑不通,还不知道为啥会有不处理选项