顶刊复现:基于TOPSIS赋权的多模型融合方法及其优化应用提升模型预测性能

机器学习向量数据库大模型

picture.image

✨ 欢迎关注 ✨

本节介绍:基于TOPSIS赋权的多模型融合方法及其优化应用,作者根据个人对机器学习的理解进行代码实现与图表输出,仅供参考。 完整 数据和代码获取,需要的朋友可关注公众文末提供的店铺获取方式- Python项目代码文档合集 。 获取 前请咨询,避免不必要的问题。

✨ 文献信息 ✨

picture.image

文献中“TCF模型是一个基于TOPSIS赋权的多模型融合集成模型,对于子模型使用训练集进行模型的参数优化,在训练之后,不同的子模型被融合在一起。模型融合是通过组合多个子模型的预测结果来提高总体预测精度的技术,融合算法考虑了多个子模型,如决策树、随机森林、XGBoost、LightGBM、支持向量机、BernoulliNB和梯度提升决策树,文中给出的方程式说明了每个子模型的贡献比例。不同子模型的权重反映了它们对最终预测的影响程度(通过TOPSIS方法得到),在这里,XGBoost的贡献为0.155,支持向量机贡献为0.089,梯度提升决策树贡献为0.158等

通过这种方式,最终的TCF模型能够融合不同模型的优势,减少单个模型可能带来的偏差,从而提高整体的预测准确性和鲁棒性

picture.image

图3展示了TCF模型与其子模型在内部验证集上的ROC曲线对比,结果表明TCF模型在曲线下面积(AUC)上优于单一的子模型,体现了TCF模型性能的优势,图2特征选择可以参考往期文章——digital medicine复现:缺失值过滤、方差过滤、缺失值插补、相关系数与逐步特征选择

picture.image

这个表格展示了基于TOPSIS方法评估TCF模型的分类性能,列出了七个子模型的计算结果,并根据正理想解(PIS)、负理想解(NIS)和综合评分指数(αi)进行排名。接下来,将在模拟数据集上应用基于TOPSIS赋权的多模型融合方法,并进行优化应用

✨ 基础代码 ✨

  
import pandas as pd  
import numpy as np  
import matplotlib.pyplot as plt  
plt.rcParams['font.family'] = 'Times New Roman'  
plt.rcParams['axes.unicode_minus'] = False  
import warnings  
# 忽略所有警告  
warnings.filterwarnings("ignore")  
  
path = r"2025-8-9公众号Python机器学习AI.xlsx"  
df = pd.read_excel(path)  
from sklearn.model_selection import train_test_split  
  
# 划分特征和目标变量  
X = df.drop(['Electrical_cardioversion'], axis=1)    
y = df['Electrical_cardioversion']    
# 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(  
    X,    
    y,   
    test_size=0.3,   
    random_state=250807,   
    stratify=df['Electrical_cardioversion']   
)  
from imblearn.over_sampling import SMOTE  #   
  
# 导入SMOTE算法用于数据过采样  
smote = SMOTE(sampling_strategy=1, k_neighbors=20)   
# sampling_strategy=1 表示将少数类样本的数量增加到与多数类相同,即使样本平衡  
# k_neighbors=20 表示用于生成合成样本时使用20个最近邻点,SMOTE算法将基于这些邻居生成新的样本  
  
# 使用SMOTE对训练集数据进行过采样,生成新的平衡数据集  
X_SMOTE_train, y_SMOTE_train = smote.fit_resample(X_train, y_train)

使用SMOTE算法对训练集进行过采样,以平衡类别不均的数据集。特别需要注意的是,在进行采样之前,必须先划分训练集和测试集,以避免数据泄露。如果整体数据先进行采样再分割,通常会导致模型在训练集和测试集上的性能都较好,但这会产生数据泄露问题,从而导致模型评估不准确

  
from sklearn.tree import DecisionTreeClassifier    
from sklearn.model_selection import GridSearchCV  
  
# 初始化决策树模型  
dt_model = DecisionTreeClassifier(random_state=42)  
  
# 设置网格搜索的参数范围  
param_grid = {  
    'criterion': ['gini', 'entropy'],  # 划分标准  
    'max_depth': [None, 10, 20, 30, 40],  # 树的最大深度  
    'min_samples_split': [2, 5, 10],  # 内部节点再划分所需的最小样本数  
    'min_samples_leaf': [1, 2, 4],  # 叶子节点的最小样本数  
    'max_features': [None, 'sqrt', 'log2']  # 每次划分时考虑的最大特征数  
}  
  
# 创建GridSearchCV对象,进行K折交叉验证,选择最优参数  
grid_search = GridSearchCV(estimator=dt_model, param_grid=param_grid, cv=5, n_jobs=-1, verbose=1)  
  
# 训练网格搜索模型  
grid_search.fit(X_SMOTE_train, y_SMOTE_train)  
  
# 输出最优参数  
print(f"最优参数:{grid_search.best_params_}")  
  
# 使用最优参数建立最终决策树模型  
best_dt_model = grid_search.best_estimator_

使用网格搜索(GridSearchCV)对决策树模型进行超参数优化,选择最优参数并训练最终的决策树模型,这个决策树模型将作为第一个子模型

  
Fitting 5 folds for each of 270 candidates, totalling 1350 fits  
最优参数:{'criterion': 'entropy', 'max_depth': None, 'max_features': None, 'min_samples_leaf': 1, 'min_samples_split': 5}

结果表明,经过网格搜索优化后,决策树模型的最优参数为:选择使用信息增益(entropy)作为划分标准,树的最大深度没有限制(None),每次划分时考虑所有特征(None),叶子节点的最小样本数为1,内部节点再划分所需的最小样本数为5,要注意的是,网格搜索返回的是在设定的网格范围内的最优参数。如果当前最优参数超出了网格搜索的参数范围,那么返回的最优参数就不是实际的最优参数,而只是网格范围内的最优结果。因此,网格搜索的结果是局限于给定的参数空间的

  
# est_dt_model是通过网格搜索训练后的决策树模型  
dt_train = evaluate_model_performance(best_dt_model, X_SMOTE_train, y_SMOTE_train)  
print("\n")  
dt_test = evaluate_model_performance(best_dt_model, X_test.reset_index(drop=True), y_test.reset_index(drop=True))

evaluate_model_performance是一个自定义函数,用于通过Bootstrap采样来评估分类模型的性能,并计算多个指标(如AUC、F1、准确率、精确率、召回率和特异度)的中位数及其95%置信区间

  
AUC: Median = 0.999898538961039, 95% CI = [0.9992940986449091, 1.0]  
F1: Median = 0.9919354838709677, 95% CI = [0.9787234042553191, 1.0]  
ACC: Median = 0.9918032786885246, 95% CI = [0.9795081967213115, 1.0]  
PRE: Median = 0.992, 95% CI = [0.9722157320872274, 1.0]  
SEN: Median = 0.9919354838709677, 95% CI = [0.9741379310344828, 1.0]  
SPE: Median = 0.992, 95% CI = [0.9739015005771451, 1.0]  
  
AUC: Median = 0.6617769897557131, 95% CI = [0.5350654791459781, 0.7760318982665529]  
F1: Median = 0.5333333333333333, 95% CI = [0.35286764705882356, 0.68099396633852]  
ACC: Median = 0.6883116883116883, 95% CI = [0.5844155844155844, 0.7792207792207793]  
PRE: Median = 0.5185185185185185, 95% CI = [0.3333333333333333, 0.7]  
SEN: Median = 0.5555555555555556, 95% CI = [0.36, 0.7407706093189963]  
SPE: Median = 0.7547169811320755, 95% CI = [0.6225754716981132, 0.8571428571428571]

这是第一个子模型DT在训练集和测试集上的评价指标,结果表明,决策树(DT)模型在训练集上的性能非常好,但在测试集上的表现较差,存在过拟合的情况。训练集的指标非常接近理想值,而测试集的各项指标则显示出模型在泛化能力上的不足。这也是典型的过拟合问题,决策树模型在训练数据上记忆得太多,导致无法很好地适应新的数据

接下来的步骤和ET模型一样,就是对剩余的5个子模型(RandomForest、XGBoost、LightGBM、SVM、BernoulliNB和GradientBoosting)进行类似的网格调参、模型训练、以及性能评估,确保每个模型在训练集和测试集上都经过同样的评价流程

  
from sklearn.metrics import roc_auc_score  
# 模型集合  
models = {  
    'DecisionTree': best_dt_model,  
    'RandomForest': best_rf_model,  
    'XGBoost': best_xgb_model,  
    'LightGBM': best_lgbm_model,  
    'SVM': best_svm_model,  
    'BernoulliNB': best_bnb_model,  
    'GradientBoosting': best_gbdt_model  
}  
  
# 存储结果  
metrics = ['AUC', 'F1', 'ACC', 'PRE', 'SEN', 'SPE']  
results = {metric: [] for metric in metrics}  
  
# 计算每个模型的评价指标  
for model_name, model in models.items():  
    y_pred = model.predict(X_test)  
    y_prob = model.predict_proba(X_test)[:, 1]  # 获取预测的概率值用于AUC计算  
  
    # 计算各个指标  
    auc = roc_auc_score(y_test, y_prob)  
    f1 = f1_score(y_test, y_pred)  
    acc = accuracy_score(y_test, y_pred)  
    precision = precision_score(y_test, y_pred)  
    recall = recall_score(y_test, y_pred)  
  
    # 计算敏感性(Recall)和特异性(Specificity)  
    tn, fp, fn, tp = confusion_matrix(y_test, y_pred).ravel()  
    sensitivity = recall  # 同为召回率  
    specificity = tn / (tn + fp)  
  
    # 将结果添加到对应的指标列表  
    results['AUC'].append(auc)  
    results['F1'].append(f1)  
    results['ACC'].append(acc)  
    results['PRE'].append(precision)  
    results['SEN'].append(sensitivity)  
    results['SPE'].append(specificity)  
  
results_df = pd.DataFrame(results, index=models.keys())  
results_df

picture.image

在所有子模型构建完成后,计算每个子模型在测试集上的AUC、F1、准确率、精确率、召回率和特异度等评价指标,并将结果整合为一个DataFrame,作为模型权重选择的依据

picture.image

通过TOPSIS方法对子模型的评价指标矩阵计算得到的各个子模型的权重。通过这种方法,模型的各项指标(如 AUC、F1、ACC、PRE、SEN、SPE)被综合评估,并通过正理想解、负理想解、综合得分等步骤,得出了每个子模型的最终排名和权重。排名越高的模型,其在综合评价中的表现越好,也就会在融合模型里面赋予更高的权重

  
ensemble\_test = evaluate\_model\_performance(ensemble\_model, X\_test.reset\_index(drop=True), y\_test.reset\_index(drop=True))

通过将6个子模型按各自的权重进行融合,得到一个新的融合模型ensemble_model,并使用evaluate_model_performance函数计算该融合模型在测试集上的表现,完整代码通过下方店铺获取

  
AUC: Median = 0.8888888888888888, 95% CI = [0.8104774052478133, 0.9506908135154888]  
F1: Median = 0.723404255319149, 95% CI = [0.5581395348837209, 0.861551724137931]  
ACC: Median = 0.8311688311688312, 95% CI = [0.7532467532467533, 0.9090909090909091]  
PRE: Median = 0.782608695652174, 95% CI = [0.5881127450980392, 0.9411764705882353]  
SEN: Median = 0.6818181818181818, 95% CI = [0.5, 0.8518518518518519]  
SPE: Median = 0.9074074074074074, 95% CI = [0.8181354359925789, 0.9795918367346939]

结果展示了融合模型在测试集上的各项性能中位数指标:AUC为0.889,F1为0.723,准确率为0.831,精确率为0.783,召回率为0.682,特异度为0.907,所有指标的95%置信区间均在较高范围内,表明该融合模型在测试集上的表现较为优秀

  
# 对于 DecisionTree 模型  
fpr_dt, tpr_dt, _ = roc_curve(y_test, best_dt_model.predict_proba(X_test)[:, 1])  
auc_dt = roc_auc_score(y_test, best_dt_model.predict_proba(X_test)[:, 1])  
  
# 对于 RandomForest 模型  
fpr_rf, tpr_rf, _ = roc_curve(y_test, best_rf_model.predict_proba(X_test)[:, 1])  
auc_rf = roc_auc_score(y_test, best_rf_model.predict_proba(X_test)[:, 1])  
  
# 对于 XGBoost 模型  
fpr_xgb, tpr_xgb, _ = roc_curve(y_test, best_xgb_model.predict_proba(X_test)[:, 1])  
auc_xgb = roc_auc_score(y_test, best_xgb_model.predict_proba(X_test)[:, 1])  
  
# 对于 LightGBM 模型  
fpr_lgbm, tpr_lgbm, _ = roc_curve(y_test, best_lgbm_model.predict_proba(X_test)[:, 1])  
auc_lgbm = roc_auc_score(y_test, best_lgbm_model.predict_proba(X_test)[:, 1])  
  
# 对于 SVM 模型  
fpr_svm, tpr_svm, _ = roc_curve(y_test, best_svm_model.predict_proba(X_test)[:, 1])  
auc_svm = roc_auc_score(y_test, best_svm_model.predict_proba(X_test)[:, 1])  
  
# 对于 BernoulliNB 模型  
fpr_bnb, tpr_bnb, _ = roc_curve(y_test, best_bnb_model.predict_proba(X_test)[:, 1])  
auc_bnb = roc_auc_score(y_test, best_bnb_model.predict_proba(X_test)[:, 1])  
  
# 对于 GradientBoosting 模型  
fpr_gbdt, tpr_gbdt, _ = roc_curve(y_test, best_gbdt_model.predict_proba(X_test)[:, 1])  
auc_gbdt = roc_auc_score(y_test, best_gbdt_model.predict_proba(X_test)[:, 1])  
  
# 对于集成模型  
fpr_ensemble, tpr_ensemble, _ = roc_curve(y_test, ensemble_model.predict_proba(X_test)[:, 1])  
auc_ensemble = roc_auc_score(y_test, ensemble_model.predict_proba(X_test)[:, 1])  
  
# 绘制 ROC 曲线  
plt.figure(figsize=(6, 5))  
  
# 绘制每个基础模型的 ROC 曲线(灰色,虚线)  
plt.plot(fpr_dt, tpr_dt, color='gray', linestyle='--', alpha=0.6, label=f'DT (AUC = {auc_dt:.4f})')  
plt.plot(fpr_rf, tpr_rf, color='gray', linestyle='--', alpha=0.6, label=f'RF (AUC = {auc_rf:.4f})')  
plt.plot(fpr_xgb, tpr_xgb, color='gray', linestyle='--', alpha=0.6, label=f'XGB (AUC = {auc_xgb:.4f})')  
plt.plot(fpr_lgbm, tpr_lgbm, color='gray', linestyle='--', alpha=0.6, label=f'LGBM (AUC = {auc_lgbm:.4f})')  
plt.plot(fpr_svm, tpr_svm, color='gray', linestyle='--', alpha=0.6, label=f'SVM (AUC = {auc_svm:.4f})')  
plt.plot(fpr_bnb, tpr_bnb, color='gray', linestyle='--', alpha=0.6, label=f'NB (AUC = {auc_bnb:.4f})')  
plt.plot(fpr_gbdt, tpr_gbdt, color='gray', linestyle='--', alpha=0.6, label=f'GBDT (AUC = {auc_gbdt:.4f})')  
  
# 绘制集成模型的 ROC 曲线(橙色)  
plt.plot(fpr_ensemble, tpr_ensemble, color='orange', label=f'Ensemble (AUC = {auc_ensemble:.4f})')  
  
# 绘制对角线(随机猜测的模型)  
plt.plot([0, 1], [0, 1], 'r--', linewidth=1.5, alpha=0.8)  
  
# 设置图像标签  
plt.xlabel("False Positive Rate (1-Specificity)", fontsize=18)  
plt.ylabel("True Positive Rate (Sensitivity)", fontsize=18)  
plt.xticks(fontsize=16)  
plt.yticks(fontsize=16)  
plt.legend(loc="lower right", fontsize=12, frameon=False)  
plt.gca().spines['top'].set_visible(False)  
plt.gca().spines['right'].set_visible(False)  
plt.gca().spines['left'].set_linewidth(1.5)  
plt.gca().spines['bottom'].set_linewidth(1.5)  
plt.grid(False)  
# 调整布局并保存图像  
plt.tight_layout()  
plt.savefig("ROC-Ensemble.pdf", format='pdf', bbox_inches='tight',dpi=1200)  
plt.show()

picture.image

最后绘制了所有子模型和融合模型在测试集上的ROC曲线,并计算每个模型的AUC值(曲线下面积)。通过可视化这些曲线,可以清晰地看到,融合模型(橙色曲线)相较于各个单独的子模型(灰色虚线)表现更好,具有更高的AUC值,证明了融合模型的优越性。展示了融合模型在综合各个子模型的优势后,能够更准确地进行分类

融合模型到这里构建完成了,通过将多个子模型的优势融合在一起,最终提升了整体的预测性能。作者将在下一期继续复现并讲解融合模型的模型解释部分,以帮助深入理解模型的决策过程和特征的重要性

当然,公众号中还有更多机器学习期刊实战技巧,您可以通过历史文章进行检索和阅读,关注公众号,点击“发信息”>“历史文章”即可搜索公众号所有文章信息

picture.image

✨ 该文章案例 ✨

picture.image

在上传至交流群的文件中,像往期文章一样,将对案例进行逐步分析,确保读者能够达到最佳的学习效果。内容都经过详细解读,帮助读者深入理解模型的实现过程和数据分析步骤,从而最大化学习成果。

同时,结合提供的免费AI聚合网站进行学习,能够让读者在理论与实践之间实现融会贯通,更加全面地掌握核心概念。

✨ 介绍 ✨

本节介绍到此结束,有需要学习数据分析和Python机器学习相关的朋友欢迎到淘宝店铺:Python机器学习AI,下方提供淘宝店铺二维码获取作者的公众号合集。截至目前为止,合集已包含近300多篇文章,购买合集的同时,还将提供免费稳定的AI大模型使用。

更新的内容包含数据、代码、注释和参考资料。 作者仅分享案例项目,不提供额外的答疑服务。项目中将提供详细的代码注释和丰富的解读,帮助您理解每个步骤 。 获取 前请咨询,避免不必要的问题。

✨ 群友反馈 ✨

picture.image

✨ 淘宝店铺 ✨

picture.image

请大家打开淘宝扫描上方的二维码,进入店铺,获取更多Python机器学习和AI相关的内容 ,希望能为您的学习之路提供帮助!

✨ 免费赠书 ✨

picture.image

picture.image

支持知识分享,畅享学习乐趣!特别感谢清华大学出版社 对本次赠书活动的鼎力支持!即日起,只需点赞、推荐、转发 此文章,作者将从后台随机抽取一位幸运儿,免费包邮赠送清华出版社提供的《ABB工业机器人离线编程与仿真》这本精彩书籍📚!

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

往期推荐

期刊复现:连续数据与分类数据共存的SHAP可视化散点图与箱形图组合形式

期刊复现:多分类任务如何拆分为二分类任务并进行堆叠预测提高模型预测性能

期刊配图:SHAP模型解释多种特征重要性柱状图可视化解析

期刊配图:SHAP值分析模型可解释性在柱状图与蜂窝图中的进阶组合展示

期刊配图:通过堆叠Mean|SHAP|展示不同区间对模型贡献度的可视化分析

期刊复现:利用UMAP降维算法可视化深度学习随着训练次数的增加模型区分能力的变化

期刊配图:PCA、t-SNE与UMAP三种降维方法简化高维数据的展示应用对比

Science期刊复现:分类、回归与Shap分析多角度揭示同一数据集变量对目标的影响

多模型SHAP+PDP解读Stacking集成模型:从基学习器到元学习器的可解释性与模型调参实现

picture.image

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

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动 XR 技术的探索与实践
火山引擎开发者社区技术大讲堂第二期邀请到了火山引擎 XR 技术负责人和火山引擎创作 CV 技术负责人,为大家分享字节跳动积累的前沿视觉技术及内外部的应用实践,揭秘现代炫酷的视觉效果背后的技术实现。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论