赞
踩
一:概述
将决策树运用到回归问题上,则为回归树。对于回归问题,响应变量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()查看树的深度和叶节点数目。接下来可考察每个变量的重要性,在此就不介绍了。有需要的可以私信,评论等。
写的有点草率,感谢大家,求赞谢谢!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。