目录
引言
数据中的缺失值是一个非常棘手的问题,那么数据缺失究竟带来了多少问题?假设有100个样本和20个特征,这些数据都是机器收集回来的,若机器上的某个传感器损坏导致一个特征无效时该怎么办?此时是否扔掉整个数据集?这种情况下,另外19个特征怎么办?它们是否还可用?答案是肯定的。因为有时数据相当昂贵,扔掉和重新获取都是不可取的,所以必须采用一些方法来解决这个问题。
一、可选处理方法
下面给出了一些可选的做法:
(1)使用可用特征的均值来填补缺失值;
(2)使用特征值来填补缺失值,如-1;
(3)忽略有缺失值的样本;
(4)使用相似样本的均值填补缺少值;
(5)使用另外的机器学习算法预测缺失值。
二、Python中Pandas库处理缺失值
1.查看数据缺失值得分布情况
【注】:缺失情况如上
1.1. 统计每列数据缺失值的分布情况
import pandas as pd
data = pd.read_csv("./data.csv")
#统计每列数据缺失值的分布情况
print(data.isnull().sum())
#统计每行数据缺失值的分布情况
#通过指定参数axis=1来实现对每行数据的缺失值进行统计,默认是axis=0表示列。
print(data.isnull().sum(axis=1))
2.删除包含缺失值的数据
处理缺失值最简单的方法就是,将包含缺失值数据的列或者行从数据中删除,但这样会造成数据的浪费。
【注】:缺失情况如上
2.1. 删除包含缺失值的行或列
data = pd.read_csv("./data.csv")
#删除包含缺失值的行
print(data.dropna())
#删除包含缺失值的列
print(data.dropna(axis=1))
【注】:在使用dropna方法的时候,我们可以通过设置inplace=True直接修改data的值,默认是是Flase 。
#保留缺失值的记录
data.dropna()
print(data) #左图
#删除缺失值的记录
data.dropna(inplace=True)
print(data) #右图
2.2. 根据条件删除包含缺失值的数据
除了直接删除包含缺失值的数据之外,我们还可以通过dropna提供的一些参数来根据条件对缺失值进行删除。
#删除全为空值的行
data = pd.read_csv("./data.csv")
print(data.dropna(how="all")) #图1
#删除行的缺失值个数大于指定阈值的行
#删除缺失值个数大于2的行
print(data.dropna(thresh=2)) #图2
#删除指定列包含缺失值的行
print(data.dropna(subset=["C"])) #删除C列包含缺失值的行 图3
三、Python中Sklearn库处理缺失值
from sklearn.preprocessing import Imputer
data = pd.read_csv("./data.csv") #原始数据如上图
#填补缺失值
my_inputer=Imputer()
data_with_imputed_values=my_imputer.fit_transform(data)
print(data_with_imputed_values) #填补后结果如下图
四、缺失值处理案例(一)----疝气病数据集预处理
1.处理缺失值,以便使用分类算法
对数据集进行预处理,使其可以顺利地使用分类算法。在预处理阶段需要做两件事:
(1)所有的缺失值必须用一个实数值来替换,因为我们使用的Numpy数据类型不允许包含缺失值,这里选择实数0来替换所有缺失值,恰好能适用于Logistic回归。另外,由于Sigmoid(0)=0.5,即它对结果的预测不具有任何的倾向性,因此上述做法不会对误差项造成任何影响。基于上述原因,将缺失值用0代替既可以保留现有数据,也不需要对优化算法进行修改。回归系数的更新公式如下:
weights=weights+alpha*error*dataMatrix[randIndex]
如果dataMatrix的某特征对应值为0,那么该特征的系数将不做更新,即:
weights=weights
如果在测试数据集中发现一条数据的类别标签已经缺失,那么我们的简单做法是将该条数据丢弃。这是因为类别标签与特征不同,很难确定采用某个合适的值来替换。
原始的数据经过预处理之后保存成两个文件:horseColicTest.txt和horseColicTraining.txt。
参考文献
1.【Machine Learning in Action --5】逻辑回归(LogisticRegression)从疝气病预测病马的死亡率
2. 数据的预处理之缺失值处理