Bohrium
robot
新建

空间站广场

论文
Notebooks
比赛
课程
Apps
我的主页
我的Notebooks
我的论文库
我的足迹

我的工作空间

任务
节点
文件
数据集
镜像
项目
数据库
公开
决策树回归案例(三):基于PCT曲线特征预测AB2合金储氢容量
Machine Learning
随机森林
Machine Learning随机森林
Letian
更新于 2024-11-12
推荐镜像 :Basic Image:bohrium-notebook:2023-04-07
推荐机型 :c2_m4_cpu
decisiontree(v7)

Open In Bohrium

代码
文本

1 回归树算法(DecisionTreeRegressor)

在Scikit-learn中,回归树(DecisionTreeRegressor)主要用于处理回归问题,即目标变量(或称为标签)是连续性的数值。回归树通过将特征空间划分成不同的区域,并在每个区域内对目标变量的值进行预测,来解决回归问题。使用回归树的步骤包括实例化模型、训练模型与数据拟合、以及使用训练好的模型进行预测。

它可以通过DecisionTreeRegressor类在Scikit-learn中实现,该类提供了许多参数(如max_depth, min_samples_split等)来调整树的结构和解决过拟合或欠拟合的问题。

  • 实例

    回归树可视化选择 吸氢金属合金材料的 曲线的实验数据进行展示。

    () 曲线是一定温度下合金中氢浓度与氢吸收/解吸压力曲线,是在特定应用下选择吸氢材料的重要参考。

sklearn 中的回归树:

classsklearn.tree.DecisionTreeRegressor(criterion=’mse’, splitter=’best’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, presort=False)

代码
文本

1.1 重要参数

回归树衡量分枝质量的指标,支持的标准有三种:

1)输入 "squared_error" 使用均方误差 mean squared error(MSE),父节点和叶子节点之间的均方误差的差额作为特征选择的标准,这种方法通过使用叶子节点的均值来最小化 损失

2)输入 "friedman_mse" 使用费尔德曼均方误差,这种指标使用弗尔德曼针对潜在分枝中的问题改进后的均方误差

3)输入 "absolute_error" 使用绝对平均误差 (meanabsoluteerror),这种指标使用叶节点的中值来最小化 损失

属性中最重要的依然是 feature_importances_,接口依然是apply, fit, predict, score最核心。


代码
文本
  • 数据集介绍

PCT曲线中包含如下几列:

  1. Vacuometer1(Pm(Pa))

    • 解释:金属氢化物吸附氢气的平衡压力(Pm),单位为帕斯卡(Pa)。
    • 背景:平衡压力是描述氢在金属氢化物中的吸附和解吸过程中的一个关键参数。它反映了金属氢化物与氢气之间的相互作用力。
  2. Vacuometer1(Pg(Pa))

    • 解释:金属氢化物脱附氢气的平衡压力(Pg),单位同样为帕斯卡(Pa)。一般吸附氢气的压力高于脱附氢气的压力。
  3. Velocity

    • 解释:这里的 Velocity 是指氢气在样品中的传输速度。
    • 背景:传输速度是评价氢在金属氢化物中扩散效率的一个指标。较高的传输速度意味着氢气能够迅速进入或离开金属氢化物,这对于快速储氢和释放氢气具有重要意义。
  4. Capacity

    • 解释:表示氢气在样品中的存储容量。
    • 背景:储氢容量是衡量金属氢化物储氢能力的一个重要参数。较高的储氢容量表明金属氢化物能够在单位体积或质量下存储更多的氢气,是评价储氢材料性能的重要指标。
  5. Velocity(L/s)

    • 样品中氢气流动的速度,数值与Velocity列一样,单位换算为升每秒(L/s)。
  6. Capacity(Pa·L)

    • 解释:样品的氢存储容量,数值与Capacity列一样,单位换为帕斯卡·升(Pa·L)。

这些数据列分别代表了 PCT 曲线中的重要参数,它们共同描述了金属氢化物在不同压力条件下的氢吸附和解吸行为。理解这些参数对于研究和开发高效储氢材料具有重要意义。

代码
文本

1.1.1 读取数据

导入必要的库并读取数据

代码
文本
[1]
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import cross_val_score

df_PCT = pd.read_csv("/bohr/decision-tree-data-eavt/v7/PCT_Curve.csv")
df_PCT
Unnamed: 0 Vacuometer1(Pm(Pa)) Vacuometer1(Pg(Pa)) Velocity Capacity
0 0 0.09032 0.000371 25582.66086 9.503959
1 1 0.09035 0.000374 25426.24960 19.010833
2 2 0.09068 0.000372 25636.54527 28.552755
3 3 0.09059 0.000376 25384.99087 38.084819
4 4 0.09086 0.000376 25433.75899 47.645369
... ... ... ... ... ...
10055 10055 0.05535 0.000381 15256.25489 68838.308140
10056 10056 0.05517 0.000380 15218.37312 68844.097210
10057 10057 0.05522 0.000381 15220.17452 68849.891530
10058 10058 0.05504 0.000384 15023.18079 68855.666440
10059 10059 0.05517 0.000382 15142.21392 68861.455300

10060 rows × 5 columns

代码
文本

1.1.2 划分特征与标签

代码
文本
[2]
X = df_PCT.iloc[:, :3] # 取前三列数据作为特征
Y = df_PCT['Capacity'] # 取容量数据作为标签
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.3, random_state=0)

dtr = DecisionTreeRegressor(criterion="absolute_error", max_depth=2)
dtr.fit(Xtrain, Ytrain)
dtr.score(Xtest, Ytest) # score 的默认评价参数是 R2
0.9357960570623147
代码
文本

1.1.3 训练并绘制决策树模型

代码
文本
[3]
from sklearn.tree import DecisionTreeRegressor, plot_tree
import matplotlib.pyplot as plt

# 训练决策树回归器
dtr = DecisionTreeRegressor(criterion="absolute_error", max_depth=2)
dtr.fit(Xtrain, Ytrain)

# 绘制决策树
plt.figure(figsize=(20, 10))
plot_tree(dtr, filled=True, feature_names=X.columns, rounded=True)
plt.show()

代码
文本

1.2 交叉验证/剪枝参数优化

通过交叉验证(cross_val_score)评估不同深度下模型的性能,并记录每次的交叉验证得分。然后,通过绘制交叉验证得分的曲线,可以直观地观察不同剪枝程度对模型性能的影响。

代码
文本
[4]
cv_list = []

for i in range(1, 10):
dtr = DecisionTreeRegressor(criterion="squared_error" ,max_depth=i ,min_samples_leaf=10)
# scoring='neg_mean_absolute_error' # 交叉验证默认评价参数为 R2,可通过 scoring=“” 修改为其它参数,在这里不作修改
cv = cross_val_score(dtr, X, Y, cv=10)
cv_list.append(-cv.mean())
# print(f"i is {i}, the mean of cv is {cv.mean()}, the score is {dtr.score(Xtest, Ytest)}")

plt.plot(cv_list)
[<matplotlib.lines.Line2D at 0x7ff3af34deb0>]
代码
文本

1.3 回归树可视化

代码
文本

选择数据中的前600个数据进行回归树模型训练与模型性能评估

代码
文本
[18]
num = 5000
X_100 = df_PCT['Velocity'][:num][:, np.newaxis]
Y_100 = df_PCT['Capacity'][:num]
plt.scatter(X_100, Y_100)

Xtrain, Xtest, Ytrain, Ytest = train_test_split(X_100, Y_100, test_size=0.1, random_state=0)
/tmp/ipykernel_129/3139847132.py:2: FutureWarning: Support for multi-dimensional indexing (e.g. `obj[:, None]`) is deprecated and will be removed in a future version.  Convert to a numpy array before indexing instead.
  X_100 = df_PCT['Velocity'][:num][:, np.newaxis]
代码
文本

1.3.1 最大深度为2

代码
文本
[19]
dtr_2 = DecisionTreeRegressor(max_depth=2, random_state=0)
dtr_2.fit(Xtrain, Ytrain)
Ypred = dtr_2.predict(Xtest)
# 绘制决策树
plt.figure(figsize=(20, 10))
plot_tree(dtr_2, filled=True, feature_names=X.columns, rounded=True)
plt.show()

# 绘制最大深度为2时回归树的拟合效果
fig, ax = plt.subplots(ncols=2, nrows=1, sharey=True, figsize=(10, 5))
ax[0].set_xlabel('Velocity')
ax[0].set_ylabel('Capacity')
ax[0].scatter(Xtest, Ytest, s=10, label='Actual')
ax[0].scatter(Xtest, Ypred, c='orange', label="Predicted - max_depth = 2")

# 将预测结果降序排序,以便plot
df_results = pd.DataFrame(data={'Xtest': Xtest.ravel(),
'Ytest': Ytest,
'Ypred': Ypred})
df_results.sort_values('Ytest', inplace=True)

ax[1].scatter(df_results['Xtest'], df_results['Ytest'], s=10, label='Actual')
ax[1].plot(df_results['Xtest'], df_results['Ypred'], c='orange', label="max_depth = 2")

ax[0].legend() # 显示图例
ax[1].legend()

#plt.show()
<matplotlib.legend.Legend at 0x7ff3ac97ec10>
代码
文本
[13]
df_results
Xtest Ytest Ypred
9 25217.21470 95.533123 9528.929960
23 24272.31287 230.554769 9528.929960
31 24190.36336 308.183742 9528.929960
33 24068.02758 327.621304 9528.929960
36 23973.35504 356.812499 9528.929960
... ... ... ...
9964 14989.01615 68310.679930 60247.924933
9970 15115.09878 68345.477190 60247.924933
9971 15075.21614 68351.258540 60247.924933
9980 15121.48688 68403.466770 60247.924933
9983 15234.85298 68420.862060 60247.924933

1000 rows × 3 columns

代码
文本

1.3.2 最大深度为5

代码
文本
[17]
dtr_5 = DecisionTreeRegressor(max_depth=5, random_state=0)
dtr_5.fit(Xtrain, Ytrain)
Ypred = dtr_5.predict(Xtest)

# 绘制决策树
#plt.figure(figsize=(20, 10))
#plot_tree(dtr_5, filled=True, feature_names=X.columns, rounded=True)
#plt.show()

# 绘制最大深度为5时, 回归树的拟合效果
fig, ax = plt.subplots(ncols=2, nrows=1, sharey=True, figsize=(10,5))
ax[0].set_xlabel('Velocity')
ax[0].set_ylabel('Capacity')
ax[0].scatter(Xtest, Ytest, s=10, label='Actual')
ax[0].scatter(Xtest, Ypred, c='red', label="Predicted - max_depth = 5")

# 将预测结果降序排序,以便plot
df_results = pd.DataFrame(data={'Xtest': Xtest.ravel(),
'Ytest': Ytest,
'Ypred': Ypred})
df_results.sort_values('Ytest', inplace=True)

ax[1].scatter(df_results['Xtest'], df_results['Ytest'], s=10, label='Actual')
ax[1].plot(df_results['Xtest'], df_results['Ypred'], c='red', label="max_depth = 5")

ax[0].legend() # 显示图例
ax[1].legend()
<matplotlib.legend.Legend at 0x7ff3acae0f40>
代码
文本

1.3.3 最大深度为10

代码
文本
[15]
dtr_10 = DecisionTreeRegressor(max_depth=10, random_state=0)
dtr_10.fit(Xtrain, Ytrain)
Ypred = dtr_10.predict(Xtest)

# 绘制最大深度为2时, 回归树的拟合效果
fig, ax = plt.subplots(ncols=2, nrows=1, sharey=True, figsize=(10,5))
ax[0].set_xlabel('Velocity')
ax[0].set_ylabel('Capacity')
ax[0].scatter(Xtest, Ytest, s=10, label='Actual')
ax[0].scatter(Xtest, Ypred, c='deeppink', label="Predicted - max_depth = 5")

# 将预测结果降序排序,以便plot
df_results = pd.DataFrame(data={'Xtest': Xtest.ravel(),
'Ytest': Ytest,
'Ypred': Ypred})
df_results.sort_values('Ytest', inplace=True)


ax[1].scatter(df_results['Xtest'], df_results['Ytest'], s=10, label='Actual')
ax[1].plot(df_results['Xtest'], df_results['Ypred'], c='deeppink', label="max_depth = 10")
[<matplotlib.lines.Line2D at 0x7ff3aed0cbe0>]
代码
文本

可以看到,当设置剪枝参数 max_depth=2 时,学习程度不足,而当设置剪枝参数 max_depth=10 时,模型学习到了许多噪音,出现了过拟合。而当剪枝参数 max_depth=5 时,模型学习的比较合适。

到目前为止,我们就得到了一个模型效果还行的决策树模型。

代码
文本

test

代码
文本
[10]
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import r2_score

# 加载数据
data = pd.read_csv('/bohr/decision-tree-data-eavt/v7/PCT_Curve.csv')

# 数据预处理,移除无关列
data = data.drop(columns=['Unnamed: 0'])

# 增加特征(平方、对数和交互项)
data['Pm_squared'] = data['Vacuometer1(Pm(Pa))'] ** 2
data['Pg_squared'] = data['Vacuometer1(Pg(Pa))'] ** 2
data['log_Velocity'] = np.log1p(data['Velocity'])
data['Pm_Pg_interaction'] = data['Vacuometer1(Pm(Pa))'] * data['Vacuometer1(Pg(Pa))']

# 划分训练集和测试集
X = data.drop(columns=['Capacity'])
y = data['Capacity']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 在训练集中加入噪声
np.random.seed(42)
X_train_noisy = X_train.copy()
X_train_noisy['Vacuometer1(Pm(Pa))'] += np.random.normal(0, 0.01, size=X_train_noisy.shape[0])
X_train_noisy['Vacuometer1(Pg(Pa))'] += np.random.normal(0, 0.0001, size=X_train_noisy.shape[0])

# 使用回归树进行训练和剪枝
tree = DecisionTreeRegressor(random_state=42)
tree.fit(X_train_noisy, y_train)

# 评估训练和测试集的R^2分数
train_score = r2_score(y_train, tree.predict(X_train_noisy))
test_score = r2_score(y_test, tree.predict(X_test))
print(f"未剪枝的训练集准确度: {train_score:.4f}, 测试集准确度: {test_score:.4f}")

# 使用交叉验证和预剪枝参数控制过拟合
tree_pruned = DecisionTreeRegressor(max_depth=5, min_samples_leaf=10, random_state=42)
tree_pruned.fit(X_train_noisy, y_train)

train_score_pruned = r2_score(y_train, tree_pruned.predict(X_train_noisy))
test_score_pruned = r2_score(y_test, tree_pruned.predict(X_test))
print(f"剪枝后的训练集准确度: {train_score_pruned:.4f}, 测试集准确度: {test_score_pruned:.4f}")

# 使用交叉验证查看剪枝效果
cv_scores = cross_val_score(tree_pruned, X_train_noisy, y_train, cv=5, scoring='r2')
print(f"剪枝后的交叉验证得分: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")

未剪枝的训练集准确度: 1.0000, 测试集准确度: 0.9993
剪枝后的训练集准确度: 0.9986, 测试集准确度: 0.9986
剪枝后的交叉验证得分: 0.9985 ± 0.0000
代码
文本

代码
文本

随堂作业

代码
文本

吸氢金属通常指的是能够在其金属结构中吸收并储存氢气的材料,这类材料在能源存储、传感器和催化剂等领域具有重要应用。请使用以下数据集 hydrogen_metal_data_300.csv,用决策树算法判断材料是否为吸氢金属:

数据集介绍

数据集中提供了四个特征,用以判断一个材料是否可作为有效的吸氢金属:

  1. 吸氢容量大小:高/低(一个材料吸收氢气的能力,高吸氢容量表明材料能够储存更多的氢气)
  2. 吸放氢平衡压:高/低(吸氢和放氢时所需的压力,低平衡压有利于在较低的外界压力下吸放氢)
  3. 使用温度:高/低(材料正常工作的温度范围,低温度使用对设备要求较低,更易实现)
  4. 循环寿命:长/短(材料能够进行吸放氢反应的次数,长寿命表示材料可重复使用多次)

特征数据介绍

为了简化问题,我们可以将吸氢容量大小吸放氢平衡压使用温度循环寿命的特征分别编码为 ,其中 代表低/短, 代表高/长。接下来,我们会生成这样的数据集,并用决策树算法(如 )来训练模型,最后绘制出决策树。

数据集中包含 组数据。每一行代表一个材料,列包括了我们关心的四个特征:吸氢容量大小吸放氢平衡压使用温度循环寿命,以及这些特征组合下的材料是否为吸氢金属( 表示是吸氢金属, 表示不是)。

代码
文本

作业要求

  1. 读取数据集并预览

  2. 划分数据集为测试集和训练集

    提示:获取列标签并转换为列表可使用:df.columns.tolist()

  3. 使用sklearn中的决策树算法DecisionTreeClassifier训练集构建决策树模型

  4. 进行剪枝操作 (最大深度设置为 )

  5. 使用训练的决策树模型对测试集数据进行模型性能评估

    可选: 准确率(accuracy_score), 精确度(precision_score), 召回率(recall_score), F1分数(f1_score), 混淆矩阵(confusion_matrix)

  6. 画出特征重要性条形图

代码
文本
Machine Learning
随机森林
Machine Learning随机森林
点个赞吧
{/**/}