如何使用集成方法来提高性能
15.1 如何综合各种模型来提高预测的性能
能否根据一个弱分类器来构建一个强分类器。 什么时候集成的效果就会好于单个学习器
这里介绍了三种流行的提升算法
- bagging, 打包。 从不同的子集里面来提炼多个模型,然后综合。随机森林:个体之间不存在强依赖关系,可并行生成。
- Boosting, 提升。 用一系列的模型, 后面的模型来可以利用上一个模型的优缺点, 这样对效果不好的部分可以进行有效的提升。 个体学习器间存在强依赖关系,必须串行生成。
- Voting 投票。 用不同的模型和简单的统计方式来综合。 比如说求个平均等等。 之前自己其实对bagging和voting理解以为是一样的, 这样看起来是不同的, 不过bagging 用的更多一些, 比如随机森林。 bagging boosting 一般都是一样的模型, 没有必要在这个地方增加复杂度。 而voting一般是多种模型。
15.2 打包算法
Bootstrap Aggregation 或者说bagging, 就是说从你的训练集中(是可以放回的)取出很多不同的样本集合, 对于每个集合训练出不同的模型。 然后根据每次的结果得到最终的预测结果。 三种算法如下:
- Bagged Decision Trees 打包决策树
- Random Forest 随机森林
- Extra Trees 多余树 (翻译的怪怪的 :))
15.2.1 Bagged Decision Trees 打包决策树
直接对决策树来进行bagging。 - 一个流行的例子就是使用没有剪枝的决策树
- 打包算法对于高方差的特征表现的比较好。
- 什么叫方差: 就是和期望差值的平方和。
- 理解后剪枝: 决策树构造完成后进行剪枝。剪枝的过程是对拥有同样父节点的一组节点进行检查,判断如果将其合并,熵的增加量是否小于某一阈值。如果确实小,则这一组节点可以合并一个节点,其中包含了所有可能的结果。后剪枝是目前最普遍的做法。
# Bagged Decision Trees for Classificationfrom pandas import read_csvfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.ensemble import BaggingClassifierfrom sklearn.tree import DecisionTreeClassifierfilename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']dataframe = read_csv(filename, names=names)array = dataframe.valuesX = array[:,0:8]Y = array[:,8]seed = 7kfold = KFold(n_splits=10, random_state=seed)cart = DecisionTreeClassifier()num_trees = 100model = BaggingClassifier(base_estimator=cart, n_estimators=num_trees, random_state=seed)results = cross_val_score(model, X, Y, cv=kfold)print(results.mean())# 0.770745044429
可以看出BaggingClassier 基本的算法是DecisionTreeClassifier, 100 棵树。 结果看起来还不错, 等会结合后面一起看。
15.2.2 随机森林
这个算法名字听的很多, 随机森林是bagging 决策树的扩展。 训练数据集是有返回的取出,但是树构造的时候要减少不同分类器之间的相关性。 特别的, 在构造每棵树的时候不是贪婪的选择最好的样本点, 而是随机选择一个分类的特征。
# Random Forest Classificationfrom pandas import read_csvfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.ensemble import RandomForestClassifierfilename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']dataframe = read_csv(filename, names=names)array = dataframe.valuesX = array[:,0:8]Y = array[:,8]num_trees = 100max_features = 3kfold = KFold(n_splits=10, random_state=7)model = RandomForestClassifier(n_estimators=num_trees, max_features=max_features)results = cross_val_score(model, X, Y, cv=kfold)print(results.mean())# 0.770727956254
其实一般使用随机森林较多。 随机森林作为一个可以高度并行化的算法,在大数据时候大有可为。
RF的主要优点有:
- 训练可以高度并行化,对于大数据时代的大样本训练速度有优势。个人觉得这是的最主要的优点。
- 由于可以随机选择决策树节点划分特征,这样在样本特征维度很高的时候,仍然能高效的训练模型。
- 在训练后,可以给出各个特征对于输出的重要性
- 由于采用了随机采样,训练出的模型的方差小,泛化能力强。
- 相对于Boosting系列的Adaboost和GBDT, RF实现比较简单。
- 对部分特征缺失不敏感。
RF的主要缺点有:
- 在某些噪音比较大的样本集上,RF模型容易陷入过拟合。
- 取值划分比较多的特征容易对RF的决策产生更大的影响,从而影响拟合的模型的效果。
15.2.3 extra tree
extra trees是RF的一个变种, 原理几乎和RF一模一样,仅有区别有:
- 对于每个决策树的训练集,RF采用的是随机采样bootstrap来选择采样集作为每个决策树的训练集,而extra trees一般不采用随机采样,即每个决策树采用原始训练集。
- 在选定了划分特征后,RF的决策树会基于信息增益,基尼系数,均方差之类的原则,选择一个最优的特征值划分点,这和传统的决策树相同。但是extra trees比较的激进,他会随机的选择一个特征值来划分决策树。
- 从第二点可以看出,由于随机选择了特征值的划分点位,而不是最优点位,这样会导致生成的决策树的规模一般会大于RF所生成的决策树。也就是说,模型的方差相对于RF进一步减少,但是偏倚相对于RF进一步增大。在某些时候,extra trees的泛化能力比RF更好。
# Extra Trees Classificationfrom pandas import read_csvfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.ensemble import ExtraTreesClassifierfilename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']dataframe = read_csv(filename, names=names)array = dataframe.valuesX = array[:,0:8]Y = array[:,8]num_trees = 100max_features = 7kfold = KFold(n_splits=10, random_state=7)model = ExtraTreesClassifier(n_estimators=num_trees, max_features=max_features)results = cross_val_score(model, X, Y, cv=kfold)print(results.mean())# 0.760269993165
15.3 boosting 算法 提升算法
boosting 就是说前一个基本分类器错的样本会得到增强,加权后的全体样本会被用来训练下一个基本分类器。当各个训练得到的弱分类组合成为强分类器。 每个弱分类器的训练过程结束后, 加大分类误差率小的弱分类的权重。
提升算法是通过一系列算法来实现的。 后面的算法会对前面的算法的错误进行弥补, 这样结果的准确性就会一步步提高。 主要以下两种算法:
- Adaboost
- Stochastic Gradient Boosting. -
15.3.1 Adaboost
Adaboost 是第一种成功的boosting 算法。
# AdaBoost Classificationfrom pandas import read_csvfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.ensemble import AdaBoostClassifierfilename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']dataframe = read_csv(filename, names=names)array = dataframe.valuesX = array[:,0:8]Y = array[:,8]num_trees = 30seed=7kfold = KFold(n_splits=10, random_state=seed)model = AdaBoostClassifier(n_estimators=num_trees, random_state=seed)results = cross_val_score(model, X, Y, cv=kfold)print(results.mean())# 0.76045796309
15.3.2 Stochastic Gradient Boosting
这种算法是目前效果最好的一种集成算法。
# Stochastic Gradient Boosting Classificationfrom pandas import read_csvfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.ensemble import GradientBoostingClassifierfilename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']dataframe = read_csv(filename, names=names)array = dataframe.valuesX = array[:,0:8]Y = array[:,8]seed = 7num_trees = 100kfold = KFold(n_splits=10, random_state=seed)model = GradientBoostingClassifier(n_estimators=num_trees, random_state=seed)results = cross_val_score(model, X, Y, cv=kfold)print(results.mean())# 0.764285714286
15.4 投票集成
这里的投票是一种从现在不同机器学习算法中集成的最简单的办法。 首先从你的数据集中去构造不同独立的模型。 然后你就可以根据不同的模型进行平均中和得到一种预测的方法。 你可以在不同的算法中加权, 但是怎么加还是很困难的。 下面的例子合并了逻辑回归, 回归树, SVM 等在一个分类问题。
# Voting Ensemble for Classificationfrom pandas import read_csvfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.linear_model import LogisticRegressionfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.svm import SVCfrom sklearn.ensemble import VotingClassifierfilename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']dataframe = read_csv(filename, names=names)array = dataframe.valuesX = array[:,0:8]Y = array[:,8]kfold = KFold(n_splits=10, random_state=7)# create the sub modelsestimators = []model1 = LogisticRegression()estimators.append(('logistic', model1))model2 = DecisionTreeClassifier()estimators.append(('cart', model2))model3 = SVC()estimators.append(('svm', model3))# create the ensemble modelensemble = VotingClassifier(estimators)results = cross_val_score(ensemble, X, Y, cv=kfold)print(results.mean())# 0.729049897471
15.5 小结
本章中我们学习了不同的集成学习算法来提供性能。
- Bagging
- Boosting
- Voting
Refer or 扩展
- 剪枝
- 随机森林