什么是集成学习
在传统的机器学习任务中,我们的目的往往是得出一个和实际情况相符的模型。例如,分类任务中,我们想要得出的结果就是可以获取一个无论输入是什么都可以输出正确分类的分类模型。但是事实上,得到这样的模型是非常困难的。通常情况下,我们得到的模型只能是较好的。
而集成学习就是组合这些这些较好的模型,以期达到更好的效果。
投票法
在现实生活中,在很多人意见不统一的时候,我们最常用的方法就是少数服从多数。这就是非常简单的投票法。
例如,在一个二选题目中,5个同学选了A,A,B,A,B。根据少数服从多数的理论我们可以很简单的得出结论这题选A。
这就是最简单的硬投票方法,并不考虑其他的影响。我们在实际的学习任务中,还可以不仅仅简单的使用一个模型一票的方法进行投票。我们可以把每个模型的预测结果都叠加在一起,这样最大的结果就是我们最后的结果。这就是软投票法。
但是,在实际生活我,我们还听过这么一句话,真理往往掌握在少数人手中。这告诉我们多数说的有时候并不一定是对的。我们可以考虑这么一个极端的环境:
还是那个双选题,这次又三个年级倒数选择了A,但是一个数学老师选了B,还有一个世界知名的数学家也选择了B。这种情况下,我们可以很容易的得出结论,这题选C。
我们可以看出,影响最终结果的并不只是结果个数的多少。有时我们还要考虑不同模型的影响。
个人理解: 在实际的操作中,我们还可以通过计算不同模型在验证集上的准确率,来对每个模型分配不同的权重。这样在软投票的基础上再进一步,考虑了模型本身的权威性,可以进一步的提升投票法的鲁棒性。
案例操作
sklearn函数介绍
sklearn.ensemble.VotingClassifier()
VotingClassifier(
estimators, # 需要比较的model序列
*,
voting='hard', # 投票的模式,分为hard和soft
weights=None, # 针对soft模式,可以为不同的模型添加权重
n_jobs=None, # 并行运行的数量,我的理解使用CPU的核心数
flatten_transform=True, # 控制soft的输出形状
verbose=False
)
sklearn.ensemble.VotingRegressor()
VotingRegressor(
estimators,
*,
weights=None,
n_jobs=None,
verbose=False
) # 与分类投票不同,不需要选择方式
实际代码
from sklearn.ensemble import VotingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import make_classification
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
# 测试分类任务
# 生成数据集
def get_dataset():
X, y = make_classification(
n_samples=1000, # 样本数量
n_features=20, # 特征数量
n_informative=15, # 多信息特征的个数
n_redundant=5, # 冗余信息
random_state=2, # 个人理解为随机种子,是否可以复现
n_classes=2, # 类别数量
)
return X, y
# 制作一个投票投票
# svm, 决策树, KNN(1, 3)
def vote_model():
model = list()
model.append(('knn1', KNeighborsClassifier(n_neighbors=1)))
model.append(('knn3', KNeighborsClassifier(n_neighbors=3)))
model.append(('svm', make_pipeline(StandardScaler(), SVC(probability=True))))
model.append(('DecisionTree', DecisionTreeClassifier()))
ensemble = VotingClassifier(
estimators=model,
voting='soft' # 软投票
)
return ensemble
def get_models():
models = dict()
models['knn1'] = KNeighborsClassifier(n_neighbors=1)
models['knn3'] = KNeighborsClassifier(n_neighbors=3)
models['svm'] = SVC()
models['DecisionTree'] = DecisionTreeClassifier()
models['vote'] = vote_model()
return models
def evaluate_model(model, X, y):
cv = RepeatedStratifiedKFold(
n_splits=10, # 划分成多少份
n_repeats=3, # 重复次数
random_state=1 # 随机种子
)
score = cross_val_score(
model,
X,
y,
scoring='accuracy', # 评价标准
cv=cv,
n_jobs=-1,
error_score='raise'
)
return score
if __name__ == '__main__':
X, y = get_dataset()
models = get_models()
for name, model in models.items():
score = evaluate_model(model, X, y)
print("%s: %.3f(%.3f)" % (name, np.mean(score), np.std(score)))
结果:
knn1: 0.873(0.030)
knn3: 0.889(0.038)
svm: 0.926(0.029)
DecisionTree: 0.775(0.041)
vote: 0.918(0.024)