欢迎光临
我们一直在努力

堆叠学习————Blending算法

一、Blending算法核心概念

        Blending——混合集成,是 Stacking 的简化版,核心思路更简单、易实现,避免了交叉验证的复杂操作:

  • 数据拆分:将原始训练集拆分为两部分 ——训练子集(Train Set) 和验证子集(Validation Set)(比如 7:3 拆分);
  • 第一层(基学习器层):用「训练子集」训练多个基模型,然后用这些基模型预测「验证子集」和「测试集」,得到:
    • 验证子集的预测结果 → 作为第二层元学习器的「训练特征」;
    • 测试集的预测结果 → 作为第二层元学习器的「测试特征」;
  • 第二层(元学习器层):用「验证子集的预测特征 + 验证子集标签」训练元模型,最后用元模型预测「测试集的预测特征」得到最终结果;
  • 核心优势:比 Stacking 更简单、计算成本更低;缺点是只用部分数据训练基模型,数据利用率稍低。
  • Blending算法的流程图

    二、Blending算法数学公式

    数学假设:
    • 原始训练集:D= \\left \\{ \\left ( x_{1}, y_{1} \\right ) ,\\left ( x_{2}, y_{2} \\right ),..,\\left ( x_{n}, y_{n} \\right )\\right \\}
    • 拆分后:训练子集 Dtrain​(占比 α,如 70%)、验证子集 Dval​(占比 1-α,如 30%)
    • 测试集:D_{test}= \\left \\{ \\left ( x_{1}^{*}, x_{2}^{*},...,x_{m}^{*}\\right ) \\right \\}
    • 第一层基学习器:f_{1},f_{2},...,f_{ m}
    • 第二层元学习器:g
    1. 数据拆分

    D=D_{train}\\cup D _{val},D_{train}\\cup D _{val}\\neq 0,\\left | D_{train} \\right |=\\alpha n,\\left | D_{val} \\right |=\\left (1-\\alpha \\right ) n

    2. 训练基学习器并生成元特征

    对每个基学习器 f_{k}

    • 用 Dtrain​ 训练 f_{k}:f_{k}^{*}=argmin_{f_{k}}L(f_{k}(x),y),(x,y)\\epsilon D_{train}
    • 预测验证子集,生成元学习器的训练特征:F_{val},k=f_{k}^{*}\\left ( x \\right ),x\\epsilon D_{val}
    • 预测测试集,生成元学习器的测试特征:F_{test},k=f_{k}^{*}\\left ( x \\right ),x\\epsilon D_{test}
    3. 构建元学习器的训练和测试特征
    • 元学习器训练特征:F_{val}=\\left [F_{val,1},F_{val,2},...,F_{val,m}\\right ]\\epsilon R ^{\\left ( 1-\\alpha \\right )n\\times m}
    • 元学习器测试特征:F_{test}=\\left [F_{test,1},F_{test,2},...,F_{test,m}\\right ]\\epsilon R ^{m\\times m}
    • 元学习器训练标签:y_{val}=\\left [ y|(x,y)\\epsilon D_{val} \\right ]
    4. 训练元学习器并预测
    • 训练元学习器:g^{*}=argmin_{g}L\\left ( g\\left ( F_{val}\\right ),y_{val} \\right )
    • 最终预测:\\hat{y_{test}}=g^{*}\\left ( F_{test} \\right )

    三、Blending算法实例代码

    模块一:导入核心库

    import numpy as np # 数值计算
    import pandas as pd # 数据处理
    from sklearn.datasets import load_iris # 加载鸢尾花数据集
    from sklearn.model_selection import train_test_split # 数据集划分(核心:拆分两次)
    from sklearn.metrics import accuracy_score # 评估指标(准确率)
    # 第一层基学习器(和Stacking保持一致,便于对比)
    from sklearn.ensemble import RandomForestClassifier # 随机森林
    from sklearn.svm import SVC # 支持向量机
    from sklearn.neighbors import KNeighborsClassifier # K近邻
    # 第二层元学习器
    from sklearn.linear_model import LogisticRegression # 逻辑回归

    模块二:加载并预处理数据

    # 加载鸢尾花数据集
    iris = load_iris()
    X = iris.data # 特征矩阵(150×4)
    y = iris.target # 标签(150×1)

    # 第一步拆分:原始数据 → 主训练集(80%) + 测试集(20%)(最终评估用)
    # 固定随机种子保证结果可复现
    X_main, X_test, y_main, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
    )

    # 第二步拆分:主训练集 → 基模型训练集(70%) + 验证子集(30%)(Blending核心)
    # 验证子集用于生成元学习器的训练特征
    X_train_base, X_val_blend, y_train_base, y_val_blend = train_test_split(
    X_main, y_main, test_size=0.3, random_state=42, stratify=y_main
    )

    # 打印数据维度,验证拆分结果(便于理解)
    print(f"基模型训练集维度: X={X_train_base.shape}, y={y_train_base.shape}")
    print(f"Blending验证子集维度: X={X_val_blend.shape}, y={y_val_blend.shape}")
    print(f"最终测试集维度: X={X_test.shape}, y={y_test.shape}")

    模块三:定义Blending第一层基学习器列表

    # 选择和Stacking相同的3类模型,便于对比效果
    base_models = [
    ('rf', RandomForestClassifier(n_estimators=100, random_state=42)), # 随机森林
    ('svm', SVC(probability=True, random_state=42)), # SVM(输出概率)
    ('knn', KNeighborsClassifier(n_neighbors=5)) # K近邻
    ]

    模块四:生成Blending的元特征

    # 4.1 初始化元特征矩阵
    n_classes = len(np.unique(y)) # 类别数(鸢尾花=3)
    # 验证子集的元特征:行数=验证子集样本数,列数=基模型数×类别数(保留所有类别概率)
    val_meta_features = np.zeros((X_val_blend.shape[0], len(base_models) * n_classes))
    # 测试集的元特征:行数=测试集样本数,列数=基模型数×类别数
    test_meta_features = np.zeros((X_test.shape[0], len(base_models) * n_classes))

    # 4.2 遍历每个基模型,训练并生成元特征
    for idx, (name, model) in enumerate(base_models):
    # 步骤1:用「基模型训练集」训练当前基模型
    model.fit(X_train_base, y_train_base)

    # 步骤2:预测「验证子集」的概率,作为元学习器的训练特征
    val_pred_proba = model.predict_proba(X_val_blend)
    # 赋值到验证子集元特征的对应列(如第0个模型对应0-2列,第1个对应3-5列)
    val_meta_features[:, idx*n_classes : (idx+1)*n_classes] = val_pred_proba

    # 步骤3:预测「最终测试集」的概率,作为元学习器的测试特征
    test_pred_proba = model.predict_proba(X_test)
    # 赋值到测试集元特征的对应列
    test_meta_features[:, idx*n_classes : (idx+1)*n_classes] = test_pred_proba

    # 打印当前基模型在验证子集上的准确率(辅助分析)
    val_pred = model.predict(X_val_blend)
    val_acc = accuracy_score(y_val_blend, val_pred)
    print(f"\\n{name} 基模型在验证子集上的准确率: {val_acc:.4f}")

    模块五:训练Blending第二层元学习器

    # 初始化元学习器(增加max_iter避免收敛警告)
    meta_model = LogisticRegression(random_state=42, max_iter=200)
    # 用「验证子集的元特征 + 验证子集标签」训练元学习器
    meta_model.fit(val_meta_features, y_val_blend)

    模块六:用Blending模型预测最终测试集

    blending_preds = meta_model.predict(test_meta_features)

    模块七:评估模型性能

    # 7.1 计算每个基模型在最终测试集上的准确率
    print("\\n===== 基学习器在最终测试集上的准确率 =====")
    base_accs = {}
    for name, model in base_models:
    # 注意:这里基模型仅用「基模型训练集」训练,和Blending保持一致
    base_preds = model.predict(X_test)
    acc = accuracy_score(y_test, base_preds)
    base_accs[name] = acc
    print(f"{name} 准确率: {acc:.4f}")

    # 7.2 计算Blending模型的准确率
    print("\\n===== Blending模型在最终测试集上的准确率 =====")
    blending_acc = accuracy_score(y_test, blending_preds)
    print(f"Blending 准确率: {blending_acc:.4f}")

    # 7.3 对比Blending是否优于所有基模型
    best_base_acc = max(base_accs.values())
    print(f"\\n===== 对比结果 =====")
    print(f"最优基学习器准确率: {best_base_acc:.4f}")
    print(f"Blending是否更优: {blending_acc >= best_base_acc}")

    运行结果

    基模型训练集维度: X=(84, 4), y=(84,)
    Blending验证子集维度: X=(36, 4), y=(36,)
    最终测试集维度: X=(30, 4), y=(30,)

    rf 基模型在验证子集上的准确率: 0.9167

    svm 基模型在验证子集上的准确率: 0.9167

    knn 基模型在验证子集上的准确率: 0.9444

    ===== 基学习器在最终测试集上的准确率 =====
    rf 准确率: 0.9667
    svm 准确率: 0.9667
    knn 准确率: 1.0000

    ===== Blending模型在最终测试集上的准确率 =====
    Blending 准确率: 1.0000

    ===== 对比结果 =====
    最优基学习器准确率: 1.0000
    Blending是否更优: True

    四、总结

    1. 数据利用率差异
    • Blending:假设主训练集有 1000 个样本,按 7:3 拆分为 700+300,这 300 个样本只用于生成元特征,基模型完全没见过,数据浪费明显;
    • Stacking:同样 1000 个样本,做 5 折 CV,每个样本都会被当作验证样本1 次,最终 1000 个样本都能生成元特征,且每个样本都参与过 90% 数据的基模型训练,数据利用率 100%。
    2. 过拟合风险的本质

            Blending 的验证子集是固定的,如果验证子集的分布和整体训练集有偏差,元学习器学到的规律就会偏离真实分布;而 Stacking 的 K 折 CV 相当于用多个不同的验证子集生成元特征,平均了这种偏差,过拟合风险更低。

            接下来,我会更一些关于机器学习前沿的算法,可能写的不是很好,请大家多多见谅!

    赞(0)
    未经允许不得转载:171主机测评 » 堆叠学习————Blending算法
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址