机器学习sklearn实战----决策树
一边学习一边记录
@机器学习sklearn实战----决策树
前言
决策树(Decision Tree)是一种非参数的有监督学习方法,它能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。决策树算法容易理解,适用各种数据,在解决各种问题时都有良好表现,尤其是以树模型为核心的各种集成算法,在各个行业和领域都有广泛的使用
一、决策树一些重要参数
(1)criterion:对于分类树而言,衡量最佳节点和最佳分枝的指标叫做“不纯度”,不纯度越低,决策树对训练集的拟合越好。criterion这个参数是用来决定不纯度计算的方法。
在sklearn中有两种:entropy 使用信息熵 gini使用基尼系数
那我们如何选取这两个参数呢?
1.不填默认使用基尼系数,填写entropy使用信息熵
2在数据维度比较大,噪声很大时使用基尼系数。
3.纬度低和数据比较清晰的时候,信息熵和基尼系数没有什么区别。
4.当决策树的拟合程度不够时,使用信息熵。
(2)random_state用来设置分枝中的随机模式的参数,高纬度时随机性会表现明显。
splitter也是用来控制决策树中随机选项,有两种情况,‘best’决策树在分枝时苏安然虽然随机,但是会优先选取更更重要的特征进行分枝,‘random’在分枝时比较随机。
(3)剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心。
1.max_depth:限制树的最大深度,超过设定深度的树枝全部剪掉
2.min_samples_leaf & min_samples_split:一个节点后在分枝后的子节点都必须包含至少min_samples_leaf个训练样本,min_samples_split限定一个节点必须包含至少这么多个训练样本,这个节点才会被允许分枝。
3.max_features & min_impurity_:max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃,min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生。这是在0.19版本中更新的功能,在0.19版本之前时使用min_impurity_split。
二、确定最优的剪枝参数
根据超参数的曲线
代码如下(示例):
import matplotlib.pyplot as plt
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(criterion='entropy'
,random_state=30
,splitter='random'
,max_depth=i+1 #最大深度
,min_samples_leaf=10#一个节点在分枝后的每个子节点都包含至少min_samples_leaf个训练样本
,min_samples_split=10 #一个节点必须要包含至少min_samples_split个训练样本
#,max_features= 限制分枝时考虑特征的个数,超过限制个数的都会被舍弃
)
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()
三、泰坦尼克号预测
读入数据
代码如下(示例):
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score,GridSearchCV
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
data = pd.read_csv('data/data.csv',index_col=0)
data.info()
对数据进行预处理
data.drop(['Name','Cabin','Ticket'],inplace=True,axis=1) #删除数据中不要的字段 按列作用
#处理缺失值
data['Age'] = data['Age'].fillna(data['Age'].mean())
data = data.dropna()#删除数据中空缺值
#对分类数据进行处理 变为数值型数据 sex Embarked
data['Sex'] = (data['Sex']=='male').astype('int')
#将三分类变量转换为数值型变量
labels = data['Embarked'].unique().tolist()
data['Embarked'] = data['Embarked'].apply(lambda x: labels.index(x))
划分测试集与训练集
#提取标签和特征矩阵,分测试集与训练集
x = data.iloc[:,data.columns!='Survived']
y = data.iloc[:,data.columns=='Survived']
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.3)
for i in [x_train,x_test,y_train,y_test]: #修正训练集与测试集的下标
i.index = range(i.shape[0])
x_train
训练模型
model = tree.DecisionTreeClassifier(random_state=25)
model = model.fit(x_train,y_train)
score_ = model.score(x_test,y_test)
score_ #打印输出精确度
确定最大树深
tr = []
te = []
for i in range(10):
model = tree.DecisionTreeClassifier(random_state=25
,max_depth=i+1
,criterion='entropy')
model = model.fit(x_train,y_train)
score = model.score(x_train,y_train)
score_= cross_val_score(model,x,y,cv=10).mean()
tr.append(score)
te.append(score_)
print("最好的预测精度为:",max(te))
plt.plot(range(1,11),tr,color = 'red',label = 'train')
plt.plot(range(1,11),te,color = 'g',label = 'test')
plt.legend()
plt.show()
可以发现使用超参数曲线来确定树深并不是很合理。
使用网格搜索和交叉验证
gini_ = np.linspace(0,0.5,20)
parameters = {'splitter':('best','random'),'criterion':("gini","entropy"),"max_depth":[*range(1,10)],'min_samples_leaf':[*range(1,50,5)],'min_impurity_decrease':[*np.linspace(0,0.5,20)]}
model = tree.DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(model,parameters,cv = 10)
GS = GS.fit(x_train,y_train)
GS.best_params_ #网格搜索之后最好的参数
GS.best_score_ #最高的精确度
四、总结
决策树优缺点
优点
1.易于理解和解释
2.需要很少的数据准备
3.能够同时处理数字和分类数据,可以做回归也可以做分类
4.即使其假设在某种程度上违背了生成数据的真实模型。也能够表现良好。
缺点
1.决策树可能不稳定,数据中微小的变化可能导致生成完全不同的树。这个问题需要集成算法来解决
2.决策树的学习是基于贪婪算法,靠优化局部最优(每个节点的最优)来试图达到整体的最优。
3.如果标签中的某些类占主导地位,决策树学习者会创建偏向主导类的树。因此,建议在拟合决策树之前平衡数据集。
4.决策树不容易解决XOR多路复用器问题。