决策树是一种非参数的有监督学习方法,它能从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。
sklearn中决策树的类都在“tree”这个模块之下,该模块包含五个类
tree.DecisionTreeClassifier | 分类树 |
---|---|
tree.DecisionTreeRegressor | 回归树 |
tree.export_graphviz | 将生成的决策树导出为DOT格式,画图专用 |
tree.ExtraTreeClassifier | 高随机版本的分类树 |
tree.ExtraTreeRegressor | 高随机版本的回归树 |
from sklearn import tree
clf = tree.DecisionTreeClassifier()
clf = clf.fit(x_train, y_train) #通过fit接口训练模型
result = clf.score(x_test, y_test) #通过score获得信息
决策树需要找出最佳节点和最佳的分枝方法,对分类树来说,衡量这个最佳的指标叫做**“不纯度”**。
通常不纯度越低,决策树对训练集的拟合越好。不纯度基于节点计算,树中的每一个节点都有一个不纯度,并且子节点的不纯度一定是低于父节点的,也就是在同一棵树上,叶子节点的不纯度一定是最低的。
导入需要的算法库和模块
from sklearn import tree
from sklearn.datasets import load_wine #红酒数据集
from sklearn.model_selection import train_test_split
探索数据集
wine = load.wine() #将数据集赋值给wine
wine #查看数据集中的所有数据
wine.data #查看数据集中的数据部分
wine.target #查看数据集的标签
wine.data.shape #查看数据有几行几列组成
wine.feature_names #特征名
wine.target_names #标签名
#将数据与标签组合为一张表进行对应
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)], axis=1)
---------------------------------------------------
0 1 2 3 4 5 6 7 8 9 10 11 12
0 14.23 1.71 2.43 15.6 127.0 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065.0
0 13.20 1.78 2.14 11.2 100.0 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050.0
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2 13.71 5.65 2.45 20.5 95.0 1.68 0.61 0.52 1.06 7.70 0.64 1.74 740.0
2 13.40 3.91 2.48 23.0 102.0 1.80 0.75 0.43 1.41 7.30 0.70 1.56 750.0
178 rows × 13 columns
将数据集分为训练集与测试集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data, wine.target, test_size=0.3)
基本建模三部曲
clf = tree.DecisionTreeClassifier(criterion="entropy"
,random_state=20 #用来设置分枝中的随机数量(默认为None)
,splitter="random" #用来控制决策树中的随机选项(best,random)
)
clf = clf.fit(x_train, y_train)
score = clf.score(x_test, y_test)
score
----------------------------------------------------
0.9629629629629629
画出一棵树
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸'] #由于原数据集特征名是英文在此进行了中文赋值
import graphviz
dot_data = tree.export_graphviz(clf
,feature_names = feature_name
,class_names = ["琴酒","雪莉","贝尔摩德"] #原数据集中类名有三种,对类名进行重新赋值
,filled=True #进行颜色填充
,rounded=True #将树中方形改为圆形
,max_depth=3
)
graph = graphviz.Source(dot_data) #从dot_data中获取生成树的代码并赋值给graph
graph #输出树
特征重要性
clf.feature_importances_
---------------------------------------------------
array([0.0707359 , 0. , 0. , 0. , 0.07183574,
0.0102946 , 0.12588086, 0. , 0. , 0. ,
0.1544854 , 0.22760254, 0.33916497])
#通过zip将特征名与特征重要性结合
clf.feature_importances_
[*zip(feature_name, clf.feature_importances_)]
为了使决策树有更好的泛化性,我们要对决策树进行剪枝,剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树的算法核心
对决策树来说最重要的是feature_importances_,能够查看各个特征对模型的重要性。
sklearn中许多算法的接口都是相似的,比如fit、score,几乎对每个算法都适用。决策树常用的接口还有apply、predict。
注:所有接口中要求输入X_train和X_test的部分,输入的特征矩阵必须是一个二维矩阵。sklearn不接受任何一维矩阵作为特征矩阵被输入。若数据只有一个特征,必须用reshape(-1,1)来给矩阵增维;若数据只有一个特征和一个样本,使用reshape(1,-1)来给矩阵增维。
clf.apply(Xtest)
clf.predict(Xtest)
-------------------------------------------------------
array([11, 11, 3, 10, 4, 11, 11, 7, 4, 3, 6, 7, 6, 4, 6, 6, 4,
10, 10, 6, 7, 11, 6, 7, 6, 12, 11, 4, 7, 10, 4, 3, 10, 4,
11, 4, 11, 4, 3, 12, 7, 3, 4, 7, 7, 10, 4, 11, 12, 4, 10,
3, 4, 3], dtype=int64)
array([0, 0, 1, 0, 1, 0, 0, 2, 1, 1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 2, 2, 0,
2, 2, 2, 0, 0, 1, 2, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 1, 1, 2,
2, 0, 1, 0, 0, 1, 0, 1, 1, 1])