随机森林总结 - RandomForestRegressor填充缺失值(三)

1,815 阅读3分钟

根据菜菜的课程进行整理,方便记忆理解

代码位置如下:

用随机森林回归填补缺失值

我们从现实中收集的数据,几乎不可能是完美无缺的,往往都会有一些缺失值。面对缺失值,很多人选择的方式是直接将含有缺失值的样本删除,这是一种有效的方法,但是有时候填补缺失值会比直接丢弃样本效果更好,即便我们其实并不知道缺失值的真实样貌。在sklearn中,我们可以使用sklearn.impute.SimpleImputer来轻松地将均值中值,或者其他最常用的数值填补到数据中.

实验目的

将使用均值,0,和随机森林回归来填补缺失值,并验证四种状况下的拟合状况,找出对使用的数据集来说最佳的缺失值填补方法。

  • 导入需要的库
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.impute import SimpleImputer
from sklearn.datasets import load_boston
from sklearn.model_selection import cross_val_score
  • 以波士顿数据集为例,导入完整的数据集并探索
boston = load_boston()

boston.data
boston.data.shape

# 多少条数据
n_simples = boston.data.shape[0]
n_simples

# 多少个特征
n_features = boston.data.shape[1]
n_features
  • 为完整数据集放入缺失值
    • 思路就是:我们获取指定数量的随机的横纵坐标,在将两个坐标结合,在结合后的数据中填上nan
# 制造缺失值数据
rng = np.random.RandomState(0)
missing_rate = 0.5
n_missing_simples = int(np.floor(n_simples * n_features * missing_rate))

n_missing_simples

# 我们想要将某一个数据制成空值,我们需要知道这个值的横纵坐标
# 注意randint的用法,我们可以randint(a,b,c) 我们从a~b取出来c个值,最后形成一个列表
missing_simples = np.random.randint(0,n_simples,n_missing_simples)
missing_features = np.random.randint(0,n_features,n_missing_simples)

missing_simples
missing_features

x_missing = x_full.copy()
y_missing = y_full.copy()

x_missing[missing_simples,missing_features]=np.nan

data = pd.DataFrame(x_missing)
data.head(10)

image.png

  • 使用0和均值填补缺失值
# 使用均值进行填补
imp_mean = SimpleImputer(missing_values=np.nan,strategy="mean")
x_missing_mean = imp_mean.fit_transform(x_missing)

# 使用0进行填充
imp_0 = SimpleImputer(missing_values=np.nan,strategy="constant",fill_value=0)
x_missing_0 = imp_0.fit_transform(x_missing)

image.png

使用随机森林填补缺失值(重点)

  • 思想:
    • 平时我们使用回归的方法针对特征进行建模然后通过模型对标签数据进行预测
    • 在填补缺失值的情况下,我们得到的数据实际上标签是没有缺失的,我们的特征列缺失,此时我们可以将标签作为一个特征,将还有缺失值的特征列作为标签,我们就可以使用随机森林的方式将非缺失值的部分当成训练集,将含有缺失值的部分作为测试集,使用随机森林进行预测,最后将预测的结果填入到我们的缺失值的特征列,完成特征列的填补
    • 多个特征列的缺失值我们怎样处理
      • 我们可以先对缺失值的特征列进行一个排序,先从缺失值少的列,先进行进行填充,逐渐的见所有的缺失值的列填充完全
      • 在我们填充一列的时候,其他的列也存在缺失值,我们可以先用0进行填充缺失值,然后不断填充就会有新数据替换nan空数据,最后就会将所有的缺失值全部替换掉
x_missing = pd.DataFrame(x_missing)
x_missing_reg = x_missing.copy()
sortindex = np.argsort(x_missing_reg.isnull().sum(axis=0)).values

sortindex

# 重点
for i in sortindex:
    # 注意在这个地方,我们要对除了要填充列的数据,其他的列首先都要进行填充,所以为了后续填充,不污染原始数据,我们赋值临时变量
    df = x_missing_reg
    fillc = df.iloc[:,i]
    df = pd.concat([df.iloc[:,df.columns!=i],pd.DataFrame(y_full)],axis=1)
    
    # 使用0进行填充
    imp_0 = SimpleImputer(missing_values=np.nan,strategy="constant",fill_value=0).fit_transform(df)
    
    Ytrain = fillc[fillc.notnull()]
    Ytest = fillc[fillc.isnull()]
    Xtrain = imp_0[Ytrain.index,:]
    Xtest = imp_0[Ytest.index,:]
    
    # 建模进行预测
    rfr = RandomForestRegressor(n_estimators=100)
    rfr = rfr.fit(Xtrain,Ytrain)
    Ypredict = rfr.predict(Xtest)
    
    # 将随机森林进行预测后的数据填充到原始数据中
    x_missing_reg.loc[x_missing_reg.iloc[:,i].isnull(),i] = Ypredict
  • 对填补好的数据进行建模
# 我们将未填充,0填充,随机森林填充,平均值填充 训练数据,记录误差
X = [x_full,x_missing_mean,x_missing_0,x_missing_reg]
mse = []
std = []
for x in X:
    estimator = RandomForestRegressor(random_state=0, n_estimators=100)
    scores = cross_val_score(estimator,x,y_full,scoring='neg_mean_squared_error', cv=5).mean()
    mse.append(scores * -1)
  • 用所得结果画出条形图
x_labels = ['Full data','Zero Imputation','Mean Imputation','Regressor Imputation']
colors = ['r', 'g', 'b', 'orange']
plt.figure(figsize=(12, 6))
ax = plt.subplot(111)
for i in np.arange(len(mse)):
    ax.barh(i, mse[i],color=colors[i], alpha=0.6, align='center')
ax.set_title('Imputation Techniques with Boston Data')
ax.set_xlim(left=np.min(mse) * 0.9,right=np.max(mse) * 1.1)
ax.set_yticks(np.arange(len(mse)))
ax.set_xlabel('MSE')
ax.set_yticklabels(x_labels)
plt.show()

image.png