融合机器学习算法:用VotingClassifier实现分类多模型的投票集成

news/2024/12/23 12:52:25/

图片

背景

VotingClassifier是一种集成学习方法,它将多个不同的机器学习模型组合起来,通过投票的方式对分类任务做出决策,从而提高整体模型的预测性能和鲁棒性

VotingClassifier的核心机制

VotingClassifier提供两种主要的投票策略硬投票和软投票

  • 硬投票:每个子模型对每个样本预测一个类别标签,最终分类结果取决于子模型中预测类别得票最多的那个类别,适合模型预测准确率较高且相差不大的场景

  • 软投票:子模型返回的是类别的概率分布(即预测某类别的概率),将每个模型预测的概率加权平均,最终选择概率最高的类别作为预测结果,适合具有概率输出能力的模型(如 XGBoost、LightGBM、CatBoost 等)

VotingClassifier的优劣势

  • 优势:性能提升集成多个模型的优点,能有效提升预测性能,尤其是当单个模型存在欠拟合或过拟合时、鲁棒性强如果某些子模型表现较差,不会严重影响整体结果(尤其是软投票)、灵活性支持组合多种不同类型的模型(如树模型、线性模型、神经网络等)

  • 劣势:对弱模型敏感如果所有模型都表现较差,投票集成的效果也会有限、依赖模型概率输出软投票要求模型返回概率分布,某些模型可能不支持、需要调试参数子模型的选择、超参数调整、权重设置等都需要耗费一定的时间

代码实现

数据读取

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings("ignore", message=".*does not have valid feature names.*")
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = Falsedf = pd.read_excel('2024-12-20公众号Python机器学习AI.xlsx')
# 划分特征和目标变量
X = df.drop(['class'], axis=1)
y = df['class']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=df['class'])

加载一个包含特征和目标变量的Excel数据集,将数据划分为训练集和测试集,准备用于机器学习模型的训练和测试,其中目标变量class表示分类标签,且为二分类数据(目标变量只有两个类别)

硬投票模型实现

from sklearn.ensemble import VotingClassifier, RandomForestClassifier, GradientBoostingClassifier, AdaBoostClassifier
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from catboost import CatBoostClassifier# 定义各个模型
rf_clf = RandomForestClassifier(random_state=42)
xgb_clf = XGBClassifier(use_label_encoder=False, eval_metric='logloss', random_state=42)
lgbm_clf = LGBMClassifier(random_state=42, verbose=-1)
gbm_clf = GradientBoostingClassifier(random_state=42)
adaboost_clf = AdaBoostClassifier(random_state=42, algorithm='SAMME')
catboost_clf = CatBoostClassifier(verbose=0, random_state=42)# 创建硬投票分类器
voting_hard = VotingClassifier(estimators=[('RandomForest', rf_clf),('XGBoost', xgb_clf),('LightGBM', lgbm_clf),('GradientBoosting', gbm_clf),('AdaBoost', adaboost_clf),('CatBoost', catboost_clf)],voting='hard'
)# 训练硬投票分类器
voting_hard.fit(X_train, y_train)

图片

定义多个机器学习分类模型(随机森林、XGBoost、LightGBM、梯度提升、AdaBoost 和 CatBoost),并将它们通过硬投票(Hard Voting)的方式组合成一个集成分类器(VotingClassifier),硬投票会根据各个模型的预测结果取多数票决定最终分类结果,最后,使用训练数据X_train和y_train对硬投票分类器进行训练,为后续分类任务做好准备

软投票模型实现

# 创建软投票分类器
voting_soft = VotingClassifier(estimators=[('RandomForest', rf_clf),('XGBoost', xgb_clf),('LightGBM', lgbm_clf),('GradientBoosting', gbm_clf),('AdaBoost', adaboost_clf),('CatBoost', catboost_clf)],voting='soft',  # 将硬投票 ('hard') 修改为软投票 ('soft')weights=[1, 1, 1, 1, 1, 1]  # 当 weights 没有被显式设置时默认权重相等
)
# 训练软投票分类器
voting_soft.fit(X_train, y_train)

图片

创建一个软投票分类器(Soft Voting),将多个机器学习模型(随机森林、XGBoost、LightGBM、梯度提升、AdaBoost和CatBoost)集成在一起。软投票会根据每个模型预测的类别概率进行加权平均(这里所有模型权重均为1),并选择概率最大的类别作为最终预测结果。随后,使用训练数据集X_train和y_train对软投票分类器进行训练,以便应用于分类任务,相比硬投票,软投票能够更好地利用模型预测概率的信息

软投票分类器使用权重参数 weights,为每个模型分配相同的权重 [1, 1, 1, 1, 1, 1],这意味着每个模型对最终预测结果的影响力是相等的。在软投票中,分类器的预测概率会根据其权重进行加权平均,然后选择加权概率最高的类别作为最终预测结果。如果某些模型在实际中表现更优,可以通过调整权重(如给更强的模型更高的权重)来提升分类器整体性能,从而使其对最终决策的贡献更大

在软投票分类器中,由于最终预测结果是基于模型预测概率的加权平均,这就要求每个参与投票的模型能够返回预测概率分布。然而,像 SVM(支持向量机)等一些模型默认情况下并不会返回预测概率,它们只提供类别标签的预测值。这使得这些模型在软投票中难以直接使用。如果确实需要将这样的模型纳入软投票分类器,可以通过设置其参数(如在 SVM 中启用 probability=True)来强制模型返回概率,但这可能会增加训练时间或降低模型性能。因此,在软投票中,优选像随机森林、XGBoost、LightGBM、CatBoost 等天然支持概率输出的模型,以确保集成效果和模型兼容性

模型成绩输出

from sklearn.metrics import classification_report# 硬投票预测测试集
y_pred_hard = voting_hard.predict(X_test)# 输出硬投票模型的评价指标
print("Classification Report for Hard Voting:")
print(classification_report(y_test, y_pred_hard))# 软投票预测测试集
y_pred_soft = voting_soft.predict(X_test)# 输出软投票模型的评价指标
print("Classification Report for Soft Voting:")
print(classification_report(y_test, y_pred_soft))

图片

使用硬投票和软投票分类器对测试集进行预测,并通过分类报告(classification_report)评估两种投票方式的分类性能,包括精确率、召回率和F1分数等指标,从结果中可以看出,软投票的总体准确率(accuracy)略高于硬投票(0.83 vs 0.82),并且在分类报告中,软投票在多个指标(如精确率和加权平均分数)上表现更优,表明软投票更好地综合了各模型的预测概率信息

混淆矩阵输出

from sklearn.metrics import confusion_matrix
import seaborn as sns
# 硬投票的混淆矩阵
conf_matrix_hard = confusion_matrix(y_test, y_pred_hard)
# 软投票的混淆矩阵
conf_matrix_soft = confusion_matrix(y_test, y_pred_soft)
fig, axes = plt.subplots(1, 2, figsize=(16, 6), dpi=1200)
# 绘制硬投票混淆矩阵热力图
sns.heatmap(conf_matrix_hard, annot=True, annot_kws={'size': 15}, fmt='d', cmap='YlGnBu', cbar_kws={'shrink': 0.75},ax=axes[0])
axes[0].set_title('Confusion Matrix (Hard Voting)', fontsize=15)
axes[0].set_xlabel('Predicted Label', fontsize=15)
axes[0].set_ylabel('True Label', fontsize=15)
# 绘制软投票混淆矩阵热力图
sns.heatmap(conf_matrix_soft, annot=True, annot_kws={'size': 15}, fmt='d', cmap='YlGnBu', cbar_kws={'shrink': 0.75},ax=axes[1])
axes[1].set_title('Confusion Matrix (Soft Voting)', fontsize=15)
axes[1].set_xlabel('Predicted Label', fontsize=15)
axes[1].set_ylabel('True Label', fontsize=15)
plt.tight_layout()
plt.savefig("混淆矩阵_硬投票_软投票.pdf", format='pdf', bbox_inches='tight')
plt.show()

图片

可视化硬投票和软投票分类器的混淆矩阵,通过热力图对比两种投票方式的分类效果

硬投票ROC绘制

from sklearn.metrics import roc_curve, roc_auc_score
# 初始化字典存储每个模型的预测结果和ROC信息
models = {'RandomForest': rf_clf,'XGBoost': xgb_clf,'LightGBM': lgbm_clf,'GradientBoosting': gbm_clf,'AdaBoost': adaboost_clf,'CatBoost': catboost_clf
}
# 绘制ROC曲线
plt.figure(figsize=(10, 8))
for name, model in models.items():# 获取预测概率y_proba = model.fit(X_train, y_train).predict_proba(X_test)[:, 1]# 计算ROC曲线和AUCfpr, tpr, _ = roc_curve(y_test, y_proba)auc_score = roc_auc_score(y_test, y_proba)# 绘制ROC曲线plt.plot(fpr, tpr, label=f"{name} (AUC = {auc_score:.2f})")
# 添加对硬投票分类器的ROC曲线
voting_hard.fit(X_train, y_train)
y_pred_hard = voting_hard.predict(X_test)
# 使用投票分类器计算硬投票下的AUC和假阳率、真阳率
y_proba_hard = voting_hard.transform(X_test)[:, 1]  # 获取概率
fpr_hard, tpr_hard, _ = roc_curve(y_test, y_proba_hard)
auc_score_hard = roc_auc_score(y_test, y_proba_hard)
plt.plot(fpr_hard, tpr_hard, label=f"Voting (AUC = {auc_score_hard:.2f})", linestyle='--')
plt.plot([0, 1], [0, 1], 'k--', label="Random Guessing")
plt.xlabel('False Positive Rate (FPR)', fontsize=18)
plt.ylabel('True Positive Rate (TPR)', fontsize=18)
plt.title('ROC Curve of Base Models and Voting Classifier', fontsize=18)
plt.legend(loc='lower right')
plt.grid()
plt.savefig("ROC Curve of Base Models and Voting Classifier.pdf", format='pdf', bbox_inches='tight',dpi=1200)
plt.show()

图片

从图中可以看出,所谓的Voting ROC曲线是通过对多个基分类器的预测概率进行求平均后计算得到的。由于硬投票分类器本身不返回概率分布,而是基于多数表决输出最终的类别,因此无法直接计算其ROC曲线。这里的Voting ROC是一种近似处理方式,将基分类器的预测概率取平均后作为集成模型的预测概率,再根据该平均概率计算ROC曲线和AUC分数。这种方法并非硬投票的真实表现,但可以用来间接评估集成模型的总体概率预测性能,因此它无法直接生成ROC曲线,需单独分析基分类器的ROC或切换为软投票(基于概率)以便绘制整体ROC曲线

软投票ROC绘制


# 获取软投票分类器的预测概率
y_proba_soft = voting_soft.predict_proba(X_test)[:, 1]  # 选择正类的概率# 计算软投票分类器的ROC曲线和AUC值
fpr_soft, tpr_soft, _ = roc_curve(y_test, y_proba_soft)
auc_score_soft = roc_auc_score(y_test, y_proba_soft)# 绘制ROC曲线
plt.figure(figsize=(8, 6))
plt.plot(fpr_soft, tpr_soft, label=f"Soft Voting (AUC = {auc_score_soft:.2f})")# 添加随机猜测的基线
plt.plot([0, 1], [0, 1], 'k--', label="Random Guessing")# 图形修饰
plt.xlabel('False Positive Rate (FPR)', fontsize=18)
plt.ylabel('True Positive Rate (TPR)', fontsize=18)
plt.title('ROC Curve of Soft Voting Classifier', fontsize=18)
plt.legend(loc='lower right')
plt.grid()
plt.savefig("ROC Curve of Soft Voting Classifier.pdf", format='pdf', bbox_inches='tight',dpi=1200)
plt.show()

软投票能够直接绘制ROC曲线的原因是:软投票分类器基于各基分类器的预测概率进行加权平均后,输出的是一个连续的概率分布。这种概率分布可以直接用于计算ROC曲线和AUC分数,因为 ROC曲线反映的是模型在不同阈值下的分类性能,而这种连续的预测概率可以提供灵活的阈值调整

相比之下,硬投票只输出离散的类别标签(如0或1),没有概率信息,无法直接用于ROC曲线的绘制,因此,软投票由于其基于概率输出的特性,可以轻松绘制ROC曲线并评估分类器性能,关注微信公众号:Python机器学习AI

往期推荐

从模型构建到在线部署:基于Stacking集成模型的全流程实现与SHAP可视化

探究SHAP交互效应:基于shap.dependence_plot与自定义可视化方法的对比分析

利用Optuna TPE算法优化RF模型及3D曲面图展示调参过程

nature medicine二分类结局随机森林模型构建与评估复现

期刊配图:分类变量SHAP值的箱线图及可视化优化展示

如何用SHAP解读集成学习Stacking中的基学习器和元学习器以及整体模型贡献

从入门到实践:如何利用Stacking集成多种机器学习算法提高模型性能

整合数据分布+拟合线+置信区间+相关系数的皮尔逊相关可视化

期刊配图:通过变量热图展示样本与模型预测的关联信息

期刊配图:如何有效呈现回归、分类模型的评价指标


http://www.ppmy.cn/news/1557466.html

相关文章

el-form组件中的常用属性

el-form组件: 是 Element UI 框架中用于创建表单的组件,它提供了丰富的功能和便捷的配置方式,方便在 Vue 项目中构建各种表单应用场景。 常用属性解释: 1、v-model: 用于将表单与一个数据对象进行双向绑定&#xf…

读书笔记~管理修炼-费斯汀格法则

费斯汀格法则:你的态度至关重要 一、什么是费斯汀格法则 费斯汀格法则是由美国社会心理学家费斯汀格(Leon Festinger)提出的一个心理学概念。这个法则主要阐述了人们对于生活中发生的事件的态度和反应对后续事件的影响。具体来说,…

37. Three.js案例-绘制部分球体

37. Three.js案例-绘制部分球体 实现效果 知识点 WebGLRenderer WebGLRenderer 是Three.js中的一个渲染器类,用于将3D场景渲染到网页上。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数,可选。 常用…

基于Spring Boot的医院质控上报系统

一、系统背景与意义 医院质控上报系统旨在通过信息化手段,实现医院质量控制的标准化、流程化和自动化管理。该系统能够帮助医院实时监控医疗质量数据,及时发现和处理潜在的质量问题,从而确保医疗服务的安全性和有效性。同时,系统…

C# 23种设计模式(5)命令模式(Command Pattern)

一、命令模式介绍 命令模式(Command Pattern)是一种行为设计模式,它将一个请求封装为一个对象,从而允许用户用不同的请求、队列请求、记录请求日志,以及支持可撤销的操作等。命令模式的主要目的是将请求的执行者和请求…

深入了解Java在人工智能领域的最新应用

Java不仅是传统企业级开发的主要语言,在人工智能(AI)领域也表现出强大的适应能力。随着AI技术的飞速发展,Java在机器学习框架、大数据分析以及深度学习中发挥了重要作用。本文将重点介绍Java在AI领域的最新进展与实际应用场景。 …

在Excel中如果制作可以自动填充的序号,删除或者合并单元也可用

大家好,我是小鱼。在日常的办公中有时需要制作带序号的表格,这样可以通过序号来直观地看到有多少条信息,但是如果普通的批量添加序号的话,一旦我们删除或者合并某几行数据,前面的序号不会自动更新,序号显示…

如何解决微信小程序使用webview无法打开

问题: 微信小程序使用 webview 但是页面无法打卡 解决: 1、登录微信小程序后台,管理–>开发管理–>鼠标下滑到 -->业务域名 2、根据指示配置一下就可以了 记住! 这里下载文件,要上传到您所要展示文件的域名…