决策树
树的基本概念
节点深度:对任意节点x,x节点的深度表示为根节点到x节点的路径长度。所以根节点深度为0,第二层节点深度为1,以此类推
节点高度:对任意节点x,叶子节点到x节点的路径长度就是节点x的高度
树的深度:一棵树中节点的最大深度就是树的深度,也称为高度
父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点
子节点:一个节点含有的子树的根节点称为该节点的子节点
节点的层次:从根节点开始,根节点为第一层,根的子节点为第二层,以此类推
兄弟节点:拥有共同父节点的节点互称为兄弟节点
度:节点的子树数目就是节点的度
叶子节点:度为零的节点就是叶子节点
祖先:对任意节点x,从根节点到节点x的所有节点都是x的祖先(节点x也是自己的祖先)
后代:对任意节点x,从节点x到叶子节点的所有节点都是x的后代(节点x也是自己的后代)
森林:m颗互不相交的树构成的集合就是森林
接下来我们将学习如何从一堆原始数据
决策树的优缺点
优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
缺点:可能会产生过度匹配问题
适用数据类型:数值型和标称型
决策树的构造 谁当根节点??
通过属性构造节点,不同属性才有Gini 熵来度量,随着树深度的增加,节点的熵迅速的降低,熵降低的速度越快越好,这样我们有望得到一根高度最矮的决策树,熵值越小,纯度越高,熵是混乱程度比较大的含义。
信息增益:熵值的变化 信息增益越大越好(根节点)
预剪枝:在构建决策树的过程时提前停止
后剪枝:决策树构建好后,然后开始剪枝
酒精树为例
导入包 第二行导入数据 第三行分测试集和训练集
查看所有数据
查看具体数据
转换成表格方式
切分训练集和测试集
为了让决策树有更好的泛化性,我们要对决策树进行剪枝。剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心
1.max_depth 限制树的最大深度,超过设定深度的树枝全部剪掉(建议从3)
2.min_samples_leaf&min_samples_split(建议从5)
确认最优的剪枝参数,我们需要使用确定超参数的曲线来进行判断
clf = tree.DecisionTreeClassifier(criterion="entropy"
,random_state=20
,splitter ="random"
,max_depth=6
# ,min_samples_leaf=5
# ,min_samples_split=5
)
clf = clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
score
#超参数曲线
import matplotlib.pyplot as plt
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth = i+1
,criterion="entropy"
,random_state=20
,splitter ="random")
clf = clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()
这里确定max_depth的值使纯度更高
完整代码
clf = tree.DecisionTreeClassifier(criterion="entropy"
,random_state=20
,splitter ="random"
,max_depth=6
# ,min_samples_leaf=5
# ,min_samples_split=5
)
clf = clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
feature_name = ['alcohol',
'malic_acid',
'ash',
'alcalinity_of_ash',
'magnesium',
'total_phenols',
'flavanoids',
'nonflavanoid_phenols',
'proanthocyanins',
'color_intensity',
'hue',
'od280/od315_of_diluted_wines',
'proline']
import graphviz
dot_data = tree.export_graphviz(clf,
feature_names = feature_name,
class_names = ['class_0', 'class_1', 'class_2'],
filled=True,#添加颜色
rounded=True#方块的形状
)
graph = graphviz.Source(dot_data)
print(graph)
print(score)
补充
再举一个小例子 虹膜数分类
from sklearn import tree
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
Xtrain,Xtest,Ytrain,Ytest = train_test_split(iris.data,iris.target,test_size=0.3)
clf = tree.DecisionTreeClassifier(criterion="entropy"
,random_state=20
,splitter ="random"
,max_depth=6
# ,min_samples_leaf=5
#,min_samples_split=5
)
clf = clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
feature_name = ['sepal length (cm)',
'sepal width (cm)',
'petal length (cm)',
'petal width (cm)']
import graphviz
dot_data = tree.export_graphviz(clf,
feature_names = feature_name,
class_names = ['setosa', 'versicolor', 'virginica'],
filled=True,#添加颜色
rounded=True#方块的形状
)
graph = graphviz.Source(dot_data)
import matplotlib.pyplot as plt
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth = i+1
,criterion="entropy"
,random_state=20
,splitter ="random")
clf = clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()
print(score)
graph