监督学习——决策树

一、决策树原理

在这里插入图片描述

1.熵的概念

化学中可定义为分子的混乱程度,这里可以理解为系统的不确定程度
在这里插入图片描述
例如:A{1,2,3,4,5},B{1,1,1,1,1}
对于A集合,每个数字发生的概率均为1/6,Pi较小,-Pi*lnPi较大,熵值较大。
对于B集合,1发生的概率为1,熵值较小。
(x为Pi,y为lnPi)

2.如何构造决策树(例子)

构造树的基本想法是随着树的深度的增加,节点的熵迅速降低。降低的越快越好,这样我们可以得到一颗最矮的决策树
(若决策树高度过高,意味着有大量分支,每一个叶子节点纯度都很高,对于一个新的数据集上,分类达到百分百的效果,会出现过拟合的问题)
例子:一共有14组和数据,每行数据有4个特征,来决定当天是否去打球。在这里插入图片描述
步骤:
1.决定哪个属性作为根节点,天气,温度,湿度,有风均可作为根节点。首先计算原始数据熵值,然后分别计算4个属性的熵值,分别计算出信息增溢,选择信息增溢最大的属性作为根节点。(划分后的族群内部混乱程度会最小)
在这里插入图片描述
熵值的计算过程如下:
在这里插入图片描述
在这里插入图片描述
2.迭代

预剪枝:在构建决策树的过程中,提前停止
后剪枝:在决策树构建好后,才开始剪枝

3.决策树的构造:

优点:计算复杂程度不高,对中间的缺失不敏感,可以处理不相关特征数据。
缺点:可能会产生过拟合问题。(例如:人类可以按照性别分类,你却按照姓名分类)
使用数据类型:数值型和离散型。

二、sklearn库实现

from sklearn import tree
form sklearn.metric import precision_recall_curve
form sklearn.metric import classification_report
form sklearn.cross_valication import train_test_split

#拆分训练数据与测试数据,80%做训练,20%做测试
train_test_split(x,y,test_size=0.2)
#信息熵作
tree.Decision TreeClassifier(criterion='entropy')
#训练结果
clf.fit(x_train,y_train)
#预测结果
clf.predict(x_train)
#计算准确率和召回率
precision_recall_curve(y_train,y_pre)
#计算全量的预测结果
clf.predict_proba(x)[:,1]
#打印每个分类的准召率
classification_report(y,answer,target_names=target_names)

红酒分类案例(建模预测+精准度+画树):

#导入库
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

wine=load_wine()
wine.data
#结果
array([[1.423e+01, 1.710e+00, 2.430e+00, ..., 1.040e+00, 3.920e+00,
        1.065e+03],
       [1.320e+01, 1.780e+00, 2.140e+00, ..., 1.050e+00, 3.400e+00,
        1.050e+03],
       [1.316e+01, 2.360e+00, 2.670e+00, ..., 1.030e+00, 3.170e+00,
        1.185e+03],
       ...,
       [1.327e+01, 4.280e+00, 2.260e+00, ..., 5.900e-01, 1.560e+00,
        8.350e+02],
       [1.317e+01, 2.590e+00, 2.370e+00, ..., 6.000e-01, 1.620e+00,
        8.400e+02],
       [1.413e+01, 4.100e+00, 2.740e+00, ..., 6.100e-01, 1.600e+00,
        5.600e+02]])
        
wine.target
#结果
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2])
       
 #表格显示
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)

wine.feature_names
#结果
['alcohol',
 'malic_acid',
 'ash',
 'alcalinity_of_ash',
 'magnesium',
 'total_phenols',
 'flavanoids',
 'nonflavanoid_phenols',
 'proanthocyanins',
 'color_intensity',
 'hue',
 'od280/od315_of_diluted_wines',
 'proline']

wine.target_names
#结果
array(['class_0', 'class_1', 'class_2'], dtype='<U7')

#30%作为训练样本
Xtrain,Xtest,Ytrain,Ytest=train_test_split(wine.data,wine.target,test_size=0.3)

#实例化+建模+预测结果+精准度
clf=tree.DecisionTreeClassifier(criterion="entropy")
clf=clf.fit(Xtrain,Ytrain)
score=clf.score(Xtest,Ytest)
clf.predict(Xtest)
score
#结果
array([0, 2, 0, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 1, 1, 0, 2, 1,
       1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 2, 2, 0, 1,
       2, 2, 1, 2, 0, 0, 1, 1, 0, 2])
0.9259259259259259

#画出一棵树
feature_name=['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
import graphviz #需要安装graphviz
dot_data=tree.export_graphviz(clf
                             ,feature_names=featrure_name
                             ,class_names=['琴酒','雪梨','贝尔摩德']
                             ,filled=True
                             ,rounded=True
                             )
graph=graphviz.Source(dot_data)
graph

#显示特征重要程度
clf.feature_importance_
[*zip(feature_name,clf.feature_importance)]

调参优化

1.random_state & splitter
random_state用来设置分枝中的随机模式的参数,高维度特征中随机性会更加明显。输入任意整数,会长出同一棵树,让模型稳定
splitter也用来控制数中的随即选项,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还会优先选择更重要的特征进行分枝。输入“random”,决策树分枝时会更加随机,树会更深,对训练集的拟合将会降低。
调整这两个参数可以降低过拟合的可能性。

clf=tree.DecisionTreeClassifier(criterion="entropy")改为
clf=tree.DecisionTreeClassifier(criterion="entropy"
								, random_state=30
								, splitter="random")

2.剪枝参数
为了让决策树有更好的泛化性,我们要对决策树进行剪枝。剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心。

  • max_depth
    限制树的最大深度,超过设定深度的树枝都会被剪掉。
    在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求就会增加一倍,否则分枝就不会发生,所以可以限制树深来限制过拟合。建议从=3开始。
  • min_sample_leaf & min_samples_split
    min_sample_leaf规定分枝后的子节点必须至少包括min_sample_leaf个训练样本,否则分枝不会发生。设置过小会引起过拟合,设置太大会组织模型学习数据。建议从=5开始。
    min_sample_split规定,一个节点必须要包含min_sample_split个训练样本,才会分枝,否则不分枝。
clf=tree.DecisionTreeClassifier(criterion="entropy"
							, random_state=30
							, splitter="random"
							, max_depth=3
							, min_sample_leaf=10
							, min_sample_split=10
							)
  • max_feature & min_impurity_decrease
    max_feature限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。可用来限制高维度数据的过拟合。但降维方式防止过拟合更建议使用PCA,ICA或者特征选择模块中的降维算法。
    min_impurity_decrease限制信息增益的大小,信息增益小于设定数值分支不会发生。

如何确认参数
使用超参数的学习曲线,是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲线,它用来度量不同参数取值下模型表现的线。

#学习曲线求参数
import  matplotlib.pyplot as plt
test = [ ]
for i in range (10):
	clf = tree.DecisionTreeClassifier(max_depth=i+1
									, criterion="entropy"
									, random_state=30
									)
	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()

结果:
在这里插入图片描述
当man_depth=3时,模型达到最优。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值