ccc-sklearn-1-决策树

1.sklearn.tree模块中的类

tree.DecisionTreeClassifier 分类树
tree.DecisionTreeRegressor 回归树
tree.export_graphviz 将生成的决策树导出为DOT格式,画图专用
tree.ExtraTreeClassifier 高随机版本的分类树
tree.ExtraTreeRegressor 高随机版本的回归树

2.sklearn基本建模流程

ccc-sklearn-1-决策树_第1张图片
流程对应代码:

from sklearn import tree #导入需要的模块
clf = tree.DecisionTreeClassifier()     #实例化
clf = clf.fit(X_train,y_train) #用训练集数据训练模型
result = clf.score(X_test,y_test) #导入测试集,从接口中调用需要的信息

3.决策树的criterion参数

不纯度介绍:
1.衡量分类数的指标,数值越低说明拟合效果越好;
2.基于节点计算,每个结点都有不纯度;
3.子结点不纯度低于父节点,即叶子结点不纯度最低

criterion参数:
用来决定不纯度的计算方法,Entropy(信息熵)或者gini(基尼系数-默认)
ccc-sklearn-1-决策树_第2张图片
说明:
1.t代表指定结点,i代表标签的任意分类,p(i|t)代表标签分类i在节点t上所占比例
2.信息熵的计算基于信息增益,即父节点信息熵和子节点信息熵的差
3.信息熵对不存度更敏感,计算较基尼系数慢(对数)。
4.信息熵对于高纬数据和噪音较多的数据容易过拟合,此时基尼系数一般效果更好
5.模型在训练集合测试集上都表现不好时,即拟合程度不足时,使用信息熵

4.python构造一课决策树(红酒分类)

决策树的基本流程
在这里插入图片描述
步骤一:导入数据以及必要的库

from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
wine = load_wine()

ccc-sklearn-1-决策树_第3张图片
步骤二:合并数据表

import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)

ccc-sklearn-1-决策树_第4张图片
基本信息
ccc-sklearn-1-决策树_第5张图片
步骤三:划分数据集与训练集

Xtrain, Xtest, Ytrain, Ytest =train_test_split(wine.data,wine.target,test_size=0.75)

步骤四:调用DecisionTreeClassifier进行分类并且评估

clf = tree.DecisionTreeClassifier(criterion="entropy")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)

ccc-sklearn-1-决策树_第6张图片
步骤五:graphviz制图

feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']

import graphviz
dot_data = tree.export_graphviz(clf
                               ,feature_names = feature_name
                               ,class_names = ["琴酒","雪梨","贝尔摩德"]
                               ,filled=True 
                               ,rounded=True)
#filled:颜色,深度越深越纯 ;rounded:轮廓
graph = graphviz.Source(dot_data)

ccc-sklearn-1-决策树_第7张图片
步骤六:查看特征的重要性

clf.feature_importances_

ccc-sklearn-1-决策树_第8张图片

说明:

决策树在每次分枝时,不从使用全部特征,而是随机选取一部分特征,从中选取不纯度相关指标最优的作为分枝用的节点。所以即使每次划分的数据集合训练集一样,最后的结果还是不同

5.决策树中的其他参数

random_state & splitter

random_state:用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,低维度的数据(比如鸢尾花数据集),随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来。

splitter:用来控制决策树中的随机选项的,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝,输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。这是防止过拟合的一种方式。

剪枝参数

参数名 意义
max_depth 限制树的最大深度,超过设定深度的树枝全部剪掉
min_samples_leaf 一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生
min_samples_split 一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生
max_features 限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃
min_impurity_decrease 限制信息增益的大小,信息增益小于设定数值的分枝不会发生

说明:

  • max_depth:决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合。在集成算法中也非常实用。实际使用时,建议从=3开始尝试,看看拟合的效果再决定是否增加设定深度
  • min_samples_leaf:让模型变得更加平滑。参数设置得太小会引起过拟合,设置太大就会阻止模型学习数据。一般建议从5开始使用。如果叶节点中含有的样本量变化很大,建议输入浮点数作为样本量的百分比来使用。同时可以保证每个叶子的最小尺寸,可以在回归问题中避免低方差,过拟合的叶子节点出现。对于类别不多的分类问题,=1通常就是最佳选择
  • max_features :限制高维度数据的过拟合的剪枝参数,比较暴力,直接限制可以使用的特征数量而强行使决策树停下。在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足。如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法

目标权重参数

class_weight & min_weight_fraction_leaf

样本不平衡:在一组数据集中,标签的一类天生占有很大的比例。比如,在银行要判断“一个办了信用卡的人是否会违约”,就是是vs否(1%:99%)的比例。这种分类状况下,即便模型什么也不做,全把结果预测成“否”,正确率也能有99%。因此我们要使用class_weight参数对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。

class_weight 默认None,表示自动给与数据集中的所有标签相同的权重。有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_weight_fraction_leaf这个基于权重的剪枝参数来使用。另请注意,基于权重的剪枝参数(例如min_weight_fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分

6.其他重要的属性和接口

名称 作用
feature_importances_(接口) 查看各个特征对模型的重要性
apply 输入测试集返回每个测试样本所在的叶子结点的索引
predict 输入测试集返回每个测试样本的标签
说明:
  • 所有接口中要求输入X_train和X_test的部分,输入的特征矩阵必须至少是一个二维矩阵。
  • sklearn不接受任何一维矩阵作为特征矩阵被输入:
    1.如果数据只有一个特征,那必须用reshape(-1,1)来给矩阵增维
    2.如果你的数据只有一个特征和一个样本,使用reshape(1,-1)来给你的数据增维

7.回归树的criterion参数

ccc-sklearn-1-决策树_第9张图片
回归树中,没有标签分布是否均衡的问题,因此没有class_weight这样的参数。其它与分类数一模一样!

criterion参数

支持三种标准:

  1. MSE:输入mse使用均方误差,父节点与叶子结点之间均方误差的差值被用来当作特征选择的标准,通过使用叶子结点的均值来最小化L2损失
  2. friedman_mse:费尔德曼均方误差,对潜在分支中问题改进后的方法
  3. MAE:输入mae使用绝对平均误差,使用叶子结点的中值来最小化L1损失

MSE表达式:本质是样本真实数据与回归结果的差异
M S E = 1 n ∑ i = 1 N ( f i − y i ) 2 MSE=\frac{1}{n}\sum_{i=1}^{N}(f_i-y_i)^2 MSE=n1i=1N(fiyi)2

  • N为样本数量,i为每一个数据样本, f i f_i fi是模型回归出的数值, y i y_i yi是样本实际的数值标签

  • 回归树接口score返回R的平方(越接近1越好),而不是MSE。R定义为:
    R 2 = 1 − u v R^2=1-\frac{u}{v} R2=1vu
    u = ∑ i = 1 N ( f i − y i ) 2 v = ∑ i = 1 N ( y i − y ^ ) 2 u=\sum_{i=1}^{N}(f_i-y_i)^2 \qquad v=\sum_{i=1}^{N}(y_i-\widehat{y})^2 u=i=1N(fiyi)2v=i=1N(yiy )2
    u是残差平方和,v是总平方和,N是样本数量,i是每一个数据样本,fi是模型回归出的数值,yi是样本点i实际的数值标签。y帽是真实数值标签的平均数。R平方可以为正为负,而均方误差永远为正。

  • 虽然均方误差永远为正,但是sklearn当中使用均方误差作为评判标准时,却是计算”负均方误差“。这是因为sklearn在计算模型评估指标的时候,会考虑指标本身的性质,均方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss),因此在sklearn当中,都以负数表示。真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字。

8.交叉验证

交叉验证是用来观察模型的稳定性的一种方法,将数据划分为n份,依次使用其中一份作为测试集,其他n-1份作为训练集,多次计算模型的精确性来评估模型的平均准确程度。训练集和测试集的划分会干扰模型的结果,因此用交叉验证n次的结果求出的平均值是对模型效果的一个更好的度量。

简单代码举例:

from sklearn.datasets import load_boston
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeRegressor
boston = load_boston()
regressor = DecisionTreeRegressor(random_state=0)
cross_val_score(regressor, boston.data, boston.target, cv=10)

ccc-sklearn-1-决策树_第10张图片

9.一维回归图像的绘制

步骤一:所需库的导入,以及numpy创建训练集

import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
rng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80,1),axis=0)
y = np.sin(X).ravel()
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data")

ccc-sklearn-1-决策树_第11张图片
步骤二:制造噪音

y[::5] += 3*(0.5 - rng.rand(16))
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data")

ccc-sklearn-1-决策树_第12张图片
步骤三:实例化深度为2和5的模型

regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)

ccc-sklearn-1-决策树_第13张图片

步骤四:导入测试集并开始预测

X_test = np.arange(0.0,5.0,0.01)[:,np.newaxis] 
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)

在这里插入图片描述

步骤五:图像的绘制

plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange",label="data")
plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=2",linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen",label="max_depth=5",linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()

ccc-sklearn-1-决策树_第14张图片
可见,回归树学习了近似正弦曲线的局部线性回归。如果树的最大深度设置得太高,则决策树学习得太精细,它从训练数据中学了很多细节,包括噪声得呈现,从而使模型偏离真实的正弦曲线,形成过拟合。

10.泰坦尼克幸存者预测

步骤一:库与数据的导入

import pandas as pd
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pylab as plt
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
data = pd.read_csv("./data/data.csv")
data.info()

ccc-sklearn-1-决策树_第15张图片
步骤二:数据预处理
Cabin、Name、Ticket无关紧要,删除!

data.drop(['Cabin','Name','Ticket'],inplace=True,axis=1)
# 记住,axis=1表示列

ccc-sklearn-1-决策树_第16张图片
说明:axis参数的理解

Age缺失200左右,且是连续值,需要填充!
Embarked 只缺两个,直接删!

ccc-sklearn-1-决策树_第17张图片
处理字符型的数据,转成数字

labels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
data["Sex"] = (data["Sex"] == "male").astype("int")
data.head()

ccc-sklearn-1-决策树_第18张图片
步骤三:划分数据,跑模型

x = data.iloc[:,data.columns != "Survived"]
y = data.iloc[:,data.columns == "Survived"]

from sklearn.model_selection import train_test_split
Xtrain, Xtest ,Ytrain, Ytest = train_test_split(x,y,test_size=0.3)

for i in [Xtrain, Xtest ,Ytrain, Ytest]:
    i.index = range(i.shape[0])
    
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score

ccc-sklearn-1-决策树_第19张图片
步骤四:绘制不同max_depth的拟合情况

tr = []
te = []
for i in range(10):
    clf = DecisionTreeClassifier(random_state=25
                                ,max_depth=i+1
                                )
    clf = clf.fit(Xtrain,Ytrain)
    score_tr = clf.score(Xtrain,Ytrain)
    score_te = cross_val_score(clf,x,y,cv=10).mean()
    tr.append(score_tr)
    te.append(score_te)
print(max(te))
plt.plot(range(1,11),tr,color="red",label="train")
plt.plot(range(1,11),te,color="blue",label="test")
plt.xticks(range(1,11))
plt.legend()
plt.show()

ccc-sklearn-1-决策树_第20张图片
步骤五:Grid网格搜索寻找最佳参数

import numpy as np
gini_threholds = np.linspace(0,0.5,50)
parameters = {"criterion":("gini","entropy")
              ,"splitter":("best","random")
              ,"max_depth":[*range(1,10)]
              ,"min_samples_leaf":[*range(1,50,5)]
              ,"min_impurity_decrease":[*np.linspace(0,0.5,50)]
    
}
clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf,parameters,cv=10)
GS = GS.fit(Xtrain,Ytrain)

GS.best_params_
GS.best_score_

ccc-sklearn-1-决策树_第21张图片

决策树总结:

优点:

  1. 易于理解和解释,是一个白盒模型。
  2. 需要很少的数据准备。其他很多算法通常都需要数据规范化,需要创建虚拟变量并删除空值等。
  3. 树的成本(比如说,在预测数据的时候)是用于训练树的数据点的数量的对数,相对其它算法成本很低。
  4. 能同时处理数字和分类数据,既可以做回归又可以做分类。
  5. 能含有多个标签的问题,注意与一个标签中含有多种标签分类的问题区别开。

缺点:

  1. 可能创建过于复杂的树,称为过度拟合。修剪,设置叶节点所需的最小样本数或设置树的最大深度等机制是避免此问题所必需的,而这些参数的整合和调整对初学者来说会比较晦涩
  2. 决策树可能不稳定,数据中微小的变化可能导致生成完全不同的树,这个问题需要通过集成算法来解决。
  3. 决策树的学习是基于贪婪算法,它靠优化局部最优来试图达到整体的最优,但这种做法不能保证返回全局最优决策树。这个问题也可以由集成算法来解决,在随机森林中,特征和样本会在分枝过程中被随机采样。
  4. 有些概念很难学习,因为决策树不容易表达它们,例如XOR,奇偶校验或多路复用器问题。
  5. 如果标签中的某些类占主导地位,决策树学习者会创建偏向主导类的树。因此,建议在拟合决策树之前平衡数据集。

你可能感兴趣的:(sklearn,sklearn,决策树)