陈强-机器学习及Python应用-12.8 回归问题的随机森林案例

前言

入门机器学习,记录学习日常,如有错误请多指正。
参考书目:机器学习及Python应用
数据集可在陈强教授主页下载

一、数据预处理

1.数据介绍

案例采用波士顿房价数据, 它包含了波士顿地区1970年房价的中位数与各种影响房价的因素。数据集共有506个数据点,每个数据点包含14个属性,其中13个是数值型特征,如城镇人均犯罪率、住宅用地比例等,以及一个目标变量即房价中位数(MEDV)。

2.导入模块和数据文件

1)导入案例所需的全部模块

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold,StratifiedKFold
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import BaggingRegressor
from sklearn.ensemble import RandomForestRegressor

2)导入数据

data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep=r"\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])#自变量
target = raw_df.values[1::2, 2]#引入Boston房价数据
boston = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :3]])
names = ["CRIM", "ZN", "INDUS", "CHAS", "NOX", "RM", "AGE", "DIS", "RAD", "TAX", "PTRATIO", "B", "LSTAT", "MEDV"]
Boston=pd.DataFrame(boston,columns=names)#数据与变量名匹配

3.随机抽样

X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.3,random_state=1)

二、袋装法

1.BaggingRegressor参数

def __init__(self,
             estimator: Any = None,#基估计器,默认决策树
             n_estimators: Any = 10,#要集成的基估计器的数量
             *,
             max_samples: Any = 1.0,#这个参数决定了从训练集x_train中抽取用来训练基估计器的样本数量。可以是整数,表示具体的样本数,也可以是浮点数,表示抽取的比例。默认值为1.0,意味着使用全部样本进行训练。
             max_features: Any = 1.0,#这个参数决定了从x_train中抽取用来训练基估计器的特征数量。同样可以是整数或浮点数,分别表示具体的特征数或比例。默认值为1.0,意味着使用所有特征进行训练。
             bootstrap: Any = True,#样本子集的抽样方式,如果设置为True(默认值),则采用有放回的抽样方式,否则采用无放回的抽样方式。
             bootstrap_features: Any = False,#决定特征子集的抽样方式(有放回和不放回)
             oob_score: Any = False,#决定了是否使用袋外估计(out of bag estimate)来评估泛化误差。如果设置为True,则使用包外样本来评估模型的性能。
             warm_start: Any = False,
             n_jobs: Any = None,#这个参数决定了用于训练基估计器的CPU核心数
             random_state: Any = None,#随机数种子
             verbose: Any = 0) -> None

2.创建实例

model=BaggingRegressor(estimator=DecisionTreeRegressor(random_state=123),n_estimators=500,oob_score=True,random_state=0)
model.fit(X_train,y_train)

pred_oob=model.oob_prediction_#袋外预测值
print('袋外均方误差:',mean_squared_error(y_train,pred_oob))#袋外均方误差
print('袋外预测值拟合优度:',model.oob_score_)
print('测试集拟合优度:',model.score(X_test,y_test))
袋外均方误差: 11.323470116238905
袋外预测值拟合优度: 0.8605296124474909
测试集拟合优度: 0.9054552734857662

3.决策树数目对袋外误差、拟合优度影响

oob_errors=[]
oob_r2=[]
for i in range(100,301):
    model=BaggingRegressor(estimator=DecisionTreeRegressor(random_state=123)
                           ,n_estimators=i
                           ,n_jobs=-1
                           ,oob_score=True
                           ,random_state=0)
    model.fit(X_train,y_train)
    pred_oob=model.oob_prediction_
    oob_errors.append(mean_squared_error(y_train,pred_oob))
    oob_r2.append(model.oob_score_)

决策树数目对袋外误差影响图

plt.plot(range(100,301),oob_errors)
plt.xlabel('number of trees')
plt.ylabel('oob errors')
plt.title('bagging oob errors')
plt.show()

在这里插入图片描述
决策树数目对拟合优度影响图

plt.plot(range(100,301),oob_r2)
plt.xlabel('number of trees')
plt.ylabel('oob r2')
plt.title('bagging oob r2')
plt.show()

在这里插入图片描述

三、回归问题的随机森林

1.RandomForestRegressor参数

def __init__(self,
             n_estimators: Any = 100,#指定了弱分类器的个数,即随机森林中决策树的数量
             *,
             criterion: Any = "squared_error",#衡量回归效果的指标,默认为均方误差(mse)。可选的值包括均方误差(mse)和平均绝对误差
             max_depth: Any = None,#树的最大深度
             min_samples_split: Any = 2,#每个内部节点(非叶子节点)包含的最少样本数
             min_samples_leaf: Any = 1,#每个叶子结点包含的最少样本数
             min_weight_fraction_leaf: Any = 0.0,#在所有叶节点处(所有输入样本)的权重总和中的最小加权分数。
             max_features: Any = 1.0,#在分枝时考虑的特征个数
             max_leaf_nodes: Any = None,#最大叶子节点数
             min_impurity_decrease: Any = 0.0,#停止拆分节点的最小不纯度减少量
             bootstrap: Any = True,#是否使用自助采样来创建树的子样本
             oob_score: Any = False,#决定了是否使用袋外估计(out of bag estimate)来评估泛化误差。如果设置为True,则使用包外样本来评估模型的性能
             n_jobs: Any = None,##这个参数决定了用于训练基估计器的CPU核心数
             random_state: Any = None,#随机数种子
             verbose: Any = 0,
             warm_start: Any = False,
             ccp_alpha: Any = 0.0,#成本复杂性参数
             max_samples: Any = None,
             monotonic_cst: Any = None) -> None

2.创建实例

max_features=int(X_train.shape[1]/3)#将随机森林的mtry参数设置为特征变量个数的三分之一
print('特征变量选取数',max_features)
rfr=RandomForestRegressor(n_estimators=500
                          ,max_features=max_features
                          ,random_state=0)
rfr.fit(X_train,y_train)
print('随机森林测试集拟合优度:',rfr.score(X_test,y_test))
特征变量选取数 4
随机森林测试集拟合优度: 0.8959042792611034

3.预测值与实际值散点图

#预测值和实际值散点图
pred=rfr.predict(X_test)
plt.scatter(pred,y_test,alpha=0.6)
w=np.linspace(min(pred),max(pred),100)
plt.plot(w,w)
plt.xlabel('pred')
plt.ylabel('y_test')
plt.title('Random Forest Prediction')
plt.show()

在这里插入图片描述

4.变量重要性程度

print([*zip(names[:-1],rfr.feature_importances_)])
[('CRIM', np.float64(0.0597377569126417)), ('ZN', np.float64(0.0071023918547778375)), ('INDUS', np.float64(0.06430074616771687)), ('CHAS', np.float64(0.004539067482199508)), ('NOX', np.float64(0.06608220770786295)), ('RM', np.float64(0.24163513970160816)), ('AGE', np.float64(0.04537914961295981)), ('DIS', np.float64(0.07261150660590945)), ('RAD', np.float64(0.007820959753125328)), ('TAX', np.float64(0.028613490944714486)), ('PTRATIO', np.float64(0.06775422204808625)), ('B', np.float64(0.02357072090637113)), ('LSTAT', np.float64(0.3108526403020265))]

变量重要性柱状图

sorted_index=rfr.feature_importances_.argsort()#argsort()返回数组元素排序后的索引值
X=pd.DataFrame(data,columns=names[:-1])
plt.barh(range(X.shape[1]),rfr.feature_importances_[sorted_index])#水平柱状图
plt.yticks(np.arange(X.shape[1]),X.columns[sorted_index])
plt.xlabel('Feature Importance')
plt.ylabel('Feature')
plt.title('Random Forest')
plt.tight_layout()
plt.show()

在这里插入图片描述

5.偏依赖图

#lstat与RM的偏依赖图
from sklearn.inspection import PartialDependenceDisplay
PartialDependenceDisplay.from_estimator(model, X, ['LSTAT', 'RM'])
plt.show()

在这里插入图片描述
如图,变量RM对房价中位数MEDV的影响为正向,但并非线性。横轴上的地毯图标出变量RM的十分位数。变量LSTAT对MEDV的影响为反向,也非线性。

6.选择最优mtry

1)通过测试集选择最优mtry

scores=[]
for mtry in range(1,X.shape[1]+1):
    rfr1=RandomForestRegressor(max_features=mtry
                               ,n_estimators=500
                               ,random_state=123)
    rfr1.fit(X_train,y_train)
    score=rfr1.score(X_test,y_test)
    scores.append(score)
index=np.argmax(scores)#计算scores最大化的索引位置
print('最优特征变量个数',range(1,X.shape[1]+1)[index])    
最优特征变量个数 9

画出测试集拟合优度与mtry的关系图

plt.plot(range(1,X.shape[1]+1),scores,'o-')
plt.axvline(range(1,X.shape[1]+1)[index],linestyle='--',color='k',linewidth=1)
plt.xlabel('max_features')
plt.ylabel('R2')
plt.title('Choose mtry via test set')
plt.show()

在这里插入图片描述
2)通过测试集选择最优超参数有提前泄露测试集信息之嫌。更严格地,可通过10折交叉验证选择最优mtry

mtry=range(1,X.shape[1]+1)
param_grid={'max_features':mtry}
kfold=KFold(n_splits=10,shuffle=True,random_state=1)
model=GridSearchCV(RandomForestRegressor(n_estimators=300,random_state=123)
                   ,param_grid
                   ,cv=kfold
                   ,scoring='neg_mean_squared_error'
                   ,return_train_score=True)
model.fit(X_train,y_train)
print('最优mtry:',model.best_params_)
最优mtry: {'max_features': 5}

随机森林交叉验证图

cv_mse=-model.cv_results_['mean_test_score']#使“负均方误差”变为均方误差
plt.plot(mtry,cv_mse,'o-')
plt.axvline(mtry[np.argmin(cv_mse)],
            linestyle='--'
            ,color='k'
            ,linewidth=1)
plt.xlabel('max_features')
plt.ylabel('MSE')
plt.title('CV Error for Random Forest')
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值