zoukankan      html  css  js  c++  java
  • 分类算法之决策树

    一、决策树概述

    1、决策树思想

      决策树思想的来源非常朴素,它来源于程序设计中的条件分支语句结构(if-then),最早的决策树就是利用这类结构分割数据的一种分类方法。例如,银行贷款是根据贷款人的各种条件来进行判断是否放贷:

    可以看到银行贷款可以根据上面的条件依次进行判断,其中很重要的是为什么将是否有房子这个条件先进行判断呢?这也是决策树划分的核心,它的理论来源于信息论。

    2、信息熵

      信息论中很重要的一个概念就是信息熵,何为信息熵?在信息论中表述了信息的单位是比特,信息熵是衡量信息量的大小,假设现在有32支球队进行比赛,希望你来猜测一下那一支球队能取得胜利,那么最少的猜测次数应该是5。那么它的信息熵就是:

    [H = - ({P_1}log {p_1} + {P_2}log {p_2} + ... + {P_{32}}log {p_{32}})]

    其中,P1...p2表示的是每一支球队获胜的概率(理论上来说都是1/32,所以对应的信息熵H=5)。H为信息熵,单位为比特。

    公式为:

    [H(X) = sum olimits_{X in X} {{P_{(x)}}log {p_{(x)}}} ]

    3、信息增益

      信息增益是决策树的划分依据之一,表示得知特征X的信息而使得类Y的信息的不确定性减少的程度,比如:上面银行贷款中将是否有房放在第一位,这样会让该后面的判断的不确定性减少的更多,从而判断出是否贷款。这种不确定减少的程度就是信息增益。

      特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:

    [g(D,A) = H(D) - H(D|A)]

     假设下面是贷款的一些信息:

    ID

    是否有房子

    是否有工作

    信贷情况

    类别

    1

    非常好

    2

    一般

    3

    4

    5

    一般

    6

    非常好

    7

    8

    一般

    9

    一般

     其中,是否有房子、是否有工作、信贷情况是其特征值;类别是其目标值,表示银行是否会放贷。我们可以利用信息增益的公式来进行计算,哪个特征应该最先放到首位。

    上面的信息熵的计算:

    [H(D) = - sumlimits_{k = 1}^k {frac{{{C_k}}}{D}} log frac{{{C_k}}}{D}]

    其中,Ck表示属于某个类别的样本数。

    条件熵的计算:

    [H(D|A) = sumlimits_{i = 1}^n {frac{{|{D_i}|}}{{|D|}}} H({D_i}) = - sumlimits_{i = 1}^n {frac{{|{D_i}|}}{{|D|}}} sumlimits_{k = 1}^K {frac{{|{D_{ik}}|}}{{|{D_i}|}}} log frac{{|{D_{ik}}|}}{{|{D_i}|}}]

    那么,我们可以利用上面的公式来计算一下:

    •  总的信息熵H
    H(D)=-3/9log3/9-6/9log6/9=0.36
    • 每个特征的条件熵
    #房子特征的信息增益
    g(D,房子) = H(D)-H(D'|房子)=H(D)-[4/10H(是)+5/10H(否)]
    
    #求出房子中是的类别的熵,注意此处的熵都是针对于目标类别的(在房子是的情况与否的情况下)
    H(是)=-(3/4*log3/4+1/4*log1/4)=0.24
    H(否)=-(5/5*log5/5+0/5*log0/5)=0
    
    g(D,房子) = H(D)-H(D'|房子)=H(D)-[5/10H(是)+5/10H(否)]=H(D)=0.3
    ...

    上述算出的就是房子特征的信息增益,其余的与之计算方式一样,最后比较每个特征的信息的增益,这样就知道那个特征应该先进性判断。

     4、常见的决策树算法

    上面我们使用的是信息增益(ID3)的算法,进行决策树,当然还有其它的方法:

    • 信息增益比(C4.5)
    • 基尼系数(CART)

    二、sklearn决策树API

     1、class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)

     上面就是决策树的分类器,其中:

    • criterion:默认是’gini’系数(基尼系数),也可以选择信息增益的熵’entropy’
    • max_depth:树的深度大小
    • random_state:随机数种子

     2、实例

    现有泰坦尼克号乘客的数据集,现提取数据集中的特征是票的类别,存活,乘坐班,年龄,登陆,home.dest,房间,票,船和性别。乘坐班是指乘客班(1,2,3),是社会经济阶层的代表。数据集的部分内容如下:

    注:其中age数据存在缺失。

    "row.names","pclass","survived","name","age","embarked","home.dest","room","ticket","boat","sex"
    "1","1st",1,"Allen, Miss Elisabeth Walton",29.0000,"Southampton","St Louis, MO","B-5","24160 L221","2","female"
    "2","1st",0,"Allison, Miss Helen Loraine", 2.0000,"Southampton","Montreal, PQ / Chesterville, ON","C26","","","female"
    "3","1st",0,"Allison, Mr Hudson Joshua Creighton",30.0000,"Southampton","Montreal, PQ / Chesterville, ON","C26","","(135)","male"
    "4","1st",0,"Allison, Mrs Hudson J.C. (Bessie Waldo Daniels)",25.0000,"Southampton","Montreal, PQ / Chesterville, ON","C26","","","female"
    "5","1st",1,"Allison, Master Hudson Trevor", 0.9167,"Southampton","Montreal, PQ / Chesterville, ON","C22","","11","male"
    "6","1st",1,"Anderson, Mr Harry",47.0000,"Southampton","New York, NY","E-12","","3","male"
    ...
    ...

    数据来源:http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt

     对于上面的乘客生存的分类模型可按照下面的流程进行处理:

    • 读取数据
    • 选取特征、处理缺失值
    • 进行特征工程(特征抽取)
    • 执行决策树估计起流程
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.feature_extraction import DictVectorizer
    from sklearn.tree import DecisionTreeClassifier, export_graphviz
    
    
    def decision():
        """
        决策树对泰坦尼克号乘客进行生死预测
        :return: None
        """
        # 读取数据
        data = pd.read_csv("./data/决策树数据/data.csv")
    
        # 选取特征值、目标值
        x = data[['pclass', 'age', 'sex']]
        y = data['survived']
    
        # 处理缺失值
        x['age'].fillna(x['age'].mean(), inplace=True)
        print(x)
        """
         pclass        age     sex
          1st  29.000000  female
          1st   2.000000  female
        ...
        """
        # 分割数据集为训练集和测试集
        x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
    
        # 特征工程,pclass与sex都是非数字的值,所以需要将其值得类别进行one-hot编码,使用字典抽取,age值不变
        dict = DictVectorizer(sparse=False)
        x_train = dict.fit_transform(x_train.to_dict(orient='records'))
        x_test = dict.transform(x_test.to_dict(orient='records'))
        print(dict.get_feature_names())  # ['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']
        print(x_train)
        """
        [[32.          0.          0.          1.          0.          1.        ]
          ...
         [58.          1.          0.          0.          1.          0.        ]
         [35.          0.          1.          0.          0.          1.        ]
         [31.19418104  0.          0.          1.          0.          1.        ]]
        
        """
        # 用决策树进行预测
        dtc = DecisionTreeClassifier()
        dtc.fit(x_train, y_train)
    
        # 预测准确率
        print(dtc.score(x_test, y_test))
    
        # 导出决策树结构
        export_graphviz(dtc, out_file='./tree.dot',feature_names=['年龄', 'pclass=1st', 
                'pclass=2nd', 'pclass=3rd', '女性', '男性']) return None if __name__ == '__main__': decision()

    三、优缺点

    1、优点

    • 树可被可视化,更易理解
    • 数据不需要进行归一化这些操作,其它算法通常需要对其进行归一化处理(比如:k-近邻算法)

    2、缺点

    • 不能推广过于复杂的树,这被称之为过拟合,也就是说在训练集中过于追求完美分类,而在测试集中并没有很好的效果。
    • 数据集中数据的一些小变化,可能会生成不同的决策树,这样导致决策树的不稳定。

    对于以上缺点可采用下面的解决方案:

    • 减枝cart算法
    • 随机森林

     

     

     

  • 相关阅读:
    matlab mex中C++内存全局共享和持久化
    算法导论01---到底何为算法(由算法联想到的大学教育)
    在Visual Studio项目中根据系统平台自动引用32或64位的DLL
    POJ2352【树状数组】
    artDialog双击会关闭对话框的修改
    利用AWR 查看SQL 执行计划
    Sql获取数据集中各类型中的最大值(最新值)
    容器常用操作
    运行容器的最佳实践
    两种进入容器的方法
  • 原文地址:https://www.cnblogs.com/shenjianping/p/13167636.html
Copyright © 2011-2022 走看看