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

背景

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

VotingClassifier的核心机制

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

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

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

VotingClassifier的优劣势

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

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

代码实现

数据读取

python 复制代码
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'] = False

df = 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表示分类标签,且为二分类数据(目标变量只有两个类别)

硬投票模型实现

python 复制代码
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对硬投票分类器进行训练,为后续分类任务做好准备

软投票模型实现

python 复制代码
# 创建软投票分类器
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 等天然支持概率输出的模型,以确保集成效果和模型兼容性

模型成绩输出

python 复制代码
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),并且在分类报告中,软投票在多个指标(如精确率和加权平均分数)上表现更优,表明软投票更好地综合了各模型的预测概率信息

混淆矩阵输出

python 复制代码
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绘制

python 复制代码
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曲线和AUC
    fpr, 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绘制

python 复制代码
# 获取软投票分类器的预测概率
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集成多种机器学习算法提高模型性能

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

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

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

相关推荐
程序猿阿伟1 分钟前
《C++与 Armadillo:线性代数助力人工智能算法简化之路》
c++·人工智能·线性代数
沐欣工作室_lvyiyi9 分钟前
基于单片机的无线水塔监控系统设计(论文+源码)
人工智能·stm32·单片机·嵌入式硬件·单片机毕业设计
野蛮的大西瓜20 分钟前
BigBlueButton视频会议 vs 华为云会议的详细对比
人工智能·自动化·音视频·实时音视频·信息与通信·视频编解码
野蛮的大西瓜2 小时前
文心一言对接FreeSWITCH实现大模型呼叫中心
人工智能·机器人·自动化·音视频·实时音视频·文心一言·信息与通信
lover_putter2 小时前
ai学习报告:训练
人工智能·学习
Srlua2 小时前
基于预测反馈的情感分析情境学习
人工智能·python
这个男人是小帅2 小时前
【AutoDL】通过【SSH远程连接】【vscode】
运维·人工智能·pytorch·vscode·深度学习·ssh
野蛮的大西瓜2 小时前
BigBlueButton视频会议 vs 钉钉视频会议系统的详细对比
人工智能·自然语言处理·自动化·音视频·实时音视频·信息与通信·视频编解码
四口鲸鱼爱吃盐3 小时前
Pytorch | 利用MI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
zaim13 小时前
计算机的错误计算(一百八十七)
人工智能·ai·大模型·llm·错误·正弦/sin·误差/error