集成学习(ensemble-learning)-(一)

  • 类似,生病了找多名专家从不同方面一起确诊。
  • 集成学习将多个学习器进行结合,通常可以获得比单一的学习器更优的泛化性能。
  • 集成学习可以得带3中不同结果:提升性能,不起作用,起负作用。
  • 所以要想获得好的集成结果,每个学习器应该“好而不同”,即每个学习器要有一定的准确性,同时,每个学习器各不相同。即“多样性”。
  • 实际上,如何产生“好而不同”的基学习器,是集成学习的核心。

构建

使用数据集:

1
x, y = datasets.make_moons(n_samples=500, noise=0.2, random_state=321)

构建三个基学习器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#1) 使用逻辑回归
from sklearn.linear_model import LogisticRegression
log = LogisticRegression()
log.fit(x_train, y_train)
print(log.score(x_test, y_test)) # 0.896

#2) 使用SVM
from sklearn.svm import SVC
svm = SVC()
svm.fit(x_train, y_train)
print(svm.score(x_test, y_test)) # 0.952

#3) 使用决策树分类
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier()
tree.fit(x_train, y_train)
print(tree.score(x_test, y_test)) # 0.944

结果分别为 0.896, 0.952, 0.944.

投票操作:

1
2
3
4
5
6
7
8
9
10
11
12
# voting
y_pre1 = log.predict(x_test)
y_pre2 = svm.predict(x_test)
y_pre3 = tree.predict(x_test)

# 少数服从多数
# 对于三个模型的预测值,至少2个模型判断它为1,我才认为它是1:
y_p = np.asarray((y_pre1 + y_pre2 + y_pre3) >= 2, dtype=int)
print(y_pre1[:10]) # [1 1 1 1 1 0 1 0 0 0]
print(y_pre2[:10]) # [1 1 1 1 1 0 1 0 0 1]
print(y_pre3[:10]) # [1 1 1 1 1 0 1 0 0 1]
print(y_p[:10]) # [1 1 1 1 1 0 1 0 0 1]

判断集成效果:

1
2
3
from sklearn.metrics import accuracy_score
acc = accuracy_score(y_test, y_p)
print(acc) # 0.96

最终集成性能是0.96。

Hard voting

hard voting 即少数服从多数:

1
2
3
4
5
6
7
8
9
10
from sklearn.ensemble import VotingClassifier

voting = VotingClassifier(estimators=[
('log', LogisticRegression()),
('svm', SVC()),
('tree', DecisionTreeClassifier())
], voting='hard')

voting.fit(x_train, y_train)
print(voting.score(x_test, y_test)) # 0.96

实际中,通常把基学习器调参到最优,后再集成

Soft voting

hard voting 其实是“少数服从多数”,而 soft voting 带权投票,如歌唱的专业评审团的投票权重就大。如:

5个学习器把同一个样本分为A类或B类的概率分别如下:

            A类    B类
学习器#0   99.0%  1.0%
学习器#1   49.0%  51.0%
学习器#2   43.0%  57.0%
学习器#3   98.0%  2.0%
学习器#4   34.0%  64.0%

如果使用hard voting 该样本最终本分为B类。

但是,显然学习器#0#3有很大的把握认为该样本属于A类,而其他三个学习器并没有很确定该样本的类别。所以“少数服从多数”不合适。使用Soft voting 计算
属于A类:(99.0%+49.0%+43.0%+98.0%+34.0%) / 5 = 64.6%.
属于B类:(1.0%+51.0%+57.0%+2.0%+64.0%) / 5 = 35.0%.
所以该样本应该被分类为A。

使用 Soft voting 的基学习器要求都应该估计概率,即可以调用 predict_proba 函数。SVM模型把probability设为true,便可以进行概率估计。调用VotingClassifier时指明voting方式为soft即可:

1
2
3
4
5
6
7
8
9
from sklearn.ensemble import VotingClassifier
voting2 = VotingClassifier(estimators=[
('log', LogisticRegression()),
('svm', SVC(probability=True)),
('tree', DecisionTreeClassifier())
], voting='soft')

voting2.fit(x_train, y_train)
print(voting2.score(x_test, y_test)) # 0.976

所以,当基学习器可以求出样本概率估计时,Soft voting 比 hard voting 性能优。

敲黑板理解当前问题,才能找到已有方法的不足,才能找到更合适的方法。就如本文表达的用Soft voting 替代已有的Hard voting。