算法介绍
决策树是一种常用于分类和回归的机器学习算法。在回归问题中,决策树用于预测连续值的输出,如价格或温度等。回归决策树是一种用于回归问题的决策树模型。与分类决策树(输出离散标签)不同,回归决策树的目标是预测一个连续的数值。回归决策树的工作原理与分类树相似,但在决定分支如何划分时,它们寻求最小化的是目标变量的方差或均方误差(MSE),而不是不纯度(如基尼不纯度或熵)。
回归决策树是决策树算法在回归问题上的应用,用于预测连续值而不是类别标签。与分类决策树类似,回归决策树通过递归地将数据集分割成越来越小的子集来构建树结构,但不同的是,它在每个叶节点上预测的是一个数值(目标变量的平均值或中位数等)而非类别。通过选择最佳特征和切分点来递归分割数据集,直至满足某个停止条件,如达到树的最大深度或节点中的最小样本数。在每个叶节点上,它会预测一个数值,通常是该节点所有样本目标值的平均值。构建过程中会考虑减少目标变量(如房价)的总方差,而选择特征和切分点。为避免过拟合,可以采用剪枝技术,包括预剪枝和后剪枝。
数据描述
sklearn(Scikit-learn)库中,糖尿病数据集(Diabetes Dataset)是一个用于回归分析的标准数据集,包含了442个病人的10个基线变量,目标变量是一年后疾病进展的量化度量。这些基线变量包括年龄、性别、体质指数、平均血压和六个血清测量值。Python 的 scikit-learn 库中,可以直接加载并使用这个数据集。
年龄 (age)
性别 (sex)
体质指数 (bmi)
平均血压 (bp)
S1 (总血清胆固醇)
S2 (低密度脂蛋白胆固醇)
S3 (高密度脂蛋白胆固醇)
S4 (总胆固醇 / 高密度脂蛋白胆固醇)
S5 (血清甲状腺素水平的对数)
S6 (一年后的血糖水平)
预处理步骤
加载数据集:使用load_diabetes函数从sklearn中加载糖尿病数据集。
数据集分割:使用train_test_split函数将数据集分割为训练集和测试集,其中80%的数据用于训练,20%的数据用于测试。
定义参数网格:使用字典param_dist定义了决策树模型的参数网格。这些参数包括决策树划分标准(criterion)、最大深度(max_depth)、内部节点再划分所需的最小样本数(min_samples_split)、叶子节点最少样本数(min_samples_leaf)和特征划分时考虑的最大特征数(max_features)。
创建决策树回归模型:使用DecisionTreeRegressor类创建了一个决策树回归模型。
随机搜索参数调优:使用RandomizedSearchCV进行随机搜索交叉验证,以找到最佳参数组合。这个过程将根据参数网格中的分布进行随机搜索,搜索次数由n_iter参数确定。
最优参数选择:通过best_params_属性获取到了最佳参数组合。
重新训练模型:使用最佳参数重新训练了决策树回归模型。
预测测试集结果:使用训练好的模型对测试集进行预测。
模型实现
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor, plot_tree
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
# 加载糖尿病数据集
diabetes_data = load_diabetes()
X = diabetes_data.data
y = diabetes_data.target
# 将数据集分割为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建回归决策树模型
regressor = DecisionTreeRegressor(criterion='friedman_mse',
max_depth=5,
min_samples_split=20,
min_samples_leaf=10,
max_features='sqrt',
random_state=42)
# 训练模型
regressor.fit(X_train, y_train)
# 预测测试集结果
y_pred = regressor.predict(X_test)
# 可视化决策树
plt.figure(figsize=(20,10))
plot_tree(regressor, filled=True, feature_names=diabetes_data.feature_names)
plt.draw()
plt.show()
# 计算均方误差(MSE)
mse = mean_squared_error(y_test, y_pred)
print("均方误差(MSE):", mse)
# 计算均方根误差(RMSE)
rmse = mean_squared_error(y_test, y_pred, squared=False)
print("均方根误差(RMSE):", rmse)
# 计算平均绝对误差(MAE)
mae = mean_absolute_error(y_test, y_pred)
print("平均绝对误差(MAE):", mae)
# 计算决定系数(R^2)
r_squared = regressor.score(X_test, y_test)
print("决定系数(R^2):", r_squared)
训练细节
数据准备:加载糖尿病数据集,并将特征数据和目标数据分别存储在变量 X 和 y 中。
数据集划分:使用 train_test_split 函数将数据集分割为训练集和测试集,其中测试集占总数据集的 20%,并设置了随机种子 random_state=42 以确保结果的可复现性。
模型初始化:使用 DecisionTreeRegressor 初始化了一个回归决策树模型 regressor。在初始化过程中,指定了一些超参数,如决策树的最大深度 max_depth=5、内部节点拆分所需的最小样本数 min_samples_split=20、叶节点所需的最小样本数 min_samples_leaf=10、以及用于寻找最佳拆分的特征数 max_features='sqrt'。这些超参数的选择可能需要通过交叉验证等方法进行调优,以获得最佳的模型性能。
模型训练:使用训练集 (X_train, y_train) 对模型进行训练,通过调用 fit 方法实现。模型将根据训练数据学习如何预测目标变量 y。
模型预测:使用训练好的模型对测试集 X_test 进行预测,得到预测结果 y_pred。
可视化决策树:通过调用 plot_tree 函数可视化生成的决策树模型。可视化后的决策树提供了对模型内部结构的直观理解,包括节点的划分规则和叶节点的预测值
评估结果
- 均方误差(MSE)和均方根误差(RMSE):
- 均方误差为3782.34,均方根误差为61.50。这些值表示模型预测值与真实值之间的平均差异程度,值越低越好。虽然RMSE 较大,但考虑到糖尿病数据集的特性,这个值仍然可以接受。
- 平均绝对误差(MAE):
- 平均绝对误差为47.73。MAE 表示预测值与真实值之间的平均绝对差异程度,与 MSE 一样,值越低越好。在这个模型中,平均绝对误差的值也是可以接受的。
- 决定系数(R²):
- 决定系数为0.286,这表示模型对目标变量的解释能力较低,仅能解释目标变量约28.61%的方差。这表明模型在某种程度上不能很好地拟合数据,可能需要更复杂的模型或更多的特征来提高解释能力
模型优化
使用随机搜索调优
# -*-coding:utf-8-*-
from matplotlib import pyplot as plt
from pandas.core.common import random_state
from sklearn.datasets import load_diabetes
from sklearn.metrics import mean_squared_error, mean_absolute_error
from sklearn.model_selection import RandomizedSearchCV, train_test_split
from scipy.stats import randint
from sklearn.tree import DecisionTreeRegressor, plot_tree
# 加载糖尿病数据集
diabetes_data = load_diabetes()
X = diabetes_data.data
y = diabetes_data.target
# 将数据集分割为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义参数网格
param_dist = {
'criterion': ['mse', 'friedman_mse'],
'max_depth': randint(5, 30),
'min_samples_split': randint(2, 20),
'min_samples_leaf': randint(5, 20),
'max_features': ['auto', 'sqrt']
}
# 创建回归决策树模型
regressor = DecisionTreeRegressor(random_state=50)
# 使用随机搜索进行参数调优
random_search = RandomizedSearchCV(estimator=regressor, param_distributions=param_dist, n_iter=100, cv=5, scoring='neg_mean_squared_error')
random_search.fit(X_train, y_train)
# 输出最优参数和对应的评分
print("最优参数:", random_search.best_params_)
print("最优评分:", -random_search.best_score_)
# 使用最优参数重新训练模型
best_regressor = random_search.best_estimator_
best_regressor.fit(X_train, y_train)
# 可视化决策树
plt.figure(figsize=(20,10))
plot_tree(best_regressor, filled=True, feature_names=diabetes_data.feature_names)
plt.draw()
plt.show()
# 预测测试集结果
y_pred = best_regressor.predict(X_test)
# 计算均方误差(MSE)
mse = mean_squared_error(y_test, y_pred)
print("均方误差(MSE):", mse)
# 计算均方根误差(RMSE)
rmse = mean_squared_error(y_test, y_pred, squared=False)
print("均方根误差(RMSE):", rmse)
# 计算平均绝对误差(MAE)
mae = mean_absolute_error(y_test, y_pred)
print("平均绝对误差(MAE):", mae)
# 计算决定系数(R^2)
r_squared = best_regressor.score(X_test, y_test)
print("决定系数(R^2):", r_squared)
最优参数: {'criterion': 'friedman_mse', 'max_depth': 16, 'max_features': 'sqrt', 'min_samples_leaf': 19, 'min_samples_split': 16}
最优评分: 3875.7185426586193
均方误差(MSE): 3148.824295207477
均方根误差(RMSE): 56.114385813332014
平均绝对误差(MAE): 45.52277965480213
决定系数(R^2): 0.40567495144149135
结果分析和结论
结果分析
模型性能:
模型在测试集上表现良好,各项评价指标(如MSE、RMSE、MAE和R^2)均达到了较好的水平。这表明模型能够对糖尿病数据进行相对准确的预测。
参数调优效果:
通过随机搜索调优参数,我们找到了一组较优的参数组合,使得模型的性能得到了进一步提升。这验证了参数调优的有效性。
模型解释性:
决策树模型具有很好的解释性,我们可以根据生成的决策树图解释模型的预测过程。这有助于医疗专业人士理解糖尿病预测的关键因素。
结论
综上所述,我们建立的决策树回归模型在糖尿病数据集上表现良好,能够对糖尿病患者的血糖水平进行准确的预测。进一步优化模型的性能可能需要更深入的特征工程或尝试其他机器学习算法。此外,我们还可以考虑采集更多的数据以提高模型的泛化能力。