导包
1 | import numpy as np |
以波士顿数据集为例,导入完整的数据集并探索
1 | datasets = load_boston() # 回归数据集 |
1 | X_full, y_full = datasets.data, datasets.target |
为完整数据集放入缺失值
1 | # 首先确定放入缺失数据的比例 |
1 | # 确定要填补的行索引 和 列索引 |
1 | X_missing = X_full.copy() |
1 | X_missing.head(10) |
使用0和均值填补缺失值
1 | # 均值填充 |
1 | # 查看是否有缺失值 |
1 | # 0填充 |
1 | # 查看是否有缺失值 |
使用随机森林填补缺失值
任何回归都是从特征矩阵中学习,然后求解连续型标签y的过程,之所以能够实现这个过程,是因为回归算法认为,特征矩阵和标签之前存在着某种联系。实际上,标签和特征是可以相互转换的,比如说,在一个“用地区,环境,附近学校数量”预测“房价”的问题中,我们既可以用“地区”,“环境”,“附近学校数量”的数据来预测“房价”,也可以反过来,用“环境”,“附近学校数量”和“房价”来预测“地区”。而回归填补缺失值,正是利用了这种思想。
对于一个有n个特征的数据来说,其中特征 T 有缺失值,我们就把特征 T 当作标签,其他的 n-1 个特征和原本的标签组成新的特征矩阵。那对于 T 来说,它没有缺失的部分,就是我们的 Y_test,这部分数据既有标签也有特征,而它缺失的部分,只有特征没有标签,就是我们需要预测的部分。
特征 T 不缺失的值对应的其他 n-1 个特征 + 本来的标签:X_train
特征 T 不缺失的值:Y_train
特征 T 缺失的值对应的其他 n-1 个特征 + 本来的标签:X_test
特征 T 缺失的值未知,我们需要预测的:Y_test
这种做法,对于某一个特征大量缺失,其他特征却很完整的情况,非常适用。
那如果数据中除了特征 T 之外,其他特征也有缺失值怎么办?
答案是遍历所有的特征,从缺失最少的开始进行填补(因为填补缺失最少的特征所需要的准确信息最少)。填补一个特征时,先将其他特征的缺失值用0代替,每完成一次回归预测,就将预测值放到原本的特征矩阵中,再继续填补下一个特征。每一次填补完毕,有缺失值的特征会减少一个,所以每次循环后,需要用0来填补的特征就越来越少。当进行到最后一个特征时(这个特征应该是所有特征中缺失值最多的),已经没有任何的其他特征需要用0来进行填补了,而我们已经使用回归为其他特征填补了大量有效信息,可以用来填补缺失最多的特征。
遍历所有的特征后,数据就完整,不再有缺失值了。
1 | X_missing_rtf = X_missing.copy() |
1 | for i in sortindex: |
1 | # 查看是否有缺失值 |
对填补好的数据进行建模
1 | X = [X_full, X_missing_mean, X_missing_0, X_missing_rtf] |
1 | [*zip(["X_full", "X_missing_mean", "X_missing_0", "X_missing_rtf"], mses)] # mse越小越好 |
用所得结果画出条形图
1 | x_labels = ['full data', 'zero imputation', 'mean imputation', 'regressor imputation'] |