四、随机森林回归
1、参数介绍
下面使用的参数是MSE:
sklearn.ensemble.RandomForestClassifier (n_estimators='warn', criterion='mse', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None)
回归树衡量分枝质量的指标:
- MSE mean squard error 均方误差
- friedman_mse 费里德曼均方误差
- MAE 绝对平均误差 mean absolute error 使用叶子节点中的中值来最小化L1损失
【1】N:样本量。
【2】i:是每个样本。
【3】fi:是模型回归得到的数值。
【4】yi:是样本点i实际的数值标签。
【5】MSE是样本真实数据与回归结果的差异。不只是分枝质量衡量的指标,也是用来衡量回归树回归质量的指标。在使用交叉验证,或者其他方式获取回归树的时候,往往选择均方误差作为评估的标准,MSE追求越小越好。
分类树中用score代表准确率,但在回归树中score返回的是R平方:
【1】u:残差平方和
【2】v:总平方和
【3】残差平方和远远大于总平方和,则模型非常差,R平方就会为负数。取值范围是1到负无穷,越接近1越好。
【4】neg_mean_squared_error:sklearn在进行模型评估指标的时候,会考虑指标本身的性质,由于均方误差本身是一种误差,会被sklearn划定为是某一种损失,而在sklearn当中是以负数表示损失。
(1)随机森林回归用法
这里使用sklearn自带的数据集——波士顿房价
# 和决策树完全一致,除了多了参数n_estimators # 这里使用sklearn自带的数据集——波士顿房价 from sklearn.datasets import load_boston from sklearn.model_selection import cross_val_score from sklearn.ensemble import RandomForestRegressor import sklearn boston=load_boston() regressor=RandomForestRegressor(n_estimators=100,random_state=0) cross_val_score(regressor,boston.data,boston.target,cv=10,scoring="neg_mean_squared_error") sorted(sklearn.metrics.SCORERS.keys()) # SCORERS.keys是整个随机森林里面使用的标签
上面的代码中如果参数scoring不写成scoring="neg_mean_squared_error",那么交叉验证模型的衡量指标默认就是R平方,因此交叉验证的结果可能为正也可能为负数。如果写上了scoring="neg_mean_squared_error",则衡量的标准是负的均方误差,那么交叉验证的结果只能是为负数。
如下所示:
cross_val_score(regressor,boston.data,boston.target,cv=10,scoring="neg_mean_squared_error") cross_val_score(regressor,boston.data,boston.target,cv=10)
2、利用随机森林回归算法进行缺失值填充
(1)导入库
#(1)导入库 import sklearn import matplotlib.pyplot as plt import pandas as pd from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.model_selection import cross_val_score from sklearn.datasets import load_boston from sklearn.model_selection import cross_val_score from sklearn.ensemble import RandomForestRegressor
(2)以波士顿数据集为例,导入完整的数据集并探索
# (2)以波士顿数据集为例,导入完整的数据集并探索 dataset=load_boston() dataset.data.shape X_full,y_full=dataset.data,dataset.target n_samples=X_full.shape[0] n_features=X_full.shape[1]
通过使用shape观察数据是否存在缺失值:
(3)人为设置缺失值
# (3)人为设置缺失值 rng=np.random.RandomState(0) missing_rate=0.5 # 将数据的50%弄成缺失值 n_missing_samples=int(np.floor(n_samples * n_features * missing_rate))
由上面得知共有6578个数据,我们选取其中的3289个数据做缺失值
# 构建缺失值的行列坐标 missing_features=rng.randint(0,n_features,n_missing_samples) missing_samples=rng.randint(0,n_samples,n_missing_samples)
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)
(4)使用0和均值填补缺失值
# (4)使用0和均值填补缺失值 # 使用均值进行填补 from sklearn.impute import SimpleImputer imp_mean=SimpleImputer(missing_values=np.nan,strategy='mean') X_missing_mean=imp_mean.fit_transform(X_missing) # 使用01进行填补 imp_0=SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0) X_missing_0=imp_0.fit_transform(X_missing)
sortindex=np.argsort(X_missing_reg.isnull().sum(axis=0)).values # 对缺失值的数据进行排序 sortindex # 得到缺失值排序之后的索引
(5)使用随机森林填补缺失值
# (5)使用随机森林填补缺失值 from sklearn.impute import SimpleImputer X_missing_reg=X_missing.copy() 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) # 将y_full)变成特征值而非标签值,并进行合并 # 在新特征矩阵中,对含有缺失值的列,进行0的填补 df_0=SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0).fit_transform(df) # 找出我们的训练集和测试集 Ytrain=fillc[fillc.notnull()] Ytest=fillc[fillc.isnull()] Xtrain=df_0[Ytrain.index,:] Xtest=df_0[Ytest.index,:] # 用随机森林回归来填补缺失值 rfc=RandomForestRegressor(n_estimators=100) rfc=rfc.fit(Xtrain,Ytrain) Ypredict=rfc.predict(Xtest) # 将填补好的特征返回我们的原始特征矩阵中 X_missing_reg.loc[X_missing_reg.iloc[:,i].isnull(),i]=Ypredict
X_missing_reg.isnull().sum()
(6)对于填充后的数据进行建模
# (6)对于填充后的数据进行建模 X=[X_full,X_missing_mean,X_missing_0,X_missing_reg] # 四种填充,分别是原始数据填充,均值填充缺失值,0填充缺失值,随机森林回归填充缺失值 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)
# 对四种填充进行MSE值的比较: # 对于MSE来说,值越小越好 [*zip(['X_full','X_missing_mean','X_missing_0','X_missing_reg'],mse)]
(7)用所得结果画出条形图
# (7)用所得结果画出条形图 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()
由下图知,使用均值填充的效果最差,因为其MSE最大,而回归填充的效果是最好的。
由下图知,使用均值填充的效果最差,因为其MSE最大,而回归填充的效果是最好的。
#(1)导入库 from sklearn.datasets import load_breast_cancer # 乳腺癌数据 from sklearn.model_selection import GridSearchCV # 网格搜索 from sklearn.model_selection import cross_val_score # 交叉验证 from sklearn.ensemble import RandomForestClassifier # 回归森林分类器
(2)导入数据,探索数据
# (2)导入数据,探索数据 data=load_breast_cancer() data
(3)进行一次简单的建模,看看模型本身在数据集上面的效果
# (3)进行一次简单的建模,看看模型本身在数据集上面的效果 rfc=RandomForestClassifier(n_estimators=100,random_state=90) score_pre=cross_val_score(rfc,data.data,data.target,cv=10).mean() # 模型,完整特殊矩阵,完整的标签,校验验证 score_pre
(4)随机森林调整的第一步:无论如何先来调整n_estimators
# (4)随机森林调整的第一步:无论如何先来调整n_estimators scorel=[] for i in range(0,200,10):# 每一次取10个 rfc=RandomForestClassifier(n_estimators=i+1, n_jobs=-1, random_state=90) score=cross_val_score(rfc,data.data,data.target,cv=10).mean() scorel.append(score) print(max(scorel),(scorel.index(max(scorel))*10)+1) plt.figure(figsize=[20,5]) plt.plot(range(1,201,10),scorel) plt.show()
由下图可以看出,大概在75附近的效果最好
(5)在确定好的范围内,进一步细化学习曲线
# (5)在确定好的范围内,进一步细化学习曲线 scorel=[] for i in range(65,75):# 上分的峰值出现在哪里,比如71,则range的设置就在这个前后 rfc=RandomForestClassifier(n_estimators=i+1, n_jobs=-1, random_state=90) score=cross_val_score(rfc,data.data,data.target,cv=10).mean() scorel.append(score) print(max(scorel),([*range(65,75)][scorel.index(max(scorel))])) plt.figure(figsize=[20,5]) plt.plot(range(65,75),scorel) plt.show()
(6)利用网格搜索做准备,网格搜索的参数
【1】调整参数max_depth
# (6)利用网格搜索做准备,网格搜索的参数 # 调整max_depth param_grid={'max_depth':np.arange(1,20,1)} rfc=RandomForestClassifier(n_estimators=72 ,random_state=90 ) GS=GridSearchCV(rfc,param_grid,cv=10) GS.fit(data.data,data.target) GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 GS.best_score_ # 返回调整好的最佳参数对应的准确率
【2】调整参数max_features
# (6)利用网格搜索做准备,网格搜索的参数 # 调整max_depth # param_grid={'max_depth':np.arange(1,20,1)} # 调整max_features param_grid={'max_features':np.arange(5,30,1)} rfc=RandomForestClassifier(n_estimators=72 ,random_state=90 ) GS=GridSearchCV(rfc,param_grid,cv=10) GS.fit(data.data,data.target) GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 GS.best_score_ # 返回调整好的最佳参数对应的准确率
【3】调整参数:min_samples_leaf
# (6)利用网格搜索做准备,网格搜索的参数 # 调整max_depth # param_grid={'max_depth':np.arange(1,20,1)} # 调整max_features # param_grid={'max_features':np.arange(5,30,1)} # 调整min_samples_leaf param_grid={'min_samples_leaf':np.arange(1,1+10,1)} rfc=RandomForestClassifier(n_estimators=72 ,random_state=90 ) GS=GridSearchCV(rfc,param_grid,cv=10) GS.fit(data.data,data.target) GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 GS.best_score_ # 返回调整好的最佳参数对应的准确率
【4】调整criterion
# (6)利用网格搜索做准备,网格搜索的参数 # 调整max_depth # param_grid={'max_depth':np.arange(1,20,1)} # 调整max_features # param_grid={'max_features':np.arange(5,30,1)} # 调整min_samples_leaf # 调整Criterion param_grid={'criterion':['gini','entropy']} rfc=RandomForestClassifier(n_estimators=72 ,random_state=90 ) GS=GridSearchCV(rfc,param_grid,cv=10) GS.fit(data.data,data.target) GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 GS.best_score_ # 返回调整好的最佳参数对应的准确率
调整完毕,总结出模型最佳的参数
# 调整完毕,总结出模型最佳的参数 rfc=RandomForestClassifier(n_estimators=72,random_state=90) score=cross_val_score(rfc,data.data,data.target,cv=10).mean() score
# 最后,对所有参数进行总结和梳理 rfc=RandomForestClassifier( n_estimators=73 ,random_state=90 ,criterion="gini" ,min_samples_split=8 ,min_samples_leaf=1 ,max_depth=12 ,max_features=2 ,max_leaf_nodes=36 ) score_pre=cross_val_score(rfc,data.data,data.target,cv=10).mean() # 模型,完整特殊矩阵,完整的标签,校验验证 score_pre