提升算法

提升算法的核心不再是投票,而是迭代.通过一轮一轮的优化权重来做到提升准确率的作用

提升算法(Boosting)虽然表面上看也是对训练数据的扰动(重采样/权值调整),但是Boosting的理论保证了其本质上是一个优化算法.集成分类器整体具有一个优化目标,即Boosting的训练过程最终可以使集成分类器收敛到最优贝叶斯决策,因此降低了bias(提高了准确度),而这个性质是Bagging不具有的.

常见的提升算法就是

  • AdaBoost
  • GradientBoosting

AdaBoost

AdaBoost的核心思想是用反复修改的数据的权重来训练一系列的弱学习器,由这些弱学习器的预测结果通过加权投票(或加权求和)的方式组合,得到我们最终的预测结果.在每一次所谓的提升迭代中,数据的修改由应用于每一个训练样本的新权重$w_1$,$w_2$,…,$w_N$组成(即修改每一个训练样本应用于新一轮学习器的权重). 初始化时,将所有弱学习器的权重都设置为$w_i = 1/N$,因此第一次迭代仅仅是通过原始数据训练出一个弱学习器.在接下来的连续迭代中,样本的权重逐个地被修改,学习算法也因此要重新应用这些已经修改的权重.在给定的一个迭代中,那些在上一轮迭代中被预测为错误结果的样本的权重将会被增加,而那些被预测为正确结果的样本的权重将会被降低.随着迭代次数的增加,那些难以预测的样例的影响将会越来越大,每一个随后的弱学习器都将会被强迫更加关注那些在之前被错误预测的样例.

AdaBoost在sklearn中的接口

sklearn中提供了俩个adaboost相关的接口:

  • ensemble.AdaBoostClassifier([…])adaboost 分类器
  • ensemble.AdaBoostRegressor([base_estimator, …])adaboost 回归器

参数方面

  • base_estimator指定弱学习器,默认是cart tree,

  • n_estimators弱学习器的数量

  • learning_rate控制每个弱学习器对最终的结果的贡献程度(权重修改速率)

获取一个好的预测结果主要需要调整的参数是n_estimatorsbase_estimator的复杂度(例如:对于弱学习器为决策树的情况,树的深度max_depth 或叶子节点的最小样本数min_samples_leaf等都是控制树的复杂度的参数)


In [2]:
import requests
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder,StandardScaler
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import classification_report
from sklearn.ensemble import AdaBoostClassifier

数据预处理


In [3]:
csv_content = requests.get("http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data").text
row_name = ['sepal_length','sepal_width','petal_length','petal_width','label']
csv_list = csv_content.strip().split("\n")
row_matrix = [line.strip().split(",") for line in csv_list]
dataset = pd.DataFrame(row_matrix,columns=row_name)

encs = {}
encs["feature"] = StandardScaler()
encs["feature"].fit(dataset[row_name[:-1]])
table = pd.DataFrame(encs["feature"].transform(dataset[row_name[:-1]]),columns=row_name[:-1])

encs["label"]=LabelEncoder()
encs["label"].fit(dataset["label"])
table["label"] = encs["label"].transform(dataset["label"])

In [4]:
table[:10]


Out[4]:
sepal_length sepal_width petal_length petal_width label
0 -0.900681 1.032057 -1.341272 -1.312977 0
1 -1.143017 -0.124958 -1.341272 -1.312977 0
2 -1.385353 0.337848 -1.398138 -1.312977 0
3 -1.506521 0.106445 -1.284407 -1.312977 0
4 -1.021849 1.263460 -1.341272 -1.312977 0
5 -0.537178 1.957669 -1.170675 -1.050031 0
6 -1.506521 0.800654 -1.341272 -1.181504 0
7 -1.021849 0.800654 -1.284407 -1.312977 0
8 -1.748856 -0.356361 -1.341272 -1.312977 0
9 -1.143017 0.106445 -1.284407 -1.444450 0

数据集拆分


In [5]:
train_set,validation_set = train_test_split(table)

训练模型


In [6]:
ab= AdaBoostClassifier(n_estimators=100)

In [7]:
ab.fit(train_set[row_name[:-1]], train_set["label"])


Out[7]:
AdaBoostClassifier(algorithm='SAMME.R', base_estimator=None,
          learning_rate=1.0, n_estimators=100, random_state=None)

In [8]:
pre = ab.predict(validation_set[row_name[:-1]])

In [9]:
print(classification_report(validation_set["label"],pre))


             precision    recall  f1-score   support

          0       1.00      1.00      1.00        18
          1       0.85      0.92      0.88        12
          2       0.86      0.75      0.80         8

avg / total       0.92      0.92      0.92        38

梯度提升(Gradient Boosting)

梯度提升算法和adaboost类似,但有几个区别:

  • adaboost对于每个样本有一个权重,样本预估误差越大,权重越大
  • gradient boosting则是直接用梯度拟合残差,没有样本权重的概念

Gradient Boosting在sklearn中的接口

sklearn中提供了俩个梯度提升相关的接口:

  • ensemble.GradientBoostingClassifier([loss, …]) 梯度提升分类器
  • ensemble.GradientBoostingRegressor([loss, …]) 梯度提升回归器

其参数用法和adaboost的接口类似,只是多了个loss参数用于设定使用什么作为损失函数,有两个可选的损失函数:

  • deviance指使用logistic作为损失函数,也是默认值
  • exponential就和adaboost一样了

In [10]:
from sklearn.ensemble import GradientBoostingClassifier

In [11]:
gb= GradientBoostingClassifier(n_estimators=100)
gb.fit(train_set[row_name[:-1]], train_set["label"])
pre = gb.predict(validation_set[row_name[:-1]])
print(classification_report(validation_set["label"],pre))


             precision    recall  f1-score   support

          0       1.00      1.00      1.00        18
          1       0.85      0.92      0.88        12
          2       0.86      0.75      0.80         8

avg / total       0.92      0.92      0.92        38

xgboost

xgboost算法比较复杂,针对传统GBDT算法做了很多细节改进,包括损失函数,正则化,切分点查找算法优化,稀疏感知算法,并行化算法设计等等.

相关文献资料:

这个方法不是sklearn中的算法,要使用它需要安装额外的包,如果是linux或者osx,那么可以使用pip直接安装,如果是windows可以去这个网址下载其动态链接库后使用git安装.

其接口和sklearn的风格一致,此处就不做更多介绍了