关于决策树集成的一份介绍
在这片文章中我将介绍决策树集成有关的东西,会主要分为两部分去讲,一部分是随机森林,另一部分是梯度提升决策树。
一、 集成学习
集成学习(Ensemble Learning)是构造多个学习器来完成学习任务的方法。
在这个过程中,一般先生成一些个体学习器,然后通过某种策略将他们结合。其中的个体学习器一般是由现有的学习算法从训练数据中 生成,如C4.5决策树、BP神经网络等。过程中,如果用全为同一种类型的个体学习器去集成,那么这样的集成就是“同质”的,如随机森林,神经网络集成等。反之则是“异质”。其中,同质的集成中的个体学习器可以称之为“基学习器”,而若是异质的话,则不如此称呼,而称为“组件学习器”,或直接就叫个体学习器。
在集成学习中,如果通过串行地生成个体学习器,并且后一个学习器专注于纠正前一个学习器的错误,那么可以使用Boosting方法,而在Boosting方法中最具代表的算法就是AdaBoost算法,它可以用于解决二分类问题;而如果是并行生成个体学习器,个体学习器间也并不存在较强的依赖关系,那么就可以使用Bagging方法,或随机森林算法等,而Bagging算法则不像Boosting算法族中的AdaBoost算法那样不能直接用于多分类或回归任务。
二、 随机森林
我们知道,决策树的一大缺点就是它容易出现过拟合的问题,那么决策树就是解决这个问题的一个好方法。因为在随机森林中,每棵树都会对数据做出较好的预测,但也都会出现过拟合的问题,所以当我么构造许多棵决策树后,它们都能很好做出预测并都以不同方式发生过拟合,那么我们就可以将这些树的结果取均值,以此来降低过拟合。
在随机森林中,每棵树的随机化的方法有两种,一种是在数据点上进行随机,一种是在特征上随机。
2.1 构造
在我们构造随机森林的过程中,首先要对数据进行自助采样,也就是说会对有n个数据点有放回的重复随机选取一个样本,共n次。比如有['a','b','c','d'],我们对其进行自主采样,可能会得到一份采样入这样:['a','b','b','d']。如此,就是随机化方法的第一种,在数据点上随机。
接下来,我们将基于这个新创建的数据集来构造决策树。我们会在每个节点处,用算法随机选择特征的一个子集,并对其中一个特征寻找最佳测试。并且每个节点的特征子集的寻找是相互独立的。其中选择的特征个数由max_features参数来控制。那么,这个参数就十分重要了,如果它较大,那么随机森林的树将会十分相似,如果较小,那么树的差异会很大,而为了很好拟合数据,每棵树的深度就会变得很大。
2.2 代码实现
在这里,我用iris数据集的预测作为例子来展示下直接调用sklearn函数库去实现随机森林的python代码:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
iris = load_iris()
X = iris.data
y = iris.target
# 划分
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# 实例化
clf = RandomForestClassifier(n_estimators=100, random_state=42)
# 拟合
clf.fit(X_train,y_train)
# 预测
y_pre = clf.predict(X_test)
# 计算
accuracy = accuracy_score(y_test, y_pre)
print("The accuracy is: {}".format(accuracy))
report = classification_report(y_test, y_pre)
print("The report of clf is: {}".format(report))
结果如下:
The accuracy is: 1.0
The report of clf is: precision recall f1-score support
0 1.00 1.00 1.00 15
1 1.00 1.00 1.00 11
2 1.00 1.00 1.00 12
accuracy 1.00 38
macro avg 1.00 1.00 1.00 38
weighted avg 1.00 1.00 1.00 38
三、 梯度提升决策树
梯度提升决策树(梯度提升机)既可以用于分类亦可以用于回归,当用于回归时,则可以将之称为梯度提升回归树。它与随机森林一样都是依靠决策树的集成,但不同的是,GBDT(梯度提升决策树)采用连续的方式构造树,每棵树都去试图纠正上一棵树的错误。在默认的情况下,它没有随机化,而是采用了强预剪枝。
在我之前所说的串行生成个体学习器时有提到的Boosting算法,而其实GBDT算法就是Boosting算法的进一步完善所得。
3.1 主要思想
GBDT的主要思想是合并许多的简单模型,它们也在这里可以叫作弱学习器(弱学习器是指一种能够从训练数据中学习到某些规则,但其性能略优于随机猜测的学习器)。每棵树都可以对部分树做出最好的预测,所以当添加的树渐渐变多时,整体的性能也可以得到提升。就像随机森林中的max_features一样,GBDT中也存在一个重要的参数,就是:learning_rate(学习率),它用于控制每棵树纠正前一棵树的错误强度,所以较高的学习率就意味着较强的修正。
3.2 代码实现
代码实现如下:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score, classification_report
iris = load_iris()
X = iris.data
y = iris.target
# 划分
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# 实例化
clf = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)
# 拟合
clf.fit(X_train,y_train)
# 预测
y_pre = clf.predict(X_test)
# 计算
accuracy = accuracy_score(y_test, y_pre)
print("The accuracy is: {}".format(accuracy))
report = classification_report(y_test, y_pre)
print("The report of clf is: {}".format(report))
从中,我们不难发现它与随机森林的代码除了函数的名称不同外,还多了两个参数,分别是learning_rate与max_depth,这两个参数分别是算法迭代的步长与树的最大深度。
如下是它的输出结果:
The accuracy is: 1.0
The report of clf is: precision recall f1-score support
0 1.00 1.00 1.00 15
1 1.00 1.00 1.00 11
2 1.00 1.00 1.00 12
accuracy 1.00 38
macro avg 1.00 1.00 1.00 38
weighted avg 1.00 1.00 1.00 38
四、 结合
当我生成好目标个数的个体学习器并预测后就需要“结合”,所以,结合就是将基学习器的结果整合在一起的过程。
学习器的结合可以带来三个方面的好处,第一,若是使用单个学习器那么有可能会因为误选而导致泛化性能的不佳,但结合后就就可以在一定程度上减少这个风险;第二,结合可以降低陷入糟糕局部点的风险;第三,结合可以将假设空间增大,而得到更好的近似。
其中关于结合的常见方法有三种,投票,平均以及加权平均。此外,还有其他一些结合方法,如Stacking等。而对于投票又可以分为两种,分别是“硬投票”与“软投票”。
有时,如果训练数据有很多,那么就有种更强大的结合策略,就是“学习法”,即通过另一个额外的学习器来结合。上述的Stacking就是它的典型代表。在这里,我们将个体学习器称为初级学习器,用于结合的学习器则称为次级学习器或元学习器。
此上