回归树的python实例

一:概述

        将决策树运用到回归问题上,则为回归树。对于回归问题,响应变量y是连续变量。故对于回归树,可使用“最小化残差平方和”作为节点的分裂准则。这意味着,在进行节点分裂时,希望分裂后,残差平方和下降最多,即两个子节点的残差平方和之总和最小。

        为避免过拟合,对于回归树,也要使用惩罚项进行修枝,即最小化如下目标函数:

其中,Rm为第m个终节点,而负号后面的这一项为该终节点的预测值(此终节点的样本均值)。为第m个终节点的残差平方和。然后对所有终节点m=1,...,|T|进行加总,即为成本R(T)。(还是需要大家有一定的决策树的基础的,要不可能会有一点点看不懂。)

二:程序实现

        本节使用波士顿房价数据boston,演示回归树。该数据集包含1970年波士顿506个社区有关房价的14个变量。响应变量为社区房价中位数MEDV。

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.tree import DecisionTreeRegressor,export_text
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_boston
from sklearn.metrics import cohen_kappa_score

        载入boston数据集,抽取 30%作为测试集,其余70%作为训练集。train_test_split()函数可以很好的划分训练集和测试集。

Boston = load_boston() #响应变量为MEDV
X_train, X_test, y_train, y_test = train_test_split(Boston.data, Boston.target, test_size=0.3, random_state=0)
model = DecisionTreeRegressor(max_depth=2, random_state=123) #进行回归树估计,max_depth=2限制最大深度为2,使用一种改进的CART算法

        此命令创建了DecisionTreeRegressor类的一个实例model。第一个参数表示最大深度为2,第二个参数设定随机种子,以表示结果可重复。DecisionTreeRegressor使用了一种改进的CART算法(CART算法可参考西瓜书,或李航的机器学习都可以)。接下来使用fit()方法进行估计。

model.fit(X_train, y_train)
model.score(X_test, y_test)

        可以把上述结果输出,考察测试集的拟合优度。接下来打印文本格式的决策树。

print(export_text(model,feature_names=list(Boston.feature_names)))

        可以用python自带的函数画出决策树。(前提别忘了加上plt.show())

plot_tree(model, feature_names=Boston.feature_names, node_ids=True, rounded=True, precision=2)

        

        如图可知,在根节点的分裂条件为房间数RM<=6.8。如果满足此条件,则为“普宅”向左。如果不满足此条件,则为“大宅”向右。

        虽然数据集有13个特征变量,但此决策树仅仅用了两个变量,十分简明且易于解释,而且测试集的拟合优度也能达到0.6。但是规模多大的决策树具有最佳的泛化预测能力?可以通过对成本复杂性参数ccp_alpha进行交叉验证来确定。当其为0,不惩罚决策树的规模,可能导致过拟合;反之参数太大,惩罚过于严厉,可能会欠拟合,就是只剩下一个树桩了。

        针对DecisionTreeRegressor类的一个实例model,可用cost_complexity_pruning_path()方法,得到一系列ccp_alpha相对应的“叶节点总不纯度”。对于回归树,其不纯度就是均方误差MSE。可输入如下命令:

model = DecisionTreeRegressor(random_state=123)
path = model.cost_complexity_pruning_path(X_train, y_train)

其中,cost_alphas与path.impurities分别为ccp_alpha序列与相应叶节点总均方误差。更直观的,画图展示:

plt.plot(path.ccp_alphas, path.impurities, marker='o', drawstyle='steps-post')
plt.xlabel('alpha (cost-complexity parameter)')
plt.ylabel('Total Leaf MSE')
plt.title('Total Leaf MSE vs alpha for Training Set')
plt.show()

        如图,成本复杂性参数alpha为0时,并不惩罚决策树规模,导致每个观测值本身就是一个叶节点,故叶节点的总均方误差为0.当alpha上升时,对于决策树的惩罚力度增加,叶节点总均方误差随之上升。然而,在alpha的一定区间内,所得决策树规模可能不变,导致图中的曲线呈现阶梯状。最后alpha接近40时,决策树仅剩下树桩,而叶节点总均方误差达到最大:

print(max(path.ccp_alphas),  max(path.impurities))

        下面用十折交叉验证,选择最优的超参数ccp_alpha。先将path.ccp_alphas定义为一个名为param_grid的字典:

param_grid = {'ccp_alpha': path.ccp_alphas}

        然后使用sklearn的KFold类,定义一个10折随机分组kfold:

kfold = KFold(n_splits=10, shuffle=True, random_state=1) #使用sklearn的KFold类,定义一个10折随机分组kfold

        将参数网格param_grid与随机分组kfold作为参数,传给sklearn的GridSearchCV类,进行十折交叉验证:

model = GridSearchCV(DecisionTreeRegressor(random_state=123), param_grid, cv=kfold)#将参数网格param_grid与随机分组kfold作为参数,传给sklearn的GridsearchCV类
model.fit(X_train, y_train)#使用fit方法进行估计

        使用model的best_params_属性,考察最优超参数:

print(model.best_params_)

        结果就是最优的ccp_alpha值,为0.039.使用best_estimator_属性,将model重新定义为最优的决策树模型(使用最优的ccp_alpha),并考察拟合优度:

model = model.best_estimator_
model.score(X_test,y_test) #0.6848 结果显示测试集的R方上升为0.685

        结果为0.68484。也可以使用model.get_depth()和model.get_n_leaves()查看树的深度和叶节点数目。接下来可考察每个变量的重要性,在此就不介绍了。有需要的可以私信,评论等。

写的有点草率,感谢大家,求赞谢谢!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值