决策树以及随机森林在Sklearn中的实现

基于树的学习算法是十分流行且应用广泛的一类非参数化的有监督学习算法,这些算法既可用于分类又可用于回归。本篇博客主要总结树模型在Sklearn中的实现,不涉及过多算法理论。

1. 训练决策树分类器

使用scikit-learn中的DecisionTreeClassifier训练决策树分类器。

from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建决策树分类器对象
decisiontree = DecisionTreeClassifier(random_state=0)
#训练模型
model = decisiontree.fit(features,target)

决策树的训练器会尝试找到在节点上能够最大限度降低数据不纯度的决策规则。默认使用基尼指数。

#创建新样本
observation = [[5,4,3,2]]
#预测样本分类
model.predict(observation)
--->
array([1])

也可以使用predict_proba方法查看该样本属于每个分类(预测分类)的概率:

#查看样本分别属于三个分类的概率
model.predict_proba(observation)
--->
array([[0., 1., 0.]])

如果想使用其他的不纯度度量方式,可以修改参数criterion。

2.训练决策树回归模型

使用DecisionTreeRegression训练决策树回归模型:

from sklearn.tree import DecisionTreeRegressor
from sklearn import datasets
#加载仅有两个特征的数据
boston = datasets.load_boston()
features = boston.data[:,0:2]
target = boston.target
#创建决策树回归模型对象
decisiontree = DecisionTreeRegressor(random_state=0)
#训练模型
model = decisiontree.fit(features,target)

决策树回归模型默认使用均方误差(MSE)的减小量来作为分裂规则的评估标准:
M S E = 1 n ∑ i = 1 n ( y i − y i ^ ) 2 MSE = {1\over n}\sum_{i=1}^n(y_i-\hat{y_i})^2 MSE=n1i=1n(yiyi^)2

#创建新样本
observation = [[0.02,16]]
#预测样本值
model.predict(observation)
--->
array([33.])

可以用参数criterion选择分裂质量(split quality),比如平均绝对误差(MAE)。

3.可视化决策树

将决策树模型导出为DOT格式并可视化:

import pydotplus
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
from IPython.display import Image
from sklearn import tree
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建决策树分类器对象
decisiontree = DecisionTreeClassifier(random_state=0)
#训练模型
model = decisiontree.fit(features,target)
#创建DOT数据
dot_data = tree.export_graphviz(decisiontree,
                                out_file=None,
                                feature_names=iris.feature_names,
                                class_names=iris.target_names)
#绘制图形
graph=pydotplus.graph_from_dot_data(dot_data)
#显示图形
Image(graph.create_png())

在这里插入图片描述
如果要在其他应用中使用决策树,可以将可视化后的决策树导出为PDF格式或PNG格式:

#创建PDF
graph.write_pdf("iris.pdf")
#创建PNG
graph.write_png("iris.png")

4.训练随机森林分类器

使用RandomForestClassifier训练随机森林分类器模型:

from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建决策树分类器对象
RF = RandomForestClassifier(random_state=0)
#训练模型
model = RF.fit(features,target)

与DecisionTreeClassifier工作方式类似:

#查看样本分别属于三个分类的概率
model.predict_proba(observation)
--->
array([[0., 1., 0.]])

不过作为一个森林而不是一个单独的决策树,RandomForestClassifier有一些独特且重要的参数。首先,参数max_features决定每个节点需要考虑的特征的最大数量,允许输入的变量类型包括整型(特征的数量)、浮点型(特征的百分比)\和sqrt(特征数量的平方根)。默认情况下,参数max_features的值被设置为auto。
其次,参数bootstrap用于设置在创建树时使用的样本子集,是有放回的抽样还是无放回抽样。第三,参数n_estimators设置森林中包含的决策树数量。

5.训练随机森林回归模型

使用RandomForestRegressor训练随机森林回归模型:

from sklearn.ensemble import RandomForestRegressor
from sklearn import datasets
#加载仅有两个特征的数据
boston = datasets.load_boston()
features = boston.data[:,0:2]
target = boston.target
#创建决策树回归模型对象
RF = RandomForestRegressor(random_state=0)
#训练模型
model = RF.fit(features,target)

和创建随机森林分类器一样,也可以创建随机森林回归模型,其中每棵树使用一个自举的样本子集,并且在每个节点决策规则仅考虑一部分特征。与RandomForestClassifier一样,随机森林回归模型也有几个重要的参数:

  • max_features设置每个节点要考虑的特征的最大数量,默认值为 p \sqrt p p 个,其中p是特征的总数
  • bootstrap设置是否使用有放回的抽样,默认值为true.
  • n_estimators设置决策树的数量,默认值为10。

6.识别随机森林中的重要特征

计算并可视化每个特征的重要性(Feature importance)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建随机森林分类器对象
randomforest = RandomForestClassifier(random_state=0,n_jobs=-1)
#训练模型
model = randomforest.fit(features,target)
#计算特征的重要性
importances = model.feature_importances_
#将特征的重要性按降序排列
indices = np.argsort(importances)[::-1]
#按照特征重要性对特征名称重新排序
names = [iris.feature_names[i] for i in indices]
#创建图
plt.figure()
#创建图表题
plt.title("Feature Importance")
#添加数据
plt.bar(range(features.shape[1]),importances[indices])
#将特征名称添加为x轴标签
plt.xticks(range(features.shape[1]),names,rotation = 90)
#显示图
plt.show()

在这里插入图片描述

在sklearn中,决策树和随机森林的分类及回归模型都可以通过feature_importances_查看模型中每个特征的重要程度:

#查看特征的重要程度
model.feature_importances_
--->
array([0.09090795, 0.02453104, 0.46044474, 0.42411627])

数值越大,说明该特征越重要(所有特征的重要性相加等于1)。绘制这些值有助于解释随机森林模型。

7.选择随机森林中的重要特征

在进行模型训练前,先确定重要特征,然后使用它们重新训练模型:

from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets
from sklearn.feature_selection import SelectFromModel
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建随机森林分类器
RF = RandomForestClassifier(random_state=0,n_jobs=-1)
#创建对象,选择重要性大于或等于阈值的特征
selector = SelectFromModel(RF,threshold=0.3)
#使用选择器创建新的特征矩阵
features_important = selector.fit_transform(features,target)
#使用重要的特征训练随机森林模型
model = RF.fit(features_important,target)

使用这种方法选择特征时,需要注意:第一,经过one-hot编码的nominal型分类特征的重要性被稀释到二元特征中;第二,一对高度相关的特征,其重要性被集中在其中一个特征上,而不是均匀分布在这两个特征上。

8.处理不均衡的分类

如果要在高度不均衡的数据上训练随机森林模型,可以用参数class_weight="balance"训练决策树或者随机森林模型:

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#删除前40个样本以获得高度不均衡的数据
features = features[40:,:]
target = target[40:]
#创建目标向量表明分类是0还是1
target = np.where((target==0),0,1)
#创建随机森林分类器对象
randomforest = RandomForestClassifier(random_state=0,n_jobs=-1,class_weight="balanced")
#训练模型
model= randomforest.fit(features,target)

在实际应用中,很容易遇到不均衡的分类问题。如果不解决这个问题,不均衡的分类就会降低模型的性能。如果使用class_weight=“balanced”,就能够增大较小分类的权重(减小较大分类的权重)。

9.控制决策树的规模

手动控制决策树的结构与规模:

from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建决策树分类器对象
DT = DecisionTreeClassifier(random_state=0,
                            max_depth=None,
                            min_samples_split=2,
                            min_samples_leaf=1,
                            min_weight_fraction_leaf=0,
                            max_leaf_nodes=None,
                            min_impurity_decrease=0)
#训练模型
model = DT.fit(features,target)
  • max_depth:树的最大深度。如果为None,则树一直生长,直到所有叶子节点都为纯节点。如果提供整数作为该参数的值,这棵树就会被有效”修剪“到这个整数所表示的深度。
  • min_samples_split:在该节点分裂之前,节点上最小的样本数。如果提供整数,则这个代表最小的样本数;如果提供浮点数,则最小样本为总样本数乘以该浮点数。
  • min_samples_leaf:叶子节点需要的最小样本数,与min_samples_split使用相同参数格式。
  • max_leaf_nodes:最大叶子节点数。
  • min_impurity_split:执行分裂所需的最小不纯度减少量。

10.通过boosting提高性能

这部分内容属于集成学习,会涉及xgboost,lightgbm等内容,所以此处不贴了。后续单独整理集成学习知识点。

11.使用袋外误差(Out-of-Bag Error)评估随机森林模型

在不使用交叉验证的情况下评估随机森林模型:

from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets
#加载数据
iris = datasets.load_iris()
features = iris.data
target = iris.target
#创建随机森林分类器对象
randomforest = RandomForestClassifier(random_state=0,n_jobs=-1,n_estimators=1000,oob_score=True)
#训练模型
model= randomforest.fit(features,target)
#查看袋外误差
randomforest.oob_score_
output--->
0.9533333333333334

在随机森林中,每个决策树使用自举样本子集进行训练。意味着对于每棵树而言,都有未参与训练的样本子集。这些样本被称为袋外(Out-of-bag,OOB)样本。袋外样本可以用作测试集评估随机森林模型的性能。

对于每个样本,算法将其真实值与未使用该样本进行训练的树模型子集产生的预测值进行比较。计算所有样本的总得分,就可以得到一个随机森林的性能指标。OOB分数评估法可以用作交叉验证的替代方案。

  • 参考:Python机器学习手册

猜你喜欢

转载自blog.csdn.net/weixin_44127327/article/details/109161102
今日推荐