Python机器学习——决策树


# 模型用途:既可以分类,也能解决回归问题
###主要还是应用分类决策树:本质是从训练数据集中归纳出一组分类规则,称为树归纳。对于给定的训练集,存在许多对他无错编码的树。为了简单起见,我们选出最小的树。
简单来说是决策树学习是由训练数据集估计条件概率模型。基于特征空间划分的类的条件概率模型由很多,训练模型既要对训练数据由很好的拟合,也要对未知数据有很好的预测。
###决策树学习算法包含特征选择、决策树的生成、决策树剪枝。决策树生成只考虑局部最优,剪枝考虑的是全局最优。
###特征选择依据:香农熵和信息增益.
   决策树需要选择最优划分属性,节点的纯度越高越好。在分类树里面,划分的优劣用不纯度度量。不纯度越低,类分布就越倾斜。
   度量不纯性的函数是包括熵函数、基尼系数、分类误差。通常情况2分类较多,也可以推广到大于2的分类。熵越高,信息不纯度越高,则混合的数据越多。信息熵是对整个数据集来讲的,计算的是分类的信息熵
   信息增益:决策树最终的优化目标使得叶节点的总不纯度最低,即对应衡量不纯度的指标最低。要求父节点的信息熵和子节点的信息熵差要最大。
#用sklearn生成决策树
###参数criterion:决定不纯度的计算方法。
        # 输入entropy,使用信息熵(enteropy)

       #输入gini,使用基尼系数(jini):适用于数据维度大,噪音很大时。
        
#一般2个都试一下,哪个好用哪个。通常信息熵多一点。
#初步建模
##导入需要的算法库和模块。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

plt.rcParams['font.sans-serif'] = ['Simhei']
plt.rcParams['axes.unicode_minus']= False
#探索数据
wine =load_wine()
#wine
#wine.data.shape
#wine.target

#将wine的特征数据和标签横向拼接
wine_pd = pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1).head()
#wine_pd
wine.feature_names.append('result')
wine_pd.columns=wine.feature_names #设置列名
#wine_pd
#切分数据集,训练集和测试集
Xtrain,Xtest,Ytrain,ytest =  train_test_split(wine.data,wine.target,test_size=0.3,random_state=420)
Xtrain.shape
Xtest.shape
#建立模型
clf = tree.DecisionTreeClassifier(criterion='gini')
clf = clf.fit(Xtrain,Ytrain)
clf.score(Xtest,ytest)#返回预测的准确率

#画一棵树,安装Graphviz,pip install graphviz
#import os
#os.environ["PATH"] += os.pathsep + r'C:\Program Files\Graphviz\bin/'

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

dot_data = tree.export_graphviz(clf,out_file=None,feature_names=feature_name,
                                class_names=['琴酒','雪梨','贝尔摩德'],
                                filled=True,
                                rounded=True)
'''feature_names:每个属性的名字
   class_names:每个因变量类别的名字
   "label:是否显示不纯度信息的标签,默认为all都显示,可以是root或者none
   filled:是否给每个节点的主分类绘制不同的烟丝,默认为False
   out_file:输出的dot文件的名字,默认为none表示不输出文件,可以自定义名字'''
graph = graphviz.Source(dot_data)
graph
#graph.render('wine')#pdf打开后会有中文乱码问题
#解决方案:jupyter 页f12打开控制台,选中图片的代码的第一行output,复制,
#新建一个文本粘贴代码保存关闭。修改文件名后缀为html然后通过打印的方式出来。

#探索决策树的属性
#显示每一个特征的重要性
clf.feature_importances_
[*zip(feature_name,clf.feature_importances_)]#将对象中对应的元素打包成一个个元祖返回
#返回每个预测样本的叶子索引
clf.apply(Xtrain)
#树的节点树
clf.tree_.node_count
#每个节点对应的属性索引值,-2,表示叶节点
clf.tree_.feature
#防止过拟合,查看我们的树对训练集的拟合程度
score_train = clf.score(Xtrain,Ytrain)
score_train
#结果是百分百了,过拟合了需要增加泛化性。通过剪枝来解决。
#random_state:用来设置分支中的随机模式的参数。
#splitter:用于控制决策树的随机选项:
  #best,决策树在分支时会优先选择更重要的特征分支
  #random,决策树在分支时更加随机,防止过拟合的一种方式
clf = tree.DecisionTreeClassifier(criterion='entropy',
                                 random_state=30,
                                 splitter='random')
clf = clf.fit(Xtrain,Ytrain)
score = clf.score(Xtest,ytest)
score
plt.rcParams['font.sans-serif'] = ['Simhei']
plt.rcParams['axes.unicode_minus'] = False
#剪枝参数:max_features,用于限制高纬度数据的过拟合的剪枝参数,用的比较少
        #min_impurity_decrease:限制信息增益大小。
       # max_depth:限制树的最大深度,通常从3开始。一般用作树的精修,应用广泛,集成算法中也实用
        #min_samples_leaf:一个节点在分支后的每个子节点都必须包含至少min_samples_leaf个训练样本
        #                   一般搭配max_depth使用。建议从5开始,也可以使用浮点数。
        #min_samples_split:一个节点必须要包含至少该参树个训练样本,这个节点才被允许分支,否则不回发生。
#确定最优的剪枝参数:使用确定超参数的曲线来判断。
test=[]
for i in range(10):
    clf = tree.DecisionTreeClassifier(max_depth=i + 1,
                                     criterion='entropy',
                                     random_state=30,
                                     splitter='random')
    clf = clf.fit(Xtrain,Ytrain)
    score = clf.score(Xtest,ytest)#记录下不同max_depth下模型在测试集分数
    test.append(score)
#test
plt.plot(range(1,11),test,color='red',label='学习曲线')
plt.ylabel('score')
plt.xlabel('max_depth')
plt.legend()
plt.show();
总结:
   属性是在模型训练之后能够调用查看的模型的各种性质,对决策树来书,最重要的是feature_importances_,能够查看各个特征对模型的重要性。
   apply中输入测试集返回每个测试样本所在的叶子节点的索引。
   predict输入测试集返回每个测试样本的标签。
   sklearn不接受任何一维矩阵作为特征被输入,如果只有一个特征,需要reshape(-1,1)来给矩阵增维。
  核心:分类树8个参数,一个属性,4个接口。
  criterion
  2个随机性相关参数(random_state,spliter):
  5个剪枝参数
  一个属性:feature_importances_
  4个接口:fit,score,apply,predict;
### 分类模型的评估指标
#### 样本不均匀问题
### 可以通过
class_weight :位于decisiontreeclassifier中。默认为None,此模式假####设数据集中的所有样本是均衡的。当样本不均衡是,通过字典模式传入真实的样本标签比例,如{‘标签值1:权重1’,‘标签值2:权重2’},手动调整倾斜。或者使用balanced模式。
sample_weight:fit接口中可以设定权重。
混淆矩阵:比如银行的风控系统会用到。一个多维衡量指标体系,在样本不平衡时十分有用。
     在混淆矩阵中,少数类是正例,多数类是负例。
     在决策树、随机森林这些分类算法例,少为1,多数类为0。
     在svm里,少数类是1,多数类为0.
     混淆矩阵模型整体效果评估指标:准确率accuracy.精确度precision(将多类判错后所需付出成本的衡量)、召回率recall,f1meansure同时兼顾精确度和召回率,roc曲线。后面2个比较重要。
#sklearn 中的混淆矩阵,导入metrics包
sklearn.metrics.confusion_matrix       混淆矩阵
sklearn.metrics.accuracy_score        准确率
sklearn.metrics.percision_score       精确度
sklearn.metrics.recall_score         召回率
sklearn.metrics.precision_recall_score  roc曲线
sklearn.metrices.f1_score          f1 measure

以上后面参数(ytest,模型名称.predict(xtest))#计算的是一个比值

你可能感兴趣的:(机器学习,决策树,python)