带你走进sklearn系列1
资料来源:菜菜B站视频
文章内容:决策树的基本概念和实战应用。不会展示公式原理,偏重于实战应用。
无意中翻到了菊安酱和菜菜的博客,大家可以去看一下:https://www.cnblogs.com/juanjiang/p/11003369.html
概述
决策树是一种非参数的有监督学习算法,非参数是说参数数量会随着训练样本增长的算法。
具体可以去看:https://www.cnblogs.com/wwwjjjnnn/p/9126906.html
核心问题
- 谁是最佳分枝点
- 什么时候停止分枝
模块sklearn.tree
共包含4种树和3种树的输出形式,官方教程:https://scikit-learn.org/stable/modules/classes.html#module-sklearn.tree
- tree.DecisionTreeClassifier() 分类树 ****今日重点**
- tree.DecisionTreeRegressor() 回归树
- tree.ExtraTreeClassifier() 高随机版本的分类树
- tree.ExtraTreeRegressor() 高随机版本的回归树
- tree.export_graphviz(decision_tree) 输出DOT格式的图
- tree.export_text(decision_tree) 输出决策树规则的文本
- tree.plot_tree(decision_tree) 画决策树
重要参数--8个
class sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort='deprecated', ccp_alpha=0.0)
1.criterion
用来决定不纯度的计算方法:entropy、gini。树中的每一个节点都有不纯度,叶子节点的不纯度最低。
一般默认使用gini,当决策树拟合程度不够时,再试试信息熵,信息熵对训练集拟合的比较精细,但往往也容易过拟合,两者基本没太大差别。选择不纯度最低的节点(就是最纯的,最容易直接分类的特征)进行分枝,决策树在分枝时,其实使用的是信息增益。
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
wine = load_wine()
利用红酒数据集建一棵树,数据集中字段包括:wine.data,wine.target,wine.target_names,wine.feature_names,该数据集是一个三分类数据。
# 做成一个表,来瞅一下,最后一列就是标签
import pandas as pd
data = pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
data.head(3)
# 划分数据集,注意前面一定是xxyy,test_size可以自己设定7:3还是8:2
x_train,x_test,y_train,y_test = train_test_split(wine.data,wine.target,test_size=0.3)
print("x_train的维度{},wine.date的维度{}".format(x_train.shape,wine.data.shape))
x_train的维度(124, 13),wine.date的维度(178, 13)
2.random_state & splitter
sklearn通过在分枝时随机选取部分特征进行优化,进而建立很多棵树,返回最好的树。
在高维度的数据中,每次运行下面的模型,会返回不同的分数。为保持结果稳定,设定random_state参数。
splitter控制随机选项,有两个参数:'best'根据重要程度选取特征;'random'在分枝时更随机,对训练集的拟合度会降低。 所以如果你本身特征就比较多,为了防止过拟合可以设置这两个参数。
# 建模看一下
clf = tree.DecisionTreeClassifier(criterion='entropy'
,random_state=30
,splitter='random'
)
clf = clf.fit(x_train,y_train)
score = clf.score(x_test,y_test)
print('模型分数:%.4f' %score)
import graphviz
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','飞黄烷类酚类','花青素','颜色强度','色调','稀释葡萄酒','脯氨酸']
dot_data = tree.export_graphviz(clf
,feature_names=feature_name
,class_names=['琴酒','雪莉','贝尔摩德']
,filled=True # 颜色填充
,rounded=True # 圆角
)
graph = graphviz.Source(dot_data)
graph
graphviz要自己另外安装,记得加入path。
查看特征排名
# 特征重要性的排名
clf.feature_importances_
# *zip()进行解压
[*zip(feature_name,clf.feature_importances_)]
3.剪枝参数(5个)
- max_depth 限制树的深度,在高维度低样本的训练中非常有效。建议从=3开始尝试,看拟合效果再决定是否增加深度。
-
min_samples_leaf
节点分枝后的每个子节点包含的样本数必须包含的样本个数,一般搭配max_depth使用,建议从=5开始使用。 -
min_samples_split
一个节点必须包含的样本数,小于这个样本数,就不会允许继续分枝。 -
max_features
限制分枝时考虑的特征个数,是一个比较暴力的强行使决策树停下的参数。如果希望降维选取重要特征,建议改用PCA、ICA或其他特征选择模块中的降维算法,盲目限制该参数,可能会使模型学习能力不足。 -
min_impurity_decrease
当信息增益小于限定的数值时,不会再分枝。
一般来讲max_depth+min_samples_leaf|min_samples_split就可以完成调参,后面的参数设置属于精修范围。
# 对训练集的拟合程度---“太完美了”
train_score=clf.score(x_train,y_train)
train_score
进行剪枝,参数是随便修改的,该结果并不是最优 ,重点看参数设置后的变化
cut_clf = tree.DecisionTreeClassifier(criterion='entropy'
,random_state=30
,splitter='random'
,max_depth=4
,min_samples_leaf=5
,min_samples_split=45
)
cut_clf = cut_clf.fit(x_train,y_train)
cut_score = cut_clf.score(x_test,y_test)
print('模型分数:%.4f' %cut_score)
cut_dot_data = tree.export_graphviz(cut_clf
,feature_names=feature_name
,class_names=['琴酒','雪莉','贝尔摩德']
,filled=True # 颜色填充
,rounded=True # 圆角
)
cut_graph = graphviz.Source(cut_dot_data)
cut_graph
如何调参
学习曲线的使用
以超参数的取值为横坐标,模型的度量值为纵坐标。
import matplotlib.pyplot as plt
%matplotlib inline
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth=i+1
,criterion='entropy'
,random_state=30
)
clf = clf.fit(x_train,y_train)
score = clf.score(x_test,y_test)
test.append(score)
plt.plot(range(1,11),test,color='red',label='max_depth')
plt.legend()
plt.show()
- 剪枝参数不一定提高模型在测试集上的表现,这取决于数据本身。
- 遗留问题:多参数调参(后面补上)
目标权重参数
-
class_weight & min_weight_fraction_leaf
当样本类别不平衡时设置的参数,默认为None,所有标签具有相同权重。
样本加权之后使用min_weight_fraction_leaf配合调参。
重要属性
- feature_importances_
训练之后,调用clf.feature_importances_查看特征重要程度。
与特征名一起解压,得到(特征,权重)元组。
重要接口
- fit()
- score()
- apply()
返回样本点所在叶子节点的索引。 - predict()
返回样本分类/回归的结果。
总结
决策树一共讲了8个参数,1个属性,4个接口 。
8个参数 | 4个接口 | 1个属性 |
---|---|---|
criterion计算不纯度 | fit() | feature_importances_ |
random_state & splitters随机项设置 | score() | |
max_depth剪枝参数 | apply() | |
min_samples_leaf & min_samples_split 剪枝参数 | predict() | |
max_features & min_impurity_decrease 剪枝参数 | ||
class_weight & min_weight_fraction_leaf 类别权重 |