随机森林回归器学习

  关于回归器的相关介绍可以看前面回归决策树的文章,由于随机森林回归器是基于回归决策树的,所以基本的概念是相同的,比如衡量标准,其他的基本属性参数等等......

  这里主要是对随机森林回归器的一个简单运用,调用一个完整的boston房价数据集,人为的使数据集变为缺失数据集,分别采用均值法、补0法、随机森林回归填充法三种方式来对缺失数据进行填补,最后采用随机森林回归器分别对不同的填充数据进行预测,得到三种方式的预测结果。

  对于均值填充和0填充容易理解,主要是随机森林填充缺失数据是什么意思?

  任何回归都是从特征矩阵中学习,然后求解连续型标签y的过程,之所以能够实现这个过程,是因为回归算法认为,特征矩阵和标签之前存在着某种联系。实际上,标签和特征是可以相互转换的,比如说,在一个“用地区,环境,附近学校数 量”预测“房价”的问题中,我们既可以用“地区”,“环境”,“附近学校数量”的数据来预测“房价”,也可以反过来, 用“环境”,“附近学校数量”和“房价”来预测“地区”。而回归填补缺失值,正是利用了这种思想。也就是某种特征与标签互换了角色,实现特征的求值。这比直接使用均值或者0填充更有说服力。

  对于一个有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来进行填补了, 而我们已经使用回归为其他特征填补了大量有效信息,可以用来填补缺失多的特征。 遍历所有的特征后,数据就完整,不再有缺失值了。

实现过程:

X_missing_reg = X_missing.copy()

#找出数据集中,缺失值从小到大排列的特征们的顺序,并且有了这些的索引
sortindex = np.argsort(X_missing_reg.isnull().sum(axis=0)).values#np.argsort()返回的是从小到大排序的顺序所对应的索引
 
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的填补
    df_0 =SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0).fit_transform(df)
                        
    #找出我们的训练集和测试集
    Ytrain = fillc[fillc.notnull()]# Ytrain是被选中要填充的特征中(现在是我们的标签),存在的那些值:非空值
    Ytest = fillc[fillc.isnull()]#Ytest 是被选中要填充的特征中(现在是我们的标签),不存在的那些值:空值。注意我们需要的不是Ytest的值,需要的是Ytest所带的索引
    Xtrain = df_0[Ytrain.index,:]#在新特征矩阵上,被选出来的要填充的特征的非空值所对应的记录
    Xtest = df_0[Ytest.index,:]#在新特征矩阵上,被选出来的要填充的特征的空值所对应的记录
    
    #用随机森林回归来填补缺失值
    rfc = RandomForestRegressor(n_estimators=100)#实例化
    rfc = rfc.fit(Xtrain, Ytrain)#导入训练集进行训练
    Ypredict = rfc.predict(Xtest)#用predict接口将Xtest导入,得到我们的预测结果(回归结果),就是我们要用来填补空值的这些值
    
    #将填补好的特征返回到我们的原始的特征矩阵中
    X_missing_reg.loc[X_missing_reg.iloc[:,i].isnull(),i] = Ypredict

 

主要流程介绍:

  首先导入数据集,查看数据集长什么样

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.impute import SimpleImputer# 填补缺失值的类
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score


dataset = load_boston()
dataset#是一个字典

dataset.data.shape#总共506*13=6578个数据

  接下来人为制作缺失数据集,本身boston数据集是完整的,这里是为了比较不同填补方式的优劣性

X_full, y_full = dataset.data, dataset.target
n_samples = X_full.shape[0]#506
n_features = X_full.shape[1]#13

rng = np.random.RandomState(0)#设置一个随机数生成种子
missing_rate = 0.5
n_missing_samples = int(np.floor(n_samples * n_features * missing_rate))#3289

missing_features = rng.randint(0,n_features,n_missing_samples)
#randint(下限,上限,n)指在下限和上限之间取出n个整数
missing_samples = rng.randint(0,n_samples,n_missing_samples)
#产生3289个在0-506之间的行索引

X_missing = X_full.copy() #定义缺失数据
y_missing = y_full.copy()#定义缺失标签
X_missing[missing_samples,missing_features] = np.nan 
#人为制作缺失数据集,在某行某列填NAN
X_missing = pd.DataFrame(X_missing)#转化为表格,便于后续索引操作

 可以查看缺失后的数据长什么样:有50%的数据随机被NAN填充了

 

 接着分别采用三种填充方式进行数据补全:

#使用均值进行填补
from sklearn.impute import SimpleImputer#一个用于填补缺失数据集的类
imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean')
#实例化,用 均值 的方式填补表格中的 NAN
X_missing_mean = imp_mean.fit_transform(X_missing)
#对X_missing数据表格运用imp_mean 实现均值填补

 可以看到原来的NAN全部被均值填充了

#使用0进行填补
imp_0 = SimpleImputer(missing_values=np.nan strategy="constant",fill_value=0)#constant指的是常数
X_missing_0 = imp_0.fit_transform(X_missing)

这里的 NAN全部被0填充了。

再采用最开始随机森林回归的方式填充,查看效果:

X_missing_reg = X_missing.copy()

#找出数据集中,缺失值从小到大排列的特征们的顺序,并且有了这些的索引
sortindex = np.argsort(X_missing_reg.isnull().sum(axis=0)).values#np.argsort()返回的是从小到大排序的顺序所对应的索引
 
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的填补
    df_0 =SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0).fit_transform(df)
                        
    #找出我们的训练集和测试集
    Ytrain = fillc[fillc.notnull()]# Ytrain是被选中要填充的特征中(现在是我们的标签),存在的那些值:非空值
    Ytest = fillc[fillc.isnull()]#Ytest 是被选中要填充的特征中(现在是我们的标签),不存在的那些值:空值。注意我们需要的不是Ytest的值,需要的是Ytest所带的索引
    Xtrain = df_0[Ytrain.index,:]#在新特征矩阵上,被选出来的要填充的特征的非空值所对应的记录
    Xtest = df_0[Ytest.index,:]#在新特征矩阵上,被选出来的要填充的特征的空值所对应的记录
    
    #用随机森林回归来填补缺失值
    rfc = RandomForestRegressor(n_estimators=100)#实例化
    rfc = rfc.fit(Xtrain, Ytrain)#导入训练集进行训练
    Ypredict = rfc.predict(Xtest)#用predict接口将Xtest导入,得到我们的预测结果(回归结果),就是我们要用来填补空值的这些值
    
    #将填补好的特征返回到我们的原始的特征矩阵中
    X_missing_reg.loc[X_missing_reg.iloc[:,i].isnull(),i] = Ypredict

#检验是否有空值
X_missing_reg.isnull().sum()
View Code

 

 

对三种填充的数据分别进行随机森林回归训练分析:

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)

[*zip(['Full data','Zero Imputation','Mean Imputation','Regressor Imputation'],mse)]    

 

 看到以均方根误差作为评分的结果,采用随机森林回归填充的数据集在预测结果上居然比原始数据集的得分都要高,而且效果明显优于均值填充和0填充,所以在缺失数据集的填充上,随机森林回归填充可以多多考虑。

 

 

  

 

posted @ 2020-05-15 16:38  victorywr  阅读(2225)  评论(0编辑  收藏  举报