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

embedded/2024/12/23 5:02:47/

图片

背景

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/embedded/147982.html

相关文章

设计模式学习[13]---抽象工厂模式+简单工厂+工厂方法模式回顾

文章目录 前言1.原理阐述1.1 说明11.2 说明2 2.举例 总结 前言 之前写过一些工厂的相关内容,详情见这两篇:简单工厂与工厂方法 这篇博客主要讲抽象工厂模式。 1.原理阐述 1.1 说明1 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的…

Neo4j插入数据逐级提升速度4倍又4倍

语雀版:https://www.yuque.com/xw76/back/dtukgqfkfwg1d6yo 目录 背景介绍初始方案Node()创建事务批量提交记录Node是否存在生成Cypher语句执行数据库参数优化切换成85k个三元组测试建索引(很显著!!!)MATCH…

Java 实现 AES 加密和解密

目录 前言 一、AES 加密算法简介 1.诞生背景 2.简介 二、AES 加密算法的核心原理 1.分组密码模式 2.密钥扩展 3.加密轮次与操作 三、AES 加密算法的优势 1.高效性 2.安全性 3.广泛的适用性 四、AES加密模式的几种方式 1.电子密码本模式(ECB&#xff0c…

【嵌入式开发笔记】OpenOCD到嵌入式调试

最近在把玩一块Risc-V的开发板,使用开发板调试时,需要用到专门的下载器和OpenOCD进行调试。 为了连接这个板子,费了九牛二虎之力。 这里简单记录一下自己的折腾经过吧。 0x00 环境准备 0x0001 调试背景 系统:Virtual Box Ub…

【软考高级】系统架构设计师复习笔记-精华版

文章目录 前言0 系统架构设计师0.1 考架构还是考系分0.2 架构核心知识0.3 架构教材变化 1 计算机操作系统1.1 cpu 组成1.2 内核的五大功能1.3 流水线技术1.4 段页式存储1.5 I/O 软件1.6 文件管理1.7 系统工程相关 2 嵌入式2.1 嵌入式技术2.2 板级支持包(BSP&#xf…

Windows开机黑屏|Windows开机黑屏只有鼠标|Windows开机不运行explorer

输入regedit打开注册表,进入以下路径 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 左键双击右侧的 Shell 查看是否设置为 Explorer.exe

MONI后台管理系统-swagger3(springdoc-openapi)集成

springdoc-openapi Java 库有助于使用 Spring Boot 项目自动生成 API 文档。springdoc-openapi 通过在运行时检查应用程序来根据 Spring 配置、类结构和各种注释推断 API 语义。 该库会自动生成 JSON/YAML 和 HTML 格式的页面文档。生成的文档可以使用swagger-api注释进行补充。…

聚观早报 | 百度回应进军短剧;iPad Air将升级OLED

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 12月18日消息 百度回应进军短剧 iPad Air将升级OLED 三星Galax S25 Ultra配色细节 一加Ace 5系列存储规格 小米…