手记

掌握Python 机器学习 (性能提升)

摘要: 摘要:本章是在以前章节基本的算法之后, 介绍了一些提升算法:boosting, bagging, voting。 这些算法可以提高算法 的精确性。 以下是详细内容。

如何使用集成方法来提高性能

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 DecisionTreeClassifier
filename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = 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 RandomForestClassifier
filename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = 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 ExtraTreesClassifier
filename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = 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 AdaBoostClassifier
filename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = 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 GradientBoostingClassifier
filename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = 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 VotingClassifier
filename = 'pima-indians-diabetes.data.csv'names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = 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

作者:zzbb

来源:https://my.oschina.net/sizhe/blog/1592530


1人推荐
随时随地看视频
慕课网APP