休闲游戏

贝叶斯优化在随机森林中的应用:从参数调优到性能提升

背景

在模型训练中,超参数如树的数量、最大深度、最小样本分割比例等对随机森林的表现有很大影响。传统的网格搜索法(Grid Search)和随机搜索法(Random Search)虽然简单,但效率相对较低,贝叶斯优化则是基于概率模型,逐步优化目标函数,更适用于计算成本较高的情况

贝叶斯优化简介

贝叶斯优化通过构建目标函数的概率分布,逐步选择最优的参数组合,接下来将用hyperopt库来实现这一优化过程,它利用了树结构的贝叶斯估计(TPE)算法来选择参数空间,示范如何在回归和分类问题中运用贝叶斯优化来提升随机森林模型的表现

代码实现

回归模型

利用贝叶斯优化提升随机森林(回归)模型性能

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import warnings

warnings.filterwarnings("ignore")

plt.rcParams['font.family'] = 'Times New Roman'

plt.rcParams['axes.unicode_minus'] = False

df = pd.read_excel('2024-10-31-公众号Python机器学习AI—regression.xlsx')

from sklearn.model_selection import train_test_split, KFold

X = df.drop(['待预测变量Y'],axis=1)

y = df['待预测变量Y']

# 划分训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

from hyperopt import fmin, tpe, hp

from sklearn.ensemble import RandomForestRegressor

from sklearn.metrics import mean_squared_error

# 定义超参数搜索空间

parameter_space_rf = {

'n_estimators': hp.choice('n_estimators', [50, 100, 200, 300]), # 决策树数量

'max_depth': hp.choice('max_depth', [5, 10, 20, None]), # 树的最大深度

'min_samples_split': hp.uniform('min_samples_split', 0.01, 0.5), # 分裂所需最小样本比例

'min_samples_leaf': hp.uniform('min_samples_leaf', 0.01, 0.5) # 叶节点最小样本比例

}

# 定义目标函数

def objective(params):

# 使用超参数创建随机森林回归模型

model = RandomForestRegressor(

n_estimators=params['n_estimators'],

max_depth=params['max_depth'],

min_samples_split=params['min_samples_split'],

min_samples_leaf=params['min_samples_leaf'],

random_state=42

)

# 在训练集上拟合模型

model.fit(X_train, y_train)

# 在测试集上预测

y_pred = model.predict(X_test)

# 计算均方误差(MSE)

mse = mean_squared_error(y_test, y_pred)

# 返回MSE,Hyperopt会最小化该目标值

return mse

# 运行超参数优化

best_params = fmin(

fn=objective, # 优化的目标函数

space=parameter_space_rf, # 搜索空间

algo=tpe.suggest, # 贝叶斯优化算法

max_evals=100 # 最大评估次数

)

# 显示最优超参数组合

print("Best hyperparameters:", best_params)

# 使用最佳超参数组合重新训练模型

best_model_regression = RandomForestRegressor(

n_estimators=[50, 100, 200, 300][best_params['n_estimators']],

max_depth=[5, 10, 20, None][best_params['max_depth']],

min_samples_split=best_params['min_samples_split'],

min_samples_leaf=best_params['min_samples_leaf'],

random_state=42

)

# 在训练集上训练模型

best_model_regression.fit(X_train, y_train)

利用贝叶斯优化(通过hyperopt库)来自动调整随机森林回归模型的超参数,以最小化测试集上的均方误差(MSE)。首先,定义了一个超参数空间,包括决策树数量、最大深度、最小分裂样本比例和最小叶子样本比例,接着,定义目标函数以构建并评估随机森林模型,将模型在测试集上的MSE作为优化目标,通过fmin函数使用贝叶斯优化搜索最佳参数组合,并用该组合重新训练最终的随机森林模型,从而获得更优的预测性能

评估模型性能:训练集与测试集的回归指标对比

from sklearn import metrics

# 预测

y_pred_train = best_model_regression.predict(X_train)

y_pred_test = best_model_regression.predict(X_test)

y_pred_train_list = y_pred_train.tolist()

y_pred_test_list = y_pred_test.tolist()

# 计算训练集的指标

mse_train = metrics.mean_squared_error(y_train, y_pred_train_list)

rmse_train = np.sqrt(mse_train)

mae_train = metrics.mean_absolute_error(y_train, y_pred_train_list)

r2_train = metrics.r2_score(y_train, y_pred_train_list)

# 计算测试集的指标

mse_test = metrics.mean_squared_error(y_test, y_pred_test_list)

rmse_test = np.sqrt(mse_test)

mae_test = metrics.mean_absolute_error(y_test, y_pred_test_list)

r2_test = metrics.r2_score(y_test, y_pred_test_list)

print("训练集评价指标:")

print("均方误差 (MSE):", mse_train)

print("均方根误差 (RMSE):", rmse_train)

print("平均绝对误差 (MAE):", mae_train)

print("拟合优度 (R-squared):", r2_train)

print("\n测试集评价指标:")

print("均方误差 (MSE):", mse_test)

print("均方根误差 (RMSE):", rmse_test)

print("平均绝对误差 (MAE):", mae_test)

print("拟合优度 (R-squared):", r2_test)

计算并输出随机森林回归模型在训练集和测试集上的性能指标,包括均方误差(MSE)、均方根误差(RMSE)、平均绝对误差(MAE)和拟合优度(R-squared),以评估模型在训练集和测试集上的预测准确度和拟合效果,从而帮助判断模型的泛化能力

模型预测可视化

利用散点图和回归线,直观展示随机森林模型在训练集和测试集上的预测表现,图中每个点代表真实值和预测值的配对关系,越接近对角线(即x=y线)的点表示预测越准确,通过不同颜色区分训练集和测试集,边缘的柱状图则显示了数据分布情况,此外,右下角标注了训练集和测试集的R^2(拟合优度),左上角注明模型名称,帮助更全面地评估模型的预测效果与泛化能力,为模型的有效性提供了直观的支持,代码获取:如果您希望获取本文展示的改进版代码,请添加作者微信联系获取

分类

模型

利用贝叶斯优化提升随机森林(分类)模型性能

import pandas as pd

import numpy as np

from hyperopt import fmin, tpe, hp

from sklearn.model_selection import train_test_split

from sklearn.ensemble import RandomForestClassifier

from sklearn.metrics import accuracy_score

# 读取数据

df = pd.read_excel('2024-10-31-公众号Python机器学习AI—class.xlsx')

# 划分特征和目标变量

X = df.drop(['目标'], axis=1)

y = df['目标']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,

random_state=42, stratify=df['目标'])

# 定义超参数空间

parameter_space_rf = {

'n_estimators': hp.choice('n_estimators', [50, 100, 200, 300]), # 决策树数量

'max_depth': hp.choice('max_depth', [5, 10, 20, None]), # 最大深度

'min_samples_split': hp.uniform('min_samples_split', 0.01, 0.5), # 分裂所需最小样本比例

'min_samples_leaf': hp.uniform('min_samples_leaf', 0.01, 0.5) # 叶节点最小样本比例

}

# 定义目标函数

def objective(params):

# 初始化模型并传入超参数

model = RandomForestClassifier(

n_estimators=params['n_estimators'],

max_depth=params['max_depth'],

min_samples_split=params['min_samples_split'],

min_samples_leaf=params['min_samples_leaf'],

random_state=42

)

# 模型拟合

model.fit(X_train, y_train)

# 测试集上的预测

y_pred = model.predict(X_test)

# 计算准确率

accuracy = accuracy_score(y_test, y_pred)

# 返回负的准确率(因为Hyperopt默认最小化目标函数)

return -accuracy

# 运行贝叶斯优化

best_params = fmin(

fn=objective, # 目标函数

space=parameter_space_rf, # 搜索空间

algo=tpe.suggest, # 贝叶斯优化算法

max_evals=100 # 最大评估次数

)

# 显示最优参数

print("Best hyperparameters:", best_params)

# 使用最佳参数创建最终模型

best_model_class = RandomForestClassifier(

n_estimators=[50, 100, 200, 300][best_params['n_estimators']],

max_depth=[5, 10, 20, None][best_params['max_depth']],

min_samples_split=best_params['min_samples_split'],

min_samples_leaf=best_params['min_samples_leaf'],

random_state=42

)

# 在训练集上拟合模型

best_model_class.fit(X_train, y_train)

通过贝叶斯优化(使用hyperopt库)为随机森林分类模型选择最佳超参数组合,以最大化在测试集上的准确率,首先将数据集划分为训练集和测试集,并定义随机森林的超参数空间,包括决策树数量、最大深度、最小分裂样本比例和最小叶节点样本比例,然后使用目标函数创建和评估模型,以测试集准确率的负值作为优化目标(因为hyperopt最小化目标值),通过100次评估后,代码选出最佳超参数组合,并用其重新训练随机森林模型,从而获得更优的分类性能

模型性能评估:多维度分类指标分析

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, classification_report

# 计算各项指标

accuracy = accuracy_score(y_test, y_pred)

precision = precision_score(y_test, y_pred)

recall = recall_score(y_test, y_pred)

f1 = f1_score(y_test, y_pred)

# 如果是二分类且有预测概率值

try:

y_pred_proba = best_model_class.predict_proba(X_test)[:, 1] # 仅适用于二分类

auc = roc_auc_score(y_test, y_pred_proba)

except AttributeError:

auc = None # 对于多分类或无 predict_proba 时不适用

metrics_df = pd.DataFrame({

'Metric': [ 'AUC', 'Precision', 'Recall', 'F1 Score','Accuracy'],

'Value': [auc, precision, recall, f1, accuracy]

})

metrics_df

计算随机森林分类模型在测试集上的多个评估指标,包括准确率(accuracy)、精确率(precision)、召回率(recall)、F1分数(F1 Score)和AUC(仅适用于二分类),这些指标各自反映模型不同方面的性能:准确率表示整体预测的准确程度,精确率关注正类预测的准确性,召回率衡量模型找到所有正类的能力,F1分数则平衡了精确率和召回率的权重。AUC则进一步评估了模型在不同阈值下区分正负类的能力。因此,使用多个指标能够更全面地了解模型的表现,从而帮助我们避免因单一指标误导而造成的模型优化偏差

模型预测可视化

绘制模型各评估指标的雷达图,将不同性能指标如准确率、精确率、召回率等在极坐标上可视化,方便直观对比模型在多个维度上的表现,从而帮助识别模型的优势和改进方向,代码获取:如果您希望获取本文展示的改进版代码,请添加作者微信联系获取

🎁

赠书活动来啦!

🎁

支持知识分享,畅享学习乐趣!特别感谢 清华出版社 对本次赠书活动的鼎力支持!即日起,只需

点赞、在看、转发

此文章,作者将从后台随机抽取一位幸运儿,免费包邮赠送清华出版社提供的《细说PyTorch:深度学习理论、算法、模型与编程实现》这本精彩书籍📚!

💡 赶快参与,一键三连,说不定你就是那位幸运读者哦!

往期推荐

SCI图表复现:整合数据分布与相关系数的高级可视化策略

SCI图表:基于相关性和标准差的多模型评价——泰勒图解析

SCI图表复现:利用小提琴图折线图综合展示训练集、验证集、测试集模型性能对比

复现SCI文章 SHAP 依赖图可视化以增强机器学习模型的可解释性

SCI图表复现:优化SHAP特征贡献图展示更多模型细节

复现 Nature 图表——基于PCA的高维数据降维与可视化实践及其扩展

复现 Nature 图表可视化——基于模型残差分析与显著性检验的模型解释

SCI图表复现:特征相关性气泡热图展示

期刊文章配图:斯皮尔曼相关系数热图反应非线性变量相关性

微信号|deep_ML

欢迎添加作者微信进入Python、ChatGPT群

进群请备注Python或AI进入相关群

无需科学上网、同步官网所有功能、使用无限制

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考