机器学习进阶<10>分类器集成:集成学习算法

引言

在机器学习建模过程中,我们常常会遇到这样的困境:单分类器在测试集上的准确率始终徘徊不前,调参到极致也难以突破瓶颈;或者模型在部分样本上表现稳定,但对异常数据的鲁棒性极差。如果你也有过类似的困扰,那今天要聊的技术,或许能成为你的破局关键。

分类器集成并非什么高深莫测的黑科技,其核心思想简单又精妙------"三个臭皮匠顶个诸葛亮"。通过将多个性能一般的基分类器 组合起来,形成一个强分类器,从而实现比单个基分类器更优的分类效果。今天这篇文章,我们就从原理、经典算法、实战代码到调优技巧,全方位拆解分类器集成,让你既能懂原理,又能上手用。

一、为什么需要分类器集成?先搞懂单分类器的"短板"

在聊集成之前,我们得先明白:单分类器的局限性是天生的。具体来说,主要有三个核心问题:

  • 偏差与方差的矛盾:简单模型(如逻辑回归、决策树深度较浅时)往往偏差高、方差低,容易出现"欠拟合";复杂模型(如深度神经网络、复杂决策树)则相反,方差高、偏差低,容易"过拟合"。单分类器很难同时兼顾低偏差和低方差。

  • 泛化能力不足:单个模型对数据分布的敏感度较高,一旦测试集与训练集的分布有细微差异,性能就可能大幅下降。比如用单一决策树处理不平衡数据时,很容易偏向多数类样本。

  • 局部最优陷阱:模型训练过程本质是寻找损失函数最小值的过程,但单分类器很容易陷入局部最优解,无法触及全局最优。

而分类器集成的核心价值,就是通过组合来弥补这些短板:通过选择多样化的基分类器,降低整体模型的方差;通过迭代优化或加权组合,降低偏差;最终实现"1+1>2"的泛化能力提升。

二、分类器集成的核心原理:两个关键要素

并非随便把几个分类器堆在一起就能叫"集成",有效的集成必须满足两个核心条件,缺一不可:

1. 基分类器的"多样性"

这是集成的灵魂。如果所有基分类器的判断结果完全一致(即高度相关),那么集成后的结果和单个分类器没有区别。只有当基分类器之间存在"互补性"------有的擅长识别正样本,有的擅长排除负样本,有的对噪声不敏感,集成才能发挥作用。

实现多样性的常见方式有三种:

  • 数据层面:对训练集进行抽样(如Bagging的自助抽样),让不同基分类器在不同的数据子集上训练。

  • 模型层面:选择不同类型的基分类器(如逻辑回归+SVM+决策树),或同一类型但超参数不同的模型(如不同深度的决策树)。

  • 特征层面:对特征进行抽样(如随机森林的特征随机选择),让不同基分类器关注不同的特征维度。

2. 合理的"组合策略"

有了多样化的基分类器,还需要一套规则将它们的预测结果组合起来。常见的组合策略分为「并行式」和「串行式」两类,分别对应不同的集成框架:

  • 并行式组合:所有基分类器独立训练,组合时仅融合预测结果(如投票、平均),代表算法是Bagging。

  • 串行式组合:基分类器按顺序训练,后一个分类器会根据前一个分类器的错误进行优化(如加权),代表算法是Boosting。

三、三大经典集成算法:从原理到适用场景

了解了核心原理后,我们来看工业界最常用的三大集成算法。这部分是重点,建议结合实际场景理解适用范围。

1. Bagging:并行集成的"稳定派"

核心思想:"自助抽样+并行训练+简单投票"。通过自助抽样(Bootstrap)从原始训练集中随机抽取多个子集,每个子集训练一个基分类器,最终通过投票(分类任务)或平均(回归任务)得到结果。

代表算法:随机森林(Random Forest)

随机森林在Bagging的基础上增加了"特征随机选择":每个决策树节点分裂时,仅从随机选择的部分特征中挑选最优分裂点。这进一步增强了基分类器的多样性,也避免了单棵决策树过拟合的问题。

优势

  • 并行训练效率高,可充分利用多核CPU;

  • 对噪声数据不敏感,鲁棒性强;

  • 自带特征重要性评估,可用于特征选择。

适用场景:数据量较大、存在噪声、需要快速建模的场景,如用户行为分类、垃圾邮件识别。

注意点:对小样本数据效果一般,因为自助抽样可能导致样本代表性不足。

2. Boosting:串行集成的"优化派"

核心思想:"迭代优化+加权投票"。先训练一个简单的基分类器,然后根据其预测错误调整样本权重(错分样本权重提高,正确样本权重降低),再训练下一个基分类器,重复此过程,最终将所有基分类器加权组合(性能好的分类器权重高)。

代表算法

  • AdaBoost:最基础的Boosting算法,通过样本权重调整实现优化,结构简单但对噪声敏感。

  • XGBoost/LightGBM/CatBoost:工业界主流的梯度提升树(GBDT)变种,通过梯度下降优化损失函数,支持正则化、缺失值处理,精度极高。

优势

  • 精度高,在 Kaggle 竞赛中常年霸榜;

  • 对特征工程要求较低,可自动处理非线性关系。

适用场景:对精度要求高的场景,如信用风险评估、房价预测(回归)、疾病诊断。

注意点:串行训练效率较低,对噪声数据和异常值敏感,需要调参(如学习率、树深度)控制过拟合。

3. Stacking:集成中的"终极玩家"

核心思想:"分层集成+元分类器"。将多个基分类器的预测结果作为新的特征,输入到一个"元分类器"(Meta-Classifier)中,由元分类器给出最终预测。相当于用一个更高级的模型来学习"如何组合基分类器"。

结构分为两层

  • 第一层(基学习器):训练多个不同类型的基分类器(如随机森林+XGBoost+SVM),得到各自的预测概率。

  • 第二层(元学习器):用基分类器的预测概率作为特征,训练一个简单模型(如逻辑回归、轻量GBDT),学习最优组合方式。

优势:灵活性极高,可融合不同类型模型的优势,理论上能达到更高精度。

适用场景:Kaggle 等竞赛的"冲榜"阶段,或对精度有极致要求的核心业务。

注意点:模型复杂度高,容易过拟合(需用交叉验证避免);训练成本高,不适合实时推理场景。

四、实战演练:用Python实现三大集成算法

光说不练假把式,接下来我们用 sklearn 实现随机森林(Bagging)、XGBoost(Boosting)和 Stacking,基于葡萄酒数据集(分类任务)对比性能。

环境准备:先安装必要的库

python 复制代码
pip install sklearn xgboost pandas numpy

1. 数据加载与预处理

python 复制代码
import pandas as pd
import numpy as np
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report

# 加载数据集(葡萄酒分类:3类,13个特征)
wine = load_wine()
X = pd.DataFrame(wine.data, columns=wine.feature_names)
y = pd.Series(wine.target, name='target')

# 划分训练集/测试集(7:3)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

print(f"训练集规模:{X_train.shape},测试集规模:{X_test.shape}")

2. 实现三大集成算法并对比

python 复制代码
from sklearn.ensemble import RandomForestClassifier, StackingClassifier
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC

# 1. 随机森林(Bagging)
rf = RandomForestClassifier(
    n_estimators=100,  # 基分类器数量
    max_depth=5,       # 每棵树最大深度
    random_state=42
)
rf.fit(X_train, y_train)
rf_pred = rf.predict(X_test)
rf_acc = accuracy_score(y_test, rf_pred)

# 2. XGBoost(Boosting)
xgb = XGBClassifier(
    n_estimators=100,
    learning_rate=0.1,  # 学习率,控制每步权重更新幅度
    max_depth=3,
    random_state=42,
    use_label_encoder=False,
    eval_metric='mlogloss'  # 多分类损失函数
)
xgb.fit(X_train, y_train)
xgb_pred = xgb.predict(X_test)
xgb_acc = accuracy_score(y_test, rf_pred)

# 3. Stacking(基分类器:随机森林+XGBoost+SVM;元分类器:逻辑回归)
base_models = [
    ('rf', RandomForestClassifier(n_estimators=50, random_state=42)),
    ('xgb', XGBClassifier(n_estimators=50, random_state=42, use_label_encoder=False, eval_metric='mlogloss')),
    ('svm', SVC(probability=True, random_state=42))  # SVM需开启概率预测
]
stack = StackingClassifier(
    estimators=base_models,
    final_estimator=LogisticRegression(random_state=42)
)
stack.fit(X_train, y_train)
stack_pred = stack.predict(X_test)
stack_acc = accuracy_score(y_test, stack_pred)

# 输出结果对比
print("=== 模型准确率对比 ===")
print(f"随机森林:{rf_acc:.4f}")
print(f"XGBoost:{xgb_acc:.4f}")
print(f"Stacking:{stack_acc:.4f}")
print("\n=== Stacking 分类报告 ===")
print(classification_report(y_test, stack_pred))

3. 结果分析

运行代码后,你会发现:

  • 随机森林和 XGBoost 准确率都在 95% 以上,远超单分类器(如逻辑回归约 90%);

  • Stacking 准确率可能略高于前两者(或持平),但优势在复杂数据集上更明显;

  • XGBoost 的训练速度比随机森林慢,但精度更稳定;Stacking 训练最慢,但灵活性最高。

五、集成调优技巧:避开这些"坑",性能再提升20%

集成不是"堆模型",调优技巧直接决定最终效果。分享几个实战中总结的关键技巧:

  1. 基分类器选择:"弱而多样"优于"强而相似":不要用多个复杂且高度相关的模型(如多个XGBoost),建议搭配"简单模型+复杂模型"(如逻辑回归+XGBoost+SVM),多样性更高。

  2. 控制基分类器数量:并非越多越好。n_estimators 增加到一定程度后,精度会饱和,反而增加训练成本。一般建议 100-500 之间,通过交叉验证确定。

  3. 防止过拟合的核心手段: Bagging:减小单棵树深度、增加特征抽样比例;

  4. Boosting:降低学习率(如 0.01-0.1)、增加正则化项(如 XGBoost 的 reg_alpha);

  5. Stacking:用交叉验证生成基分类器的预测结果(避免数据泄露)。

  6. 权重调整技巧:对 Boosting 类模型,可根据基分类器在验证集的性能动态调整权重,而非默认的迭代权重。

六、总结:集成算法的选型指南

最后,用一张表总结三大算法的选型逻辑,帮你快速决策:

算法类型 核心优势 训练效率 适用场景 代表工具
Bagging(随机森林) 鲁棒性强、抗噪声 高(并行) 快速建模、数据有噪声 sklearn、Spark MLlib
Boosting(XGBoost) 精度高、支持正则化 中(串行) 精度优先、结构化数据 XGBoost、LightGBM
Stacking 融合多模型优势 低(多层训练) 竞赛冲榜、极致精度 sklearn、自定义实现

分类器集成的核心逻辑,是通过"多样性"和"组合策略"突破单模型的局限。在实际工作中,建议从简单的随机森林或XGBoost入手,再根据精度需求尝试Stacking。记住:没有最好的算法,只有最适合场景的算法。

七、项目源代码

python 复制代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, roc_curve, auc
from sklearn.preprocessing import label_binarize
from sklearn.ensemble import RandomForestClassifier, StackingClassifier
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
import warnings

warnings.filterwarnings('ignore')

# 设置图形样式
plt.rcParams['figure.figsize'] = [12, 8]
plt.rcParams['font.size'] = 12
sns.set_style("whitegrid")

# 加载数据集(葡萄酒分类:3类,13个特征)
wine = load_wine()
X = pd.DataFrame(wine.data, columns=wine.feature_names)
y = pd.Series(wine.target, name='target')
target_names = wine.target_names

# 划分训练集/测试集(7:3)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

print(f"训练集规模:{X_train.shape},测试集规模:{X_test.shape}")
print(f"类别分布 - 训练集: {np.bincount(y_train)},测试集: {np.bincount(y_test)}")

# 1. 随机森林(Bagging)
rf = RandomForestClassifier(
    n_estimators=100,
    max_depth=5,
    random_state=42
)
rf.fit(X_train, y_train)
rf_pred = rf.predict(X_test)
rf_acc = accuracy_score(y_test, rf_pred)

# 2. XGBoost(Boosting)
xgb = XGBClassifier(
    n_estimators=100,
    learning_rate=0.1,
    max_depth=3,
    random_state=42,
    eval_metric='mlogloss'
)
xgb.fit(X_train, y_train)
xgb_pred = xgb.predict(X_test)
xgb_acc = accuracy_score(y_test, xgb_pred)

# 3. Stacking
base_models = [
    ('rf', RandomForestClassifier(n_estimators=50, random_state=42)),
    ('xgb', XGBClassifier(n_estimators=50, random_state=42, eval_metric='mlogloss')),
    ('svm', SVC(probability=True, random_state=42))
]
stack = StackingClassifier(
    estimators=base_models,
    final_estimator=LogisticRegression(random_state=42, max_iter=1000)
)
stack.fit(X_train, y_train)
stack_pred = stack.predict(X_test)
stack_acc = accuracy_score(y_test, stack_pred)

# 输出结果对比
print("\n" + "=" * 40)
print("=== 模型准确率对比 ===")
print("=" * 40)
print(f"随机森林准确率:{rf_acc:.4f}")
print(f"XGBoost准确率:{xgb_acc:.4f}")
print(f"Stacking准确率:{stack_acc:.4f}")

print("\n" + "=" * 40)
print("=== Stacking 分类报告 ===")
print("=" * 40)
print(classification_report(y_test, stack_pred, target_names=target_names))

# ==================== 可视化部分 ====================

# 1. 创建综合可视化图表
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
fig.suptitle('Wine Classification Model Performance Visualization', fontsize=16, fontweight='bold')

# 1.1 准确率对比柱状图
ax1 = axes[0, 0]
models = ['Random Forest', 'XGBoost', 'Stacking']
accuracies = [rf_acc, xgb_acc, stack_acc]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
bars = ax1.bar(models, accuracies, color=colors, alpha=0.8)
ax1.set_title('Model Accuracy Comparison', fontsize=14, fontweight='bold')
ax1.set_ylabel('Accuracy', fontsize=12)
ax1.set_ylim(0, 1.1)
ax1.grid(True, alpha=0.3)

for bar, acc in zip(bars, accuracies):
    height = bar.get_height()
    ax1.text(bar.get_x() + bar.get_width() / 2., height + 0.02,
             f'{acc:.3f}', ha='center', va='bottom', fontweight='bold')

# 1.2 训练集特征分布箱线图
ax2 = axes[0, 1]
# 选择前6个特征进行可视化
selected_features = X_train.columns[:6]
data_to_plot = []
for feature in selected_features:
    data_to_plot.append(X_train[feature].values)

box = ax2.boxplot(data_to_plot, patch_artist=True, labels=selected_features)
colors_box = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99', '#FF99CC', '#99CCFF']
for patch, color in zip(box['boxes'], colors_box):
    patch.set_facecolor(color)
    patch.set_alpha(0.7)

ax2.set_title('Feature Distribution (Training Set)', fontsize=14, fontweight='bold')
ax2.set_ylabel('Value', fontsize=12)
ax2.tick_params(axis='x', rotation=45)

# 1.3 类别分布饼图
ax3 = axes[0, 2]
class_counts = np.bincount(y_train)
colors_pie = ['#FF6B6B', '#4ECDC4', '#45B7D1']
wedges, texts, autotexts = ax3.pie(class_counts,
                                   labels=target_names,
                                   colors=colors_pie,
                                   autopct='%1.1f%%',
                                   startangle=90,
                                   explode=(0.05, 0.05, 0.05))
ax3.set_title('Class Distribution (Training Set)', fontsize=14, fontweight='bold')
for autotext in autotexts:
    autotext.set_color('white')
    autotext.set_fontweight('bold')

# 1.4 随机森林特征重要性
ax4 = axes[1, 0]
rf_importance = pd.DataFrame({
    'feature': wine.feature_names,
    'importance': rf.feature_importances_
}).sort_values('importance', ascending=True)

bars_rf = ax4.barh(rf_importance['feature'], rf_importance['importance'], color='#FF6B6B', alpha=0.7)
ax4.set_title('Random Forest Feature Importance', fontsize=14, fontweight='bold')
ax4.set_xlabel('Importance Score', fontsize=12)

# 1.5 XGBoost特征重要性
ax5 = axes[1, 1]
xgb_importance = pd.DataFrame({
    'feature': wine.feature_names,
    'importance': xgb.feature_importances_
}).sort_values('importance', ascending=True)

bars_xgb = ax5.barh(xgb_importance['feature'], xgb_importance['importance'], color='#4ECDC4', alpha=0.7)
ax5.set_title('XGBoost Feature Importance', fontsize=14, fontweight='bold')
ax5.set_xlabel('Importance Score', fontsize=12)

# 1.6 混淆矩阵(Stacking模型)
ax6 = axes[1, 2]
cm = confusion_matrix(y_test, stack_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
            xticklabels=target_names, yticklabels=target_names, ax=ax6)
ax6.set_title('Stacking Confusion Matrix', fontsize=14, fontweight='bold')
ax6.set_xlabel('Predicted Label', fontsize=12)
ax6.set_ylabel('True Label', fontsize=12)

plt.tight_layout()
plt.savefig('model_performance_visualization.png', dpi=300, bbox_inches='tight')
plt.show()

# 2. 创建ROC曲线图
fig2, ax_roc = plt.subplots(figsize=(10, 8))

# 将标签二值化
y_test_bin = label_binarize(y_test, classes=[0, 1, 2])
n_classes = y_test_bin.shape[1]

# 为每个模型计算ROC曲线
models_info = [
    ('Random Forest', rf, rf_pred, '#FF6B6B'),
    ('XGBoost', xgb, xgb_pred, '#4ECDC4'),
    ('Stacking', stack, stack_pred, '#45B7D1')
]

for name, model, pred, color in models_info:
    # 获取预测概率
    if hasattr(model, "predict_proba"):
        y_score = model.predict_proba(X_test)
    else:
        y_score = model.decision_function(X_test)

    # 计算微平均ROC曲线
    fpr_micro, tpr_micro, _ = roc_curve(y_test_bin.ravel(), y_score.ravel())
    roc_auc_micro = auc(fpr_micro, tpr_micro)

    # 绘制ROC曲线
    ax_roc.plot(fpr_micro, tpr_micro, color=color, lw=2,
                label=f'{name} (AUC = {roc_auc_micro:.3f})')

# 绘制对角线
ax_roc.plot([0, 1], [0, 1], 'k--', lw=1, alpha=0.6)
ax_roc.set_xlim([0.0, 1.0])
ax_roc.set_ylim([0.0, 1.05])
ax_roc.set_xlabel('False Positive Rate', fontsize=12)
ax_roc.set_ylabel('True Positive Rate', fontsize=12)
ax_roc.set_title('ROC Curves (Micro-average)', fontsize=14, fontweight='bold')
ax_roc.legend(loc="lower right")
ax_roc.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('roc_curves.png', dpi=300, bbox_inches='tight')
plt.show()

# 3. 创建性能对比雷达图
fig3 = plt.figure(figsize=(10, 8))
ax_radar = fig3.add_subplot(111, projection='polar')


# 获取分类指标
def get_metrics(y_true, y_pred):
    report = classification_report(y_true, y_pred, output_dict=True)
    return {
        'precision': report['macro avg']['precision'],
        'recall': report['macro avg']['recall'],
        'f1': report['macro avg']['f1-score'],
        'accuracy': report['accuracy']
    }


# 收集每个模型的指标
rf_metrics = get_metrics(y_test, rf_pred)
xgb_metrics = get_metrics(y_test, xgb_pred)
stack_metrics = get_metrics(y_test, stack_pred)

# 准备雷达图数据
categories = ['Accuracy', 'Precision', 'Recall', 'F1-Score']
N = len(categories)


# 将数据转为列表
def metrics_to_list(metrics):
    return [metrics['accuracy'], metrics['precision'],
            metrics['recall'], metrics['f1']]


rf_values = metrics_to_list(rf_metrics)
xgb_values = metrics_to_list(xgb_metrics)
stack_values = metrics_to_list(stack_metrics)

# 角度设置
angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
angles += angles[:1]  # 闭合

rf_values += rf_values[:1]
xgb_values += xgb_values[:1]
stack_values += stack_values[:1]

# 绘制雷达图
ax_radar.plot(angles, rf_values, 'o-', linewidth=2, label='Random Forest', color='#FF6B6B')
ax_radar.fill(angles, rf_values, alpha=0.1, color='#FF6B6B')
ax_radar.plot(angles, xgb_values, 'o-', linewidth=2, label='XGBoost', color='#4ECDC4')
ax_radar.fill(angles, xgb_values, alpha=0.1, color='#4ECDC4')
ax_radar.plot(angles, stack_values, 'o-', linewidth=2, label='Stacking', color='#45B7D1')
ax_radar.fill(angles, stack_values, alpha=0.1, color='#45B7D1')

# 设置标签
ax_radar.set_xticks(angles[:-1])
ax_radar.set_xticklabels(categories, fontsize=12)
ax_radar.set_ylim(0, 1.1)
ax_radar.set_title('Model Performance Radar Chart', fontsize=14, fontweight='bold', pad=20)
ax_radar.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
ax_radar.grid(True)

plt.tight_layout()
plt.savefig('performance_radar_chart.png', dpi=300, bbox_inches='tight')
plt.show()

# 4. 特征相关性热图
fig4, ax_corr = plt.subplots(figsize=(12, 10))
correlation_matrix = X.corr()
mask = np.triu(np.ones_like(correlation_matrix, dtype=bool))
sns.heatmap(correlation_matrix, mask=mask, annot=True, fmt='.2f',
            cmap='coolwarm', center=0, square=True, linewidths=0.5,
            cbar_kws={"shrink": 0.8}, ax=ax_corr)
ax_corr.set_title('Feature Correlation Heatmap', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.savefig('feature_correlation.png', dpi=300, bbox_inches='tight')
plt.show()

print("\n" + "=" * 50)
print("Visualization Summary:")
print("=" * 50)
print("1. model_performance_visualization.png - Main performance dashboard")
print("2. roc_curves.png - ROC curves for all models")
print("3. performance_radar_chart.png - Performance comparison radar chart")
print("4. feature_correlation.png - Feature correlation heatmap")
print("\nAll charts have been saved to the current directory!")

1.model_performance_visualization.png(模型性能综合可视化)

这张综合图表包含了6个子图,全面展示了模型的各个方面:

  • 左上角:模型准确率对比柱状图,直观显示三个模型(随机森林、XGBoost、Stacking)在测试集上的准确率,柱状图高度代表准确率数值

  • 右上角:训练集特征分布箱线图,展示了前6个特征的数值分布情况,箱体显示数据的四分位数,须线显示数据范围,异常值以点显示

  • 中上:类别分布饼图,显示训练集中三个葡萄酒类别的比例分布,帮助了解数据是否均衡

  • 左下角:随机森林特征重要性条形图,展示了随机森林模型认为最重要的特征,特征重要性越高表示该特征对分类贡献越大

  • 中下:XGBoost特征重要性条形图,展示了XGBoost模型的特征重要性排序,可以与随机森林的结果进行对比

  • 右下角:Stacking模型混淆矩阵热力图,显示Stacking模型的预测结果,对角线上的数值表示正确分类的样本数,非对角线表示误分类情况

2. roc_curves.png(ROC曲线图)

ROC曲线图是评估分类模型性能的重要工具:

  • 图中展示了三个模型(随机森林、XGBoost、Stacking)的ROC曲线

  • 横轴:假正率(False Positive Rate),即被错误分类为正类的负类样本比例

  • 纵轴:真正率(True Positive Rate),即被正确分类的正类样本比例

  • 对角线:随机分类器的性能基准(AUC=0.5)

  • 每条曲线下的面积(AUC值)显示在标签中,AUC值越接近1表示模型性能越好

  • 微平均:在多分类问题中,我们将所有类别的预测合并计算一个整体的ROC曲线

3. performance_radar_chart.png(性能雷达图)

雷达图以多边形形式对比三个模型在四个关键指标上的表现:

  • 四个维度

    1. 准确率:所有样本中被正确分类的比例

    2. 精确率:预测为正类的样本中实际为正类的比例

    3. 召回率:实际为正类的样本中被正确预测的比例

    4. F1分数:精确率和召回率的调和平均数,综合衡量模型性能

  • 越靠近外圈表示性能越好(最大值为1.0)

  • 多边形面积越大表示模型综合性能越好

  • 不同颜色代表不同模型,可以直观比较哪个模型在各方面都表现更优

4. feature_correlation.png(特征相关性热图)

这张热图展示了葡萄酒数据集中13个特征之间的相关性:

  • 颜色深浅:红色表示正相关,蓝色表示负相关,白色表示无相关

  • 数值范围:-1到+1,绝对值越大表示相关性越强

  • 对角线:特征与自身的相关性为1(最深红色)

  • 应用价值

    • 帮助识别高度相关的特征(可能包含冗余信息)

    • 指导特征选择,避免多重共线性问题

    • 理解数据集中特征之间的关系结构

相关推荐
全栈陈序员2 小时前
【Python】基础语法入门(十八)——函数式编程初探:用 `map`、`filter`、`reduce` 和 `lambda` 写出更简洁的代码
开发语言·人工智能·python·学习
m5655bj2 小时前
如何使用 Python 调整 PDF 页面顺序?
python·pdf
数据科学项目实践2 小时前
建模步骤 3 :数据探索(EDA) — 1、初步了解数据:自定义函数
大数据·人工智能·python·机器学习·matplotlib·数据可视化
月明长歌2 小时前
【码道初阶】【LeetCode 160】相交链表:让跑者“起跑线对齐”的智慧
java·算法·leetcode·链表
beordie.cloud2 小时前
LeetCode 49. 字母异位词分组 | 从排序到计数的哈希表优化之路
算法·leetcode·散列表
我命由我123452 小时前
Python 开发 - OpenAI 兼容阿里云百炼平台 API
开发语言·人工智能·后端·python·阿里云·ai·语言模型
南_山无梅落2 小时前
7.2 Python3序列 | 字符串操作:常用方法与格式化技巧
python
共享家95272 小时前
每日一题(一)
算法
往事如yan2 小时前
机器学习面试核心概念速览
人工智能·机器学习