ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

sklearn的学习笔记--决策树(1)

2021-10-23 16:33:01  阅读:180  来源: 互联网

标签:plt taitanic -- 数据 import sklearn data 决策树


1、决策树

1.1 分类树

在sklearn中所有的机器模型算法都可以简化为三行代码。

image-20211021201130667

对应的代码如下所示:

# 第一步骤:实例化一个决策树的模型,其中criterion代表决策树进行决策的准则,有gini和entropy两种方法
clf = tree.DecisionTreeClassifier(criterion="entropy")
# 第二步骤:将之前准备好的数据喂入决策树,将其对应的数据和标签成组输入
clf = clf.fit(Xtrain,Ytrain)
# 第三步骤:准备通过train_test_split方法得到的切分后的数据集进行测试,输出内容为对应的acc得分
score  = clf.score(Xtest,Ytest)

在本实验中,我我们采用红酒数据集来进行辅助的学习:

# 第一步:导入已经处理好的红酒数据集
from sklearn.datasets import load_wine
# 第二部:实例化这个数据集接口
wine = load_wine()
# 第三步(选):将数据集可视化操作,记住concat中需要给定对应合并到维度条件
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target),axis=1])
# 如下是对应的可视化数据集的结果

image-20211021201742385

# 拿到了wine整体的数据集,但是没有区别训练集和验证集两种不同的状态
Xtrain,Xtest,Ytrain,Ytest = train_test_split(wine.data, wine.target, test_size=0.3)
# 到此为止,所有的准备工作都已经完成了
# 接下来,执行sk三部曲,并输出你的得分,就可以渐渐看见你需要的树的得分了

决策树可视化

可是?我的树在哪呢?我怎么看不见,因此将我们的决策树实例化就显得非常重要了。

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

image-20211021202900836

这个树还是比较大的,但是我们可以发现其实在我们的训练数据中,拥有者13个不同的指标及其对应的数据,但是为什么这儿只有这点不同的决策条件呢?

这是因为:决策树本身就具有一定的随机性,在实例化对应的决策树的时候,内部有不少的参数采用了默认的设置内容,包括random_state这类随机种子,因此多次执行上述的三部曲,都有可能出现不同的数值;就决策树本身而言,无论模型如何进化,本质上都在某个不纯度相关的指标上进行优化。因此,集成算法被用来解决这个问题:sklearn表示,既然一棵树不能保证最优,那就建更多不同的树没然后从其中挑选出最好的树。这样,也就导致了每次都会生成一些结果不同的树。

那么?哪些参数会影响我们的树模型呢?

随机参数

  • random_state:随机种子,默认为None,表示每一次建立决策树的时候都随机,在高维度特征上表现明显,如果固定输入整数,则会让模型稳定下来,只输出一个树。
  • splitter:best or random 表示决策树分支时候的策略,选择best时候,会根据属性feature_importances来进行。
clf.feature_importances_
# 获得决策树的属性,输出其中的关键分类点
# 将zip函数将名字和其对应的全书组成元组,并输出,可以更直观的看到哪一个数据起到决定性作用
[*zip(feature_name,clf.feature_importances_)]

image-20211021205640840

剪枝参数

决策树的模型也并非越深越好,当模型足够深就会出现过拟合的情况,因此我们应当对模型进行限制,防止其出现过拟合的情况

  • max_depth:限制树的最大深度,将超过设定深度的树枝全部剪掉
  • min_samples_leaf: 决定了一个节点在分支后的每个字典姐必须包含至少X个训练样本,否则不会进行分支,或者香可以分支的方向发展,一般搭配max_depth使用,太小和太大都会导致意想不到的情况发生,因此要进行不断的验证并且结合自己的经验。
  • min_samples_split: 刚才的参数决定了叶子节点中个数的,现在这个决定了节点必须要包含Y个样本,才可以被允许分支,否则不会发生这样的问题。
  • max_features: 限制建树时候的对于特征的选择,比较暴力,建立搭配PCA或者ICA这种降维算一起使用
  • min_impurity_decrease: 用来限制信息增益的带下,如果信息增益小于设定的数值分支就不会发生。

分类树总结

  • 八个参数
  • 一个属性
  • 四个接口:fit、score、apply、predict(其中apply返回对应的索引,predict返回对应的标签)

1.2 回归树

回归树主要不同于决策树的在于其关于label的预测并不是一个指定的,出现截断式的输出,而是一种体现连续化的分布,更多的是拟合一条比较好的曲线去代替其中对应的内容。

回归树衡量分支质量的指标支持三种不同的标准:

  • mse使用均方误差mean squared error
  • friedman_mse费尔德曼均方误差,这种指标主要针对潜在分支中的问题改进后的均方误差
  • mae是u用绝对值平均误差mean absolute error

在本次学习中,我们采用波士顿房价来进行训练,在sklearn中提供相应的数据集用于学习模型

from sklearn.tree import DecisionTreeRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import cross_val_score
import pandas as pd
boston = load_boston()
# 将波士顿房价进行可视化的输出来展示
pd.concat([pd.DataFrame(boston.data),pd.DataFrame(boston.target)],axis=1)

image-20211022152147654

根据上图我们可以检出,一种拥有13个不同的指标如下所示,其中最后为其对应的标签。

array([‘CRIM’, ‘ZN’, ‘INDUS’, ‘CHAS’, ‘NOX’, ‘RM’, ‘AGE’, ‘DIS’, ‘RAD’, ‘TAX’, ‘PTRATIO’, ‘B’, ‘LSTAT’], dtype=’<U7’)

搭建模型三部曲

regressor = DecisionTreeRegressor(random_state=0)
cross_val_score(regressor, boston.data, boston.target, cv=10)

#array([ 0.48141081,  0.60461936, -1.32633384,  0.54154398,  0.75705408,
#        0.33934083,  0.18757206,  0.40679147, -1.9602183 , -0.32967889])
# 利用数据交叉认证来完成对应,其中cv表示对应的数据需要加载的次数,默认的评价指标采用的是R平方来操作数据分布为[-∞,1]

regressor = DecisionTreeRegressor(random_state=0)
cross_val_score(regressor, boston.data, boston.target, cv=10,scoring="neg_mean_squared_error")

# 同上,-mse的数据分布为[-∞,0]
#array([-18.08941176, -10.61843137, -16.31843137, -44.97803922,
#      -17.12509804, -49.71509804, -12.9986    , -88.4514    ,
#     -55.7914    , -25.0816    ])

实例一:一维回归的图像绘制,拟合正弦函数

# 导入一些必要的包
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() # 去除矩阵中一些无用的维度信息,np中的降维函数
# 为生成的数据添加一些扰动来干扰模型,模拟显示数据可能存在的问题
y[::5] += 3*(0.5 -rng.rand(16))
# 生成三种不同的回归树,深度设置成2、3、5来展示
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_3 = DecisionTreeRegressor(max_depth=3)
# 对三个模型喂入一定的数据
regr_1.fit(X,y)
regr_2.fit(X,y)
regr_3.fit(X,y)
# 生成序列化的数据用于测试,病假数据插入对应的模型中进行测试
Xtest = np.arange(0.0, 5.0, 0.01)[:,np.newaxis]
y_1 = regr_1.predict(Xtest)
y_3 = regr_2.predict(Xtest)
y_5 = regr_3.predict(Xtest)
# 可视化视图
plt.figure()
plt.scatter(X,y,s=20,edgecolors="black",c='darkorange',label='data')
plt.plot(Xtest,y_1,color="blue",label='max_2',linewidth=2)
plt.plot(Xtest,y_3,color="green",label='max_5',linewidth=2)
plt.plot(Xtest,y_5,color="yellow",label='max_3',linewidth=2)
plt.xlabel('data')
plt.ylabel('target')
plt.title('Decision Tree Regression')
plt.legend()
plt.show()

image-20211022161350224

实例二:泰坦尼克号数据

泰坦尼克号的沉没是迄今为止最大的海难吗,但在sklearn中并没有提供其对应的数据集,可以在kaggle中找到对应的数据。

# 导入可能使用的方法
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import GridSearchCV,train_test_split,cross_val_predict

# 导入对应的数据集,具有data和test两个数据集,其中test数据集并没有对应的label,主要用于比赛中。
taitanic_data = pd.read_csv("Taitanic_data/data.csv")

如下是taitanic_data数据集的展示:

image-20211022195902467

# 输出数据的头部数据,大概5个,也可以在head中写入需要展示的数据个数
taitanic_data.head()
# 输出数据的信息
taitanic_data.info()
# info中的信息更为具体,可以看见对应的列数和其格式还有是否为空,对后续的数据集操作都有比较好的效果和帮助

image-20211022200203247

在上图中可以发现,其中存在一定的缺失值,age确实的内容较少且age确实会对是否存活有着比较大的影响。类似于Cabin这种无效的且缺失严重的内容可以将其抛弃。类似对于是否存活无关的数据还有Name和Ticket等信息。

# 删除一些无用的数值来进行,可以提前判断某些内容是否影响对应的结果
taitanic_data.drop(['Cabin','Name','Ticket'],inplace=True,axis=1)

image-20211022202634737

如上图就是经过drop操作后的数据,除去了一些无用的特征信息来使得数据更为精纯。

# 处理缺失值,对缺失值较多的列进行填补,如果有些特征确实缺少太多数据,完全可以删除对应的记录
taitanic_data['Age'] = taitanic_data['Age'].fillna(taitanic_data['Age'].mean())
taitanic_data = taitanic_data.dropna()
# 将分类变量转换为数值型变量
# 方法一:主要针对于二分类特征0~1,可以定义某一个数值为True,另一种就是False,然后通过astype()
taitanic_data['Sex'] = (taitanic_data['Sex']=='male').astype('int')
# 方法二:将三分类变量转换为数值型变量
# 将对应的数据转换成为,可以理解为set操作,将重复的数值去掉,转换成list后续可以用来获取对应的下标用来代替标签
labels = taitanic_data['Embarked'].unique().tolist()
taitanic_data['Embarked'] = taitanic_data['Embarked'].apply(lambda x: labels.index(x))

image-20211022204824769

执行上述代码的时候可以发现,会有warning的提醒跳出,如下所示

image-20211022205436451

这里提醒我们最好使用 loc()方法来帮助实现刚才对应任务。

x = taitanic_data.iloc[:,taitanic_data.columns != 'Survived']
y = taitanic_data.iloc[:,taitanic_data.columns == 'Survived']
# 需要注意一下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])
Xtrain.head()

image-20211022212915140

# 训练模型
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(Xtrain,Ytrain)
score_ = clf.score(Xtest,Ytest)
# 0.7715355805243446
score = cross_val_socre(clf,x,y,cv=10).mean()
# 0.7212391248121231
# 效果还是太差了,想办法提升一下对应的效果,针对于通道的max_depth进行调整
tr = []
te = []
n = 10
for i in range(n):
    clf = DecisionTreeClassifier(random_state=3,max_depth=i+1,criterion='entropy')
    clf.fit(Xtrain,Ytrain)
    score_tr = clf.score(Xtest,Ytest)
    score_te = cross_val_score(clf,x,y,cv=10).mean()
    tr.append(score_tr)
    te.append(score_te)
print(max(te))
plt.figure()
plt.plot(range(1,n+1),tr,color='red',label='train')
plt.plot(range(1,n+1),te,color='blue',label='test')
plt.xticks(range(1,n+1))
plt.legend()
plt.show()
# 输出的图片如下所示

image-20211022215219410

可以看出,在max_depth=3的时候,效果是最好的。

加餐:网格搜索

# 为了更好的显示数据,搜索出一个比较好的效果,
import numpy as np
# 设置基尼系数的边界,一般取值在(0,0.5)之间,其中每个参数都会倍用来搜索
gini_thresholds = np.linspace(0,0.5,20)
parameters = {
    'criterion':('gini','entropy'),
    'splitter':('best','random'),
    'max_depth':[*range(1,11)],
    'min_samples_leaf':[*range(1,50,5)]
    ,'min_impurity_decrease':[*np.linspace(0,0.5,20)]
}
# 设置好对应的网格搜索内容后可以进行决策树的网格搜索
clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf,parameters,cv=10)
GS.fit(Xtrain,Ytrain)

GS.best_score_

利用网格搜索,可以得到对应的搜索数据,但是GridSearch并不会让你的模型有意识的选择部分参数,因此如果在parameters中设定的参数都会参与到网络的选择中,但是根据结果发现,其实通过criterion和max_depth就可以较好的选择出一个模型,其他参数的设定会导致模型效果下降。

GS.best_params_
# 将最好的parameters进行输出,得到最好的效果
{'criterion': 'gini',
 'max_depth': 7,
 'min_impurity_decrease': 0.0,
 'min_samples_leaf': 6,
 'splitter': 'best'}
 
 GS.best_score_
 # 输出网格搜索中最好的得分
 0.829390681003584

实例三:在合成数据集上的表现

就决策树而言,不同的数据分布也会影响其在数据上的不同表现,接下来我们用实验的方式进行探究。看看究竟在那种模式上,决策拥有比较好的效果呢?

# 导入一些常用的库
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 从sklearn数据集中分别导入月亮、环形、分类三种不同的数据集,用于后期探究何种数据上分类效果更好?
from sklearn.datasets import make_noons, make_circles, make_classification
from sklearn.tree import DecisionTreeClassifier

生成数据和数据可视化

# 利用对应的api生成对应的数据来展示
# 其中n_samples表示生成多少个样本,n_features指的是样本的维度,n_redundant表示冗余特征个数
# n_informative表示包含信息的特征个数,n_clusters_per_class表示每个簇内的类别个数
x,y = make_classification(n_samples=100,n_features=2,n_redundant=0,n_informative=2,random_state=2,n_clusters_per_class=1)

class_a = []
class_b = []
for i in range(100):
    if y[i]==0:
        class_a.append(list(x[i]))
    else:
        class_b.append(list(x[i]))
class_a = np.array(class_a)
class_b = np.array(class_b)
plt.figure()
plt.scatter(class_a[:,0],class_a[:,1],color='red')
plt.scatter(class_b[:,0],class_b[:,1],color='blue')
plt.show()

如下是对应的可视化结果

image-20211023150259307

可以发现,通过这样生成的图片,具有一个比较明显的分类决策边界,为了使得模型具备鲁棒性,我们给我们的模型添加一定的干扰噪声。

rng = np.random.RandomState(2) # 生成一种随机模式
x += 2* rng.uniform(size=x.shape) # 生成一个和x矩阵大小一致的新矩阵
linearly_separable = (x,y)

# 将三种的数据集整合变,并且打包放在datasets中
datasets = [make_moons(noise=0.3,random_state=0),
            make_circles(noise=0.2,factor=0.5,random_state=1),
            linearly_separable]

image-20211023150659802

1.3 决策树的优缺点

优点

  • 易于解释和理解,因为可以将树结构可视化实现
  • 并不需要大量的数据进行训练
  • 可是显示回归和分类,方法具有普适性
  • 能够处理多输出问题
  • 白盒模型
  • 具有一定的容错率,具备鲁棒能力

缺点

  • 决策树学习者可能创建过于复杂的树,这些树不能很好 推广数据。
  • 决策树是不稳定的,其中微笑的变化可能会导致生成完全不同的树
  • 决策树的学习是基于贪婪算法的,可能会局部最优,但不能保证全局最优
  • 如果标签中某一个类占有主要地位,那么决策树会创建一个偏向主导类的树。因此,对于数据集有一定的要求。

标签:plt,taitanic,--,数据,import,sklearn,data,决策树
来源: https://blog.csdn.net/qq_44747847/article/details/120922611

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有