机器学习之随机森林分类篇(RandomForestClassifier)

1,271 阅读6分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

一 随机森林简介

集成学习(ensemble learning)是时下非常流行的机器学习算法,它本身不是一个单独的机器学习算法,而是通 过在数据上构建多个模型,集成所有模型的建模结果。集成算法会考虑多个评估器的建模结果,汇总之后得到一个综合的结果,以此来获取比单个模型更好的回归或分类表现。多个模型集成成为的模型叫做集成评估器(ensemble estimator),组成集成评估器的每个模型都叫做基评估器 (base estimator)。通常来说,有三类集成算法:装袋法(Bagging),提升法(Boosting)和stacking。

image.png 装袋法的核心思想是构建多个相互独立的评估器,然后对其预测进行平均或多数表决原则来决定集成评估器的结 果。装袋法的代表模型就是随机森林。 提升法中,基评估器是相关的,是按顺序一一构建的。其核心思想是结合弱评估器的力量一次次对难以评估的样本 进行预测,从而构成一个强评估器。提升法的代表模型有Adaboost和梯度提升树。

二 重要参数

2.1 n_estimators

基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越 大,模型的效果往往越好。但是任何模型都有决策边界,n_estimators达到一定的程度之后,随机森林的 精确性往往不在上升或开始波动,而且n_estimators越大,需要的计算量和内存也越大,训练的时间也会越来越 长。对于这个参数,应在训练难度和模型效果之间取得平衡

2.2 RandomForestClassifier VS DecisionTreeClassifier

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine  #内置红酒数据集

wine=load_wine()
wine.data
wine.target

#同时使用随机森林和决策树进行结果比较
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(wine.data,wine.target,test_size=0.3)

clf=DecisionTreeClassifier(random_state=200)
rfc=RandomForestClassifier(random_state=200)
clf=clf.fit(x_train,y_train)
rfc=rfc.fit(x_train,y_train)
score_c=clf.score(x_test,y_test)
score_r=rfc.score(x_test,y_test)

print('Tree Score:{}'.format(score_c), ' \n'  'Random Forest Score:{}'.format(score_r))

image.png 随机森林结果高于决策树结果

2.3 再次使用交叉验证进行比较(cross_val_score)

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

rfc=RandomForestClassifier(n_estimators=30)
rfc_s=cross_val_score(rfc,wine.data,wine.target,cv=10)

clf=DecisionTreeClassifier()
clf_s=cross_val_score(clf,wine.data,wine.target,cv=10)
plt.figure(figsize=(10,5))
plt.plot(range(1,11),rfc_s,label='RandomForest')
plt.plot(range(1,11),clf_s,label='Decision Tree')
plt.title('RandomForest VS Decision Tree')
plt.legend()
plt.show()

image.png 10次交叉验证下,虽然决策树的结果有时和随机森林相同,但是大总体上,随机森林结果显著优于决策树。

三 袋装法

当random_state固定时,随机森林中生成是一组固定的树,但每棵树依然是不一致的,消除了每次结果的随机性。并且我们可以证明,当这种随机性越大的时候,袋装法的效果一 般会越来越好。用袋装法集成时,基分类器应当是相互独立的,是不相同的。 但这种做法的局限性是很强的,当我们需要成千上万棵树的时候,数据不一定能够提供成千上万的特征来让我们建尽量多尽量不同的树。因此,除了random_state。我们还需要其他的随机性。

3.1 bootstrap&oob_score

要让基分类器尽量都不一样,则使用不同的训练集来进行训练,而袋装法通过有放回的随机抽样技术来形成不同的训练数据,bootstrap就是用来控制抽样技术的参数。 在一个含有n个样本的原始训练集中,我们进行随机采样,每次采样一个样本,并在抽取下一个样本之前将该样本放回原始训练集,也就是说下次采样时这个样本依然可能被采集到,这样采集n次,最终得到一个和原始训练集一 样大的n个样本组成的自助集。由于是随机采样,这样每次的自助集和原始数据集不同,和其他的采样集也是不同的。这样就有取之不尽用之不竭,并且互不相同的自助集,用这些自助集来训练我们的基分类 器,我们的基分类器自然也就各不相同了。这样就会有一部分训练数据被浪费掉,这些数据被称为袋外数据(out of bag data ,简写oob),除了最开始就划分好的测试集之外,这些数据被用来作为集成算法的测试集。也就是说,在使用随机森林时,我们可以不划分测试集和训练集,只需要用袋外数据来测试模型即可。当然,这也不是绝对的,当n和n_estimators都不够大的时候,很可能就没有数据掉 落在袋外,自然也就无法使用oob数据来测试模型了。 如果希望用袋外数据来测试,则需要在实例化时就将oob_score这个参数调整为True,训练完毕之后,我们可以用 随机森林的另一个重要属性:oob_score_来查看我们的在袋外数据上测试的结果:

rfc=RandomForestClassifier(n_estimators=30,oob_score=True)
rfc=rfc.fit(wine.data,wine.target)
rfc.oob_score_

image.png

四 重要属性和接口

随机森林的接口与决策树完全一致,因此依然有四个常用接口:apply, fit, predict和score。除此之外,还需要注意随机森林的predict_proba接口,这个接口返回每个测试样本对应的被分到每一类标签的概率,标签有几个分类就返回几个概率。如果是二分类问题,则predict_proba返回的数值大于0.5的,被分为1,小于0.5的,被分为0。 传统的随机森林是利用袋装法中的规则,平均或少数服从多数来决定集成的结果,而sklearn中的随机森林是平均每个样本对应的predict_proba返回的概率,得到一个平均概率,从而决定测试样本的分类。

rfc =RandomForestClassifier(n_estimators=25)
rfc=rfc.fit(x_train,y_train)

#预测结果和标签相比的正确率
print('Random Forest Score:{}'.format(rfc.score(x_test,y_test)))
print('-'*100)
#特征重要性
print('特征重要性:{}'.format([*zip(wine.feature_names,rfc.feature_importances_)]))
print('-'*100)
#每个样本在每棵树中叶子节点的索引
print('每个样本在每棵树中叶子节点的索引:{}'.format(rfc.apply(x_test)[:2]))
print('-'*100)
#测试集预测的标签
print('测试集预测的标签:{}'.format(rfc.predict(x_test)))
print('-'*100)
#每个样本被分到每个标签的概率
print('每个样本被分到每个标签的概率:{}'.format(rfc.predict_proba(x_test)[:5]))

image.png **在使用随机森林之前,一定要检查,用来组成随机 森林的分类树们是否都有至少50%的预测正确率。