漫昵 發表於 2025-5-16 10:09:00

同样的数据,更强的效果:如何让模型学会‘互补思维’?

<p><strong>集成学习</strong>虽然能够通过组合多个学习器来提高预测性能,然而,如果这些学习器过于相似,集成的效果可能并不理想。</p>
<p>因此,增强学习器的<strong>多样性</strong>是提升<strong>集成学习</strong>性能的关键。</p>
<p><strong>多样性</strong>带来的优势在于:</p>
<ul>
<li><strong>群体智慧原理</strong>:多样化的模型可以从不同角度捕捉数据规律</li>
<li><strong>误差互补效应</strong>:不同模型的错误模式不同,投票后误差相互抵消</li>
<li><strong>防止过拟合</strong>:多样性能降低模型之间的相关性,增强泛化能力</li>
</ul>
<p>本文将介绍<strong>4种</strong>增强学习器多样性的方法,并通过代码示例展示如何在实践中应用这些方法。</p>
<h1 id="1-数据样本扰动">1. 数据样本扰动</h1>
<p><strong>数据样本扰动</strong>是最常见的增强多样性的方法之一。</p>
<p>它的<strong>核心思想</strong>是通过对训练数据的不同子集进行采样,使得每个学习器在不同的数据上进行训练,从而产生差异化的模型。</p>
<p>在<strong>数据样本扰动</strong>中,最常用的方法是<strong>自助采样</strong>(<code>Bootstrap Sampling</code>)。</p>
<p><strong>自助采样</strong>是从原始数据集中有放回地抽取样本,这样每个学习器看到的数据集略有不同,从而增加了多样性。</p>
<p>实现<strong>数据样本扰动</strong>的代码示例如下:</p>
<p>首先创建一些随机的模拟数据。</p>
<pre><code class="language-python">import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier, RandomForestClassifier, VotingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# 设置随机种子保证可复现性
np.random.seed(42)

# ======================
# 数据准备
# ======================
# 生成模拟数据集(1000个样本,20个特征)
X, y = make_classification(
    n_samples=1000, n_features=20, n_informative=8, random_state=42# 设置8个有效特征
)

# 划分训练集/测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, stratify=y, random_state=42# 保持类别分布
)
</code></pre>
<p>然后实现<strong>数据样本扰动</strong>的代码:</p>
<pre><code class="language-python"># 方法1:数据样本扰动(Bagging)
bagging_model = BaggingClassifier(
    estimator=DecisionTreeClassifier(max_depth=3),
    n_estimators=10,
    max_samples=0.8,# 每次采样80%样本
    bootstrap=True,# 有放回采样
    random_state=42,
)
bagging_model.fit(X_train, y_train)
pred = bagging_model.predict(X_test)
base_acc = accuracy_score(y_test, pred)
print(f"【数据样本扰动 准确率】{base_acc:.4f}")

## 输出结果:
'''
【数据样本扰动 准确率】0.7133
'''
</code></pre>
<h1 id="2-输入属性扰动">2. 输入属性扰动</h1>
<p><strong>输入属性扰动</strong>是通过选择不同的特征子集来训练每个学习器,从而增加学习器之间的差异。</p>
<p>在每次训练学习器时,随机选择一部分特征,而不是使用完整的特征集。</p>
<p>这样,每个学习器只能看到部分特征,从而产生不同的模型。</p>
<p>实现<strong>输入属性扰动</strong>的代码示例如下:</p>
<pre><code class="language-python"># 方法2:输入属性扰动(随机子空间)
subspace_model = BaggingClassifier(
    estimator=DecisionTreeClassifier(max_depth=3),
    n_estimators=10,
    max_features=0.5,# 随机选择50%特征
    bootstrap_features=True,# 特征有放回采样
    random_state=42,
)
subspace_model.fit(X_train, y_train)
pred = subspace_model.predict(X_test)
base_acc = accuracy_score(y_test, pred)
print(f"【输入属性扰动 准确率】{base_acc:.4f}")

## 输出结果:
'''
【输入属性扰动 准确率】0.7300
'''
</code></pre>
<h1 id="3-输出表示扰动">3. 输出表示扰动</h1>
<p><strong>输出表示扰动</strong>是通过对目标变量进行扰动,例如,通过添加噪声或对目标变量进行随机化处理,来增加学习器之间的差异。</p>
<p>在训练过程中,对目标变量的值进行微小的调整,使得每个学习器学习到不同的目标分布。</p>
<p>实现<strong>输出表示扰动</strong>的代码示例如下:</p>
<pre><code class="language-python"># 方法3:输出表示扰动(随机翻转5%标签)
# 生成扰动标签
flip_mask = np.random.rand(len(y_train)) &lt; 0.05
y_flipped = y_train.copy()
y_flipped = 1 - y_flipped

# 使用扰动标签训练模型
label_flip_model = LogisticRegression(penalty="l2", C=1.0)
label_flip_model.fit(X_train, y_flipped)

label_flip_model.fit(X_train, y_train)
pred = label_flip_model.predict(X_test)
base_acc = accuracy_score(y_test, pred)
print(f"【输出表示扰动 准确率】{base_acc:.4f}")

## 输出结果:
'''
【输出表示扰动 准确率】0.6867
'''
</code></pre>
<h1 id="4-算法参数扰动">4. 算法参数扰动</h1>
<p><strong>算法参数扰动</strong>是通过为每个学习器设置不同的参数,使得学习器之间产生差异。</p>
<p>为每个学习器随机选择不同的参数,例如决策树的深度、学习率等,从而增加模型的多样性。</p>
<p>实现<strong>算法参数扰动</strong>的代码示例如下:</p>
<pre><code class="language-python"># 方法4:算法参数扰动
param_variation_model = RandomForestClassifier(
    n_estimators=10,
    max_depth=5,
    criterion="entropy",# 使用信息熵代替基尼系数
    max_features="sqrt",# 每棵树使用sqrt(n_features)个特征
    random_state=42,
)
param_variation_model.fit(X_train, y_train)
pred = param_variation_model.predict(X_test)
base_acc = accuracy_score(y_test, pred)
print(f"【算法参数扰动 准确率】{base_acc:.4f}")

## 输出结果:
'''
【算法参数扰动 准确率】0.7633
'''
</code></pre>
<h1 id="5-集成4种增强多样性的方法">5. 集成4种增强多样性的方法</h1>
<p>最后,我们再把上面<strong>4种</strong>增强多样性的方法集成一起使用,看看效果:</p>
<pre><code class="language-python"># ======================
# 构建集成模型
# ======================
ensemble = VotingClassifier(
    estimators=[
      ("bagging", bagging_model),
      ("subspace", subspace_model),
      ("label_flip", label_flip_model),
      ("param_tuned", param_variation_model),
    ],
    voting="soft",# 使用概率加权投票
)

# ======================
# 训练与评估
# ======================
# 训练集成模型
ensemble.fit(X_train, y_train)

# 预测测试集
y_pred = ensemble.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"【集成模型准确率】{accuracy:.4f}")

## 输出结果:
'''
【集成模型准确率】0.7500
'''
</code></pre>
<p>从结果来看,集成4种增强多样性的方法后,准确率与单独使用某一种增强多样性方法相比,</p>
<p>比其中三种要高,但是不如<strong>算法参数扰动</strong>高,这是正常的现象。</p>
<p>因为这里我们为了演示使用方法,只是简单的集成,没有做任何调优(比如权重设置等等)。</p>
<p>在实际场景中,会根据数据的情况调整集成方法,并且,如果某一种增强多样性方法效果很好,也没有必要非要集成4种一起使用,单独使用一种也可以的。</p>
<h1 id="6-总结">6. 总结</h1>
<p><strong>增强学习器多样性</strong>是提升集成学习性能的重要手段。通过<strong>数据样本扰动</strong>、<strong>输入属性扰动</strong>、<strong>输出表示扰动</strong>和<strong>算法参数扰动</strong>等方法,可以有效地增加学习器之间的差异,从而提高集成模型的性能。</p>
<p>在实际应用中,可以根据具体问题选择合适的方法或组合多种方法来进一步优化模型性能。</p>
<p>下面是一些实践建议,供参考:</p>
<ol>
<li><strong>组合使用多种方法</strong>(如同时使用数据扰动和参数扰动)</li>
<li><strong>控制扰动强度</strong>:过强的扰动会降低基学习器性能</li>
<li><strong>优先选择计算高效的方法</strong>:如参数扰动通常比数据扰动更快</li>
<li><strong>监控多样性指标</strong>:使用双样本误差或相关系数评估模型差异度</li>
</ol><br><br>
来源:https://www.cnblogs.com/wang_yb/p/18879563
頁: [1]
查看完整版本: 同样的数据,更强的效果:如何让模型学会‘互补思维’?