集成学习虽然能够通过组合多个学习器来提高预测性能,然而,如果这些学习器过于相似,集成的效果可能并不理想。
因此,增强学习器的多样性是提升集成学习性能的关键。
多样性带来的优势在于:
- 群体智慧原理:多样化的模型可以从不同角度捕捉数据规律误差互补效应:不同模型的错误模式不同,投票后误差相互抵消防止过拟合:多样性能降低模型之间的相关性,增强泛化能力
本文将介绍4种增强学习器多样性的方法,并通过代码示例展示如何在实践中应用这些方法。
1. 数据样本扰动
数据样本扰动是最常见的增强多样性的方法之一。
它的核心思想是通过对训练数据的不同子集进行采样,使得每个学习器在不同的数据上进行训练,从而产生差异化的模型。
在数据样本扰动中,最常用的方法是自助采样(Bootstrap Sampling
)。
自助采样是从原始数据集中有放回地抽取样本,这样每个学习器看到的数据集略有不同,从而增加了多样性。
实现数据样本扰动的代码示例如下:
首先创建一些随机的模拟数据。
import numpy as npfrom sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_splitfrom sklearn.ensemble import BaggingClassifier, RandomForestClassifier, VotingClassifierfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.linear_model import LogisticRegressionfrom 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 # 保持类别分布)
然后实现数据样本扰动的代码:
# 方法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'''
2. 输入属性扰动
输入属性扰动是通过选择不同的特征子集来训练每个学习器,从而增加学习器之间的差异。
在每次训练学习器时,随机选择一部分特征,而不是使用完整的特征集。
这样,每个学习器只能看到部分特征,从而产生不同的模型。
实现输入属性扰动的代码示例如下:
# 方法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'''
3. 输出表示扰动
输出表示扰动是通过对目标变量进行扰动,例如,通过添加噪声或对目标变量进行随机化处理,来增加学习器之间的差异。
在训练过程中,对目标变量的值进行微小的调整,使得每个学习器学习到不同的目标分布。
实现输出表示扰动的代码示例如下:
# 方法3:输出表示扰动(随机翻转5%标签)# 生成扰动标签flip_mask = np.random.rand(len(y_train)) < 0.05y_flipped = y_train.copy()y_flipped[flip_mask] = 1 - y_flipped[flip_mask]# 使用扰动标签训练模型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'''
4. 算法参数扰动
算法参数扰动是通过为每个学习器设置不同的参数,使得学习器之间产生差异。
为每个学习器随机选择不同的参数,例如决策树的深度、学习率等,从而增加模型的多样性。
实现算法参数扰动的代码示例如下:
# 方法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'''
5. 集成4种增强多样性的方法
最后,我们再把上面4种增强多样性的方法集成一起使用,看看效果:
# ======================# 构建集成模型# ======================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'''
从结果来看,集成4种增强多样性的方法后,准确率与单独使用某一种增强多样性方法相比,
比其中三种要高,但是不如算法参数扰动高,这是正常的现象。
因为这里我们为了演示使用方法,只是简单的集成,没有做任何调优(比如权重设置等等)。
在实际场景中,会根据数据的情况调整集成方法,并且,如果某一种增强多样性方法效果很好,也没有必要非要集成4种一起使用,单独使用一种也可以的。
6. 总结
增强学习器多样性是提升集成学习性能的重要手段。通过数据样本扰动、输入属性扰动、输出表示扰动和算法参数扰动等方法,可以有效地增加学习器之间的差异,从而提高集成模型的性能。
在实际应用中,可以根据具体问题选择合适的方法或组合多种方法来进一步优化模型性能。
下面是一些实践建议,供参考:
- 组合使用多种方法(如同时使用数据扰动和参数扰动)控制扰动强度:过强的扰动会降低基学习器性能优先选择计算高效的方法:如参数扰动通常比数据扰动更快监控多样性指标:使用双样本误差或相关系数评估模型差异度