在使用python里的pandas库进行数据分析工作时,很多时候我们都会遇到这样一个问题:数据缺失。这也是大部分数据分析工作所会遇到的之一。而正确处理缺失值,也是我们在数据分析中数据预处理环节的关键的一环。
在之前的文章中,我们也介绍过关于缺失值填充的一些小技巧:
侦探L:如何处理Pandas里的缺失值(入门篇2)zhuanlan.zhihu.com今天我们继续讲讲填补缺失值的其它方法。
今天的主角:常用的机器学习库——sklearn库
设计的知识点:
- sklearn中,关于缺失值填充的impute.SimpleImputer类
- sklearn中,随机森林回归(RandomForestRegressor)填补缺失值
一、impute.SimpleImputer基本介绍
1、类体及主要参数:
sklearn.impute.SimpleImputer (missing_values=nan, strategy=’mean’, fill_value=None, verbose=0,copy=True)
它包括四个重要参数:
2、使用方法:
实例化(和类一样)
二、举例说明
首先我们还是先创建实验用的数据表:
import
之后,导入我们的impute.SimpleImputer:
from sklearn.impute import SimpleImputer
PS:使用impute.SimpleImputer类进行缺失值填充前,我们先需要将其实例化。
(1)我们先尝试对整个DataFrame进行处理,这里我们用的是均值:
df_mean = SimpleImputer(missing_values=np.nan, strategy='mean')
df = df_mean.fit_transform(df)
输出一下:
df
type(df)
注意看此时我们原来的数据表的类型!已经不再是DataFrame了,而是ndarray了。
当然,我们可以把它再转回DataFrame型:
pd.DataFrame(df)
不过我们也可以看到,我们是用“均值”填充的,而原数据表的第‘C’列都是nan值,不存在均值,因此被默认删除了。
(2)对整个数据表使用指定的数字填充,这里我们选择数字9:
df_0 = SimpleImputer(strategy="constant",fill_value=9)
df_cons = df_0.fit_transform(df)
pd.DataFrame(df_cons)
这时,数据表中只要是缺失值,都被数字9给替换了。
(3)与前面整个数据表采用同一种填补方法不同,下面,我们尝试针对不同列,采用不同的方法进行缺失值填充:
首先,我们建立一个新的数据表:
df = pd.DataFrame([[np.nan, 2, np.nan, 'a'],
[3, 4, np.nan, 'a'],
[np.nan, np.nan, np.nan, np.nan],
[np.nan, 4, np.nan, 'b']],
columns=list('ABCD'))
df
可以看到,新的数据表中出现了非数值型数据。
我们的操作目标是:
- 对A列采用均值填充;
- 对B列采用中位数填充;
- 对C列采用常数0填充;
- 对D列采用众数填充。
首先,第一步,对我们要用的4种方法进行实例化:
#均值:
df_mean = SimpleImputer(missing_values=np.nan, strategy='mean',copy=False)
#中位数:
df_median = SimpleImputer(missing_values=np.nan, strategy='median',copy=False)
#常数0:
df_0 = SimpleImputer(strategy="constant",fill_value=0,copy=False)
#众数:
df_most_frequent = SimpleImputer(missing_values=np.nan, strategy='most_frequent',copy=False)
接着,对不同的列使用不同的方法:
#A列
df_A = df.loc[:,'A'].values.reshape(-1,1)
df.loc[:,'A']=df_mean.fit_transform(df_A)
#B列
df_B = df.loc[:,'B'].values.reshape(-1,1)
df.loc[:,'B']=df_median.fit_transform(df_B)
#C列
df_C = df.loc[:,'C'].values.reshape(-1,1)
df.loc[:,'C']=df_0.fit_transform(df_C)
#D列
df_D = df.loc[:,'D'].values.reshape(-1,1)
df.loc[:,'D']=df_most_frequent.fit_transform(df_D)
修改成功~
查看一下我们的修改结果:
df
不错~
(4)最后,给大家介绍在机器学习中,另一种缺失值填充的有效方法——随机森林回归(RandomForestRegressor)填补缺失值。
首先,新创建一个数据表:
df = pd.DataFrame({'Country':[12,34,23,45,34,23,12,2,3],
'Income':[10000, 10000, 5000, 5002, 40000, 50000, 8000, 5000,3000],
'Age':[50, 43, 34, 40, 25, 25, 45, 32,12],'填充列':[2,4,7,4,5,np.nan,np.nan,np.nan,np.nan]})
df
可以看到,在‘填充列’这一列出现了较多的缺失值,其他列没有出现缺失值。
首先,导入机器学习中的随机森林回归(RandomForestRegressor)方法:
from sklearn.ensemble import RandomForestRegressor
接着,将我们的数据集分成两部分:
第一部分,不含缺失值的其他所有列:
df_full=df.drop(labels='填充列',axis=1)
df_full
第二部分,含缺失值的那一列:
df_nan=df.loc[:,'填充列']
df_nan
然后,区别测试集与训练集:
#区别我们的训练集和测试集
Ytrain = df_nan[df_nan.notnull()]
Ytest = df_nan[df_nan.isnull()]
Xtrain = df_full.iloc[Ytrain.index]
Xtest = df_full.iloc[Ytest.index]
接着,实例化,然后用随机森林回归来填补缺失值:
#用随机森林回归来填补缺失值
rfc = RandomForestRegressor(n_estimators=100)
rfc = rfc.fit(Xtrain, Ytrain)
Ypredict = rfc.predict(Xtest)
完成~
看看我们的预测结果(即代替原来缺失的结果):
Ypredict
将结果填补到我们原来的数据表中:
df_nan[df_nan.isnull()] = Ypredict
此时,我们的填补过程已经全部结束,让我们再次看看我们数据集填补后的样子:
df
成功!撒花~
(5)随机森林回归(RandomForestRegressor)填补缺失值的原理
最后,我们讲一下使用随机森林回归填补缺失值的原理。任何回归都是从特征矩阵中学习,然后求解连续型标签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
这种做法,对于某一个特征大量缺失,其他特征却很完整的情况,非常适用。
注~
在本文随机森林回归那个例子中,有缺失值的那列,就相当于原理里说的标签,而其他不含缺失值的列,相当于特征矩阵~
以上便是<如何填补Pandas中的缺失值(机器学习入门篇)>的内容,感谢大家的细心阅读,同时欢迎感兴趣的小伙伴一起讨论、学习,想要了解更多内容的可以看我的其他文章,同时可以持续关注我的动态~