在决策树中,一棵树得出的结果往往拟合度不够好。所以引入了集成学习。集成学习(Ensemble learning)是用多种学习方法的组合来获取比原方法更优的结果。
用于组合的算法是弱学习算法,即分类正确率仅比随机猜测略高的学习算法,但是组合之后的效果仍可能高于强学习算法,即集成之后的算法准确率和效率都很高。
装袋法又称Bootstrap Aggregating,其原理是通过组合多个训练集的分类结果来提升分类效果。
比如在n个样本的数据集中,不是检验一次,而是多次抽样,比如抽取m次,每次从n个样本中有放回的抽取70%的样本进行训练。在大量样本中,每次从样本中随机抽取70%的样本几乎都不相同,那么我们就可以做出多棵树来。之后将新样本带入到各棵树中,得出分类结果,取分类中较多的类即为结果。
装袋法由于多次采样,每个样本被选中的概率相同,因此噪声数据的影响下降,所以袋装法太容易受到过拟合的影响。
使用sklearn库实现的决策树袋装法提升分类效果。其中X和Y分别是鸢尾花(iris)数据集中的自变量(花的特征)和因变量(花的类别)。
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
# 加载iris数据
iris = datasets.load_iris()
X = iris.data
Y = iris.target
# 分类器及交叉验证
seed = 42
kfold = KFold(n_splits=10, random_state=seed, shuffle=True) # n_splits=10表示进行10折交叉校验
cart = DecisionTreeClassifier(criterion="gini", max_depth=2)
cart = cart.fit(X, Y)
result = cross_val_score(cart, X, Y, cv=kfold)
print("CART结果:", result.mean())
model = BaggingClassifier(base_estimator=cart, n_estimators=100, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
print("袋装法提升后结果:", result.mean())
可以看到装袋法对模型结果有一定提升。当然,提升程度与原模型的结构和数据质量有关。如果分类回归树的树高度设置为3或5,原算法本身的效果就会比较好,装袋法就没有提升空间。
提升法与装袋法相比每次的训练样本均为同一组,并且引入了权重的概念,给每个单独的训练样本都会分配个相同的初始权值。然后进行T轮训练,每一轮中使用一个分类方法训练出一个分类模型,使用此分类模型对所有样本进行分类并更新所有样本的权重;分类正确的样本权重降低,分类错误的样本权重增加,从而达到更改样本分布的目的。由此可知,每一轮训练后,都会生成一个分类模型,而每次生成的这个分类模型都会更加注意在之前分类错误的样本,从而提高样本分类准确率。对于新的样本,将T轮训练出的T个分类模型得出的预测结果加权平均,即可得出最终的预测结果
基于sklearn库中的提升法分类器对决策树进行优化,提高分类准确率。python代码如下,其中load_breast_cancer()方法加载乳腺癌数据集,自变量(细胞核特征)和因变量(良性、恶性)分别赋给X和Y变量。
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
cancer = datasets.load_breast_cancer()
X = cancer.data
Y = cancer.target
seed = 42
kflod = KFold(n_splits=10, random_state=seed, shuffle=True)
dtree = DecisionTreeClassifier(criterion="gini", max_depth=2)
dtree = dtree.fit(X, Y)
result = cross_val_score(dtree, X, Y, cv=kflod)
print("决策树结果:", result.mean())
model = AdaBoostClassifier(base_estimator=dtree, n_estimators=100, random_state=seed)
result = cross_val_score(model, X, Y, cv=kflod)
print("提升法改进结果:", result.mean())
# 运行结果
决策树结果: 0.9208646616541353
提升法改进结果: 0.9701127819548871
可以看到提升法对当前决策树分类器的分类效果改进较大。
随机森林是专为决策树分类器设计的集成方式,是袋装法的一种扩展。随机森林与袋装法采取相同的样本抽取方式。袋装法中的决策树每次从所有属性中选择一个最优的属性作为其分支属性,而随机森林算法每次从所有属性中随机抽取t个属性,然后从t个属性中选取一个最优的属性作为其分支属性,这样就使得整个模型的随机性更强,从而使模型的泛化能力更强。而对于参数t的选取,决定了模型的随机性,若样本属性共有M个,t=1意味着随机选择一个属性来作为分支属性,t=属性总数时就变成了袋装法集成方式,通常t的取值为小于log2(M+1)的最大整数。而随机森林算法使用的弱分类决策树通常为CART算法。