公号:码农充电站pro
主页:https://codeshellme.github.iohtml
上篇文章介绍了决策树算法的理论篇,本节来介绍如何用决策树解决实际问题。node
决策树是经常使用的机器学习算法之一,决策树模型的决策过程很是相似人类作判断的过程,比较好理解。python
决策树可用于不少场景,好比金融风险评估,房屋价格评估,医疗辅助诊断等。git
要使用决策树算法,咱们先来介绍一下 scikit-learn 。github
scikit-learn 是基于Python 的一个机器学习库,简称为sklearn,其中实现了不少机器学习算法。咱们能够经过sklearn 官方手册 来学习如何使用它。算法
sklearn 自带数据集shell
要进行数据挖掘,首先得有数据。sklearn 库的datasets 模块中自带了一些数据集,能够方便咱们使用。数组
sklearn 自带数据集:dom
冒号后边是每一个数据集对应的函数,可使用相应的函数来导入数据。机器学习
好比咱们用以下代码导入鸢尾花数据集:
from sklearn.datasets import load_iris iris = load_iris()
使用dir(iris)
查看iris
中包含哪些属性:
>>> dir(iris) ['DESCR', 'data', 'feature_names', 'filename', 'frame', 'target', 'target_names']
sklearn 库的tree 模块实现了两种决策树:
sklearn.tree.DecisionTreeClassifier
类:分类树的实现。sklearn.tree.DecisionTreeRegressor
类:回归树的实现。分类树用于预测离散型数值,回归树用于预测连续性数值。
sklearn 只实现了预剪枝,没有实现后剪枝。
DecisionTreeClassifier
类的构造函数
def __init__(self, *, criterion="gini", splitter="best", max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0., max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0., min_impurity_split=None, class_weight=None, ccp_alpha=0.0):
DecisionTreeClassifier
类的构造函数中的criterion
参数有2 个取值:
entropy
:表示使用 ID3 算法(信息增益)构造决策树。gini
:表示使用CART 算法(基尼系数)构造决策树,为默认值。其它参数可以使用默认值。
sklearn 库中的决策分类树只实现了ID3 算法和CART 算法。
DecisionTreeRegressor
类的构造函数
def __init__(self, *, criterion="mse", splitter="best", max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0., max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0., min_impurity_split=None, ccp_alpha=0.0):
DecisionTreeRegressor
类的构造函数中的criterion
参数有4 个取值:
mse
:表示均方偏差算法,为默认值。friedman_mse
:表示费尔德曼均方偏差算法。mae
:表示平均偏差算法。poisson
:表示泊松误差算法。其它参数可以使用默认值。
咱们使用 sklearn.datasets
模块中自带的鸢尾花数据集 构造一颗决策树。
鸢尾花数据集目的是经过花瓣的长度和宽度,及花萼的长度和宽度,预测出花的品种。
这个数据集包含150条数据,将鸢尾花分红了三类(每类是50条数据),分别是:
setosa
,用数字0
表示。versicolor
,用数字1
表示。virginica
,用数字2
表示。咱们抽出3 条数据以下:
5.1,3.5,1.4,0.2,0 6.9,3.1,4.9,1.5,1 5.9,3.0,5.1,1.8,2
数据的含义:
特征值
,最后1列称为目标值
。咱们的目的就是用特征值预测出目标值。将上面3 条数据,用表格表示就是:
花萼长度 | 花萼宽度 | 花瓣长度 | 花瓣宽度 | 花的品种 |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | 0 |
6.9 | 3.1 | 4.9 | 1.5 | 1 |
5.9 | 3.0 | 5.1 | 1.8 | 2 |
首先导入必要的类和函数:
from sklearn.tree import DecisionTreeClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score
其中:
DecisionTreeClassifier
类用于构造决策树。load_iris()
函数用于导入数据。train_test_split()
函数用于将数据集拆分红训练集与测试集。accuracy_score()
函数用于为模型的准确度进行评分。导入数据集:
iris = load_iris() # 准备数据集 features = iris.data # 获取特征集 labels = iris.target # 获取目标集
将数据分红训练集和测试集,训练集用于训练模型,测试集用于测试模型的准确度。
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size=0.33, random_state=0)
咱们向train_test_split()
函数中传递了4 个参数,分别是:
该函数返回4 个值,分别是:
接下来构造决策树:
# 用CART 算法构建分类树(你也可使用ID3 算法构建) clf = DecisionTreeClassifier(criterion='gini') # 用训练集拟合构造CART分类树 clf = clf.fit(train_features, train_labels)
上面两句代码已经在注释中说明,最终咱们获得了决策树clf
(classifier
的缩写)。
用clf
预测测试集数据,test_predict
为预测结果:
test_predict = clf.predict(test_features)
计算预测结果的准确率:
score = accuracy_score(test_labels, test_predict) score2 = clf.score(test_features, test_labels) print(score, score2)
最终得出,sorce
和 score2
都为 0.96,意思就是咱们训练出的模型的准确率为96%。
函数accuracy_score()
和 clf.score()
均可以计算模型的准确率,但注意这两个函数的参数不一样。
为了清楚的知道,咱们构造出的这个决策树cfl
究竟是什么样子,可以使用 graphviz
模块将决策树画出来。
代码以下:
from sklearn.tree import export_graphviz import graphviz # clf 为决策树对象 dot_data = export_graphviz(clf) graph = graphviz.Source(dot_data) # 生成 Source.gv.pdf 文件,并打开 graph.view()
为了画出决策树,除了须要安装相应的 Python 模块外,还须要安装Graphviz 软件。
由上面的代码,咱们获得的决策树图以下:
咱们以根节点为例,来解释一下每一个方框里的四行数据(叶子节点是三行数据)都是什么意思。
四行数据所表明的含义:
X[3]<=0.75
:鸢尾花数据集的特征集有4 个属性,因此对于X[n]
中的n
的取值范围为0<=n<=3
,X[0]
表示第1个属性,X[3]
表示第4 个属性。X[3]<=0.75
的意思就是当X[3]
属性的值小于等于0.75 的时候,走左子树,不然走右子树。
gini=0.666
,表示当前的gini
系数值。samples=100
,samples
表示当前的样本数。咱们知道整个数据集有150 条数据,咱们选择了0.33 百分比做为测试集,那么训练集的数据就占0.67,也就是100 条数据。根节点包含全部样本集,因此根节点的samples
值为100。value
:value
表示属于该节点的每一个类别的样本个数,value
是一个数组,数组中的元素之和为samples
值。咱们知道该数据集的目标集中共有3 个类别,分别为:setosa
,versicolor
和 virginica
。因此:
value[0]
表示该节点中setosa
种类的数据量,即34。value[1]
表示该节点中versicolor
种类的数据量,即31。value[2]
表示该节点中virginica
种类的数据量,即35。咱们构造出来的决策树对象clf
中,有一个feature_importances_
属性,以下:
>>> clf.feature_importances_ array([0, 0.02252929, 0.88894654, 0.08852417])
clf.feature_importances_
是一个数组类型,里边的元素分别表明对应特征的重要性,全部元素之和为1
。元素的值越大,则对应的特征越重要。
因此,从这个数组,咱们能够知道,四个特征的重要性排序为:
咱们可使用下面这个函数,将该数组画成柱状图:
import matplotlib.pyplot as plt import numpy as np # mode 是咱们训练出的模型,即决策树对象 # data 是原始数据集 def plot_feature_importances(model, data): n_features = data.data.shape[1] plt.barh(range(n_features), model.feature_importances_, align='center') plt.yticks(np.arange(n_features), data.feature_names) plt.xlabel("Feature importance") plt.ylabel("Feature") plt.show() plot_feature_importances(clf, iris)
下图是用plot_feature_importances()
函数生成的柱状图(红字是我添加的
),从图中能够清楚的看出每一个特种的重要性。
从该图中也能够看出,为何决策树的根节点的特征是X[3]
。
咱们已经用鸢尾花数据集构造了一棵分类树,下面咱们用波士顿房价数据集构造一颗回归树。
来看几条数据:
首先,咱们认为房价是有不少因素影响的,在这个数据集中,影响房价的因素有13 个:
数据中的最后一列的数据是房价:
由于房价是一个连续值,而不是离散值,因此须要构建一棵回归树。
下面对数据进行建模,构造回归树使用DecisionTreeRegressor
类:
from sklearn.tree import DecisionTreeRegressor from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error # 准备数据集 boston = load_boston() # 获取特征集和房价 features = boston.data prices = boston.target # 随机抽取33% 的数据做为测试集,其他为训练集 train_features, test_features, train_price, test_price = train_test_split(features, prices, test_size=0.33) # 建立CART回归树 dtr = DecisionTreeRegressor() # 拟合构造CART回归树 dtr.fit(train_features, train_price) # 预测测试集中的房价 predict_price = dtr.predict(test_features) # 测试集的结果评价 print('回归树准确率:', dtr.score(test_features, test_price)) print('回归树r2_score:', r2_score(test_price, predict_price)) print('回归树二乘误差均值:', mean_squared_error(test_price, predict_price)) print('回归树绝对值误差均值:', mean_absolute_error(test_price, predict_price))
最后四行代码是计算模型的准确度,这里用了4 种方法,输出以下:
回归树准确率: 0.7030833400349499 回归树r2_score: 0.7030833400349499 回归树二乘误差均值: 28.40730538922156 回归树绝对值误差均值: 3.6275449101796404
须要注意,回归树与分类树预测准确度的方法不同:
dtr.score
():与分类树相似,很少说。r2_score
():表示R 方偏差,结果与 dtr.score
() 同样,取值范围是0 到1。mean_squared_error
():表示均方偏差,数值越小,表明准确度越高。mean_absolute_error
():表示平均绝对偏差,数值越小,表明准确度越高。能够用下面代码,将构建好的决策树画成图:
from sklearn.tree import export_graphviz import graphviz # dtr 为决策树对象 dot_data = export_graphviz(dtr) graph = graphviz.Source(dot_data) # 生成 Source.gv.pdf 文件,并打开 graph.view()
这棵二叉树比较大,你能够本身生成看一下。
再来执行下面代码,看下特征重要性:
import matplotlib.pyplot as plt import numpy as np # mode 是咱们训练出的模型,即决策树对象 # data 是原始数据集 def plot_feature_importances(model, data): n_features = data.data.shape[1] plt.barh(range(n_features), model.feature_importances_, align='center') plt.yticks(np.arange(n_features), data.feature_names) plt.xlabel("Feature importance") plt.ylabel("Feature") plt.show() plot_feature_importances(dtr, boston)
从生成的柱状图,能够看到LSTAT 对房价的影响最大:
本文中用到的数据是sklearn 中自带的数据,数据完整性比较好,因此咱们没有对数据进行预处理。实际项目中,可能数据比较杂乱,因此在构建模型以前,先要对数据进行预处理。
要对数据有个清楚的认识,每一个特征的含义。若是有特别明显的特征对咱们要预测的目标集没有影响,则要将这些数据从训练集中删除。
若是某些特征有数据缺失,须要对数据进行补全,可使用著名的 Pandas 模块对数据进行预处理。若是某特征的数据缺失严重,则应该将其从训练集中删除。对于须要补全的值:
若是某些特征的值是字符串类型数据,则须要将这些数据转为数值型数据。
sklearn.feature_extraction
模块中的 DictVectorizer
类来处理(转换成数字0/1
)。在测试模型的准确率时,若是测试集中只有特征值没有目标值,就很差对测试结果进行验证。此时有两种方法来测试模型准确率:
train_test_split
() 函数将原始数据集(含有目标集)拆分红训练集和测试集。sklearn.model_selection
模块中的 cross_val_score
函数进行K 折交叉验证来计算准确率。K 折交叉验证原理很简单:
- 将数据集平均分红K 个等份,
K
通常取10
。- 使用K 份中的1 份做为测试数据,其他为训练数据,而后进行准确率计算。
- 进行屡次以上步骤,求平均值。
本篇文章介绍了如何用决策树来处理实际问题。主要介绍了如下知识点:
sklearn
是基于 Python
的一个机器学习库。sklearn.datasets
模块中有一些自带数据集供咱们使用。sklearn.tree
中的两个类来构建分类树和回归树:
DecisionTreeClassifier
类:构造决策分类树,用于预测离散值。DecisionTreeRegressor
类:构造决策回归树,用于预测连续值。criterion
参数的含义。train_test_split
() 函数用于拆分数据集。o.fit
() 用于拟合决策树。(o
表示决策树对象)o.predict
() 用于预测数据。o.score
() 用于给模型的准确度评分。accuracy_score
() 函数用于给分类树模型评分。r2_score
() 函数用于给回归树模型评分。mean_squared_error
() 函数用于给回归树模型评分。mean_absolute_error
() 函数用于给回归树模型评分。(本节完。)
推荐阅读:
欢迎关注做者公众号,获取更多技术干货。