美文网首页
机器学习---决策树(随机森林)

机器学习---决策树(随机森林)

作者: strive鱼 | 来源:发表于2018-09-18 15:50 被阅读0次

    决策树本质上是一个classfication 问题的监督学习算法,其结构上分为根节点和叶节点,底层python 的实现可以参考机器学习实战一书,本质上是一个递归实现。

    1. 伪代码的介绍
      假定一个训练集合D={(x1,y1),(x2,y2),...,(xm,ym)};
      属性集合A={a1,a2,...,ad}.
      有三种情况下,导致递归直接返回结果:(1)当前节点包含的样本全部属于同一个类别,无需进行划分;(2)当前属性为空,或者是所有样本在所有的属性上的取值相等,无法划分;(3)当前节点包含的样本集合为空,不能划分
    1. 决策树划分的原则和定量值
      一般而言,随着划分的不断进行,希望决策树的分支点所包含的样本尽可能的属于同一类别,即节点的纯度要高,衡量纯度的标准为信息熵
      信息熵有如下的定义:假定样本集合D中的第x类样本所占的比例之和为px,则D的信息熵为:

      假定离散属性a有V个可能的取值{a1,a2,...,av},若使用a对样本集合D来进行划分,则会产生v个分支节点,其中第v个分支节点包含了D中所有在属性a上取值为av的样本,记作Dv,且考虑到不同的分支节点所包含的样本数不同,给分支节点赋予权重|Dv|/|D|,即样本数越多的分支节点的影响越大
      Gain(D,a)=H[x]-(v=1到v=v的和)|Dv|/|D|*Ent(Dv)

    具体来讲,当有多个属性,每一个属性都对应多个属性值,那么就计算每一个属性的信息熵,哪一个属性的信息熵大,则选择该属性为决策树的节点

    1. 增益率
      在周志华p78有一个例子,判断是否为好瓜,有17个样本,把每一个样本进行编号,作为一列,如果把该列也作为属性,那么它的信息增益应该最大,因为这样决策树就会产生17个分支,每一个分支的节点就包含一个样本,纯度达到最大,这样的决策树准确率高,但是不具备泛化能力,无法对新样本进行有效的预测
      增益率的公式为:
      Gain_ratio(D,a)=Gain(D,a)/IV(a)
      其中,iv(a)=-(v=1到v=v的和)|Dv|/|D|*log2|Dv|/|D| (C4.5算法)
    1. 基尼指数(CART Classification and regression Tree 的简称,这是一种著名决策树的学习算法,分类和回归都可以使用)

      其中属性a的基尼指数定义为:
      Gini_index(D,a)=(v=1 到v=v的和)|Dv|/|D|Gini(Dv)
    1. 对过拟合的解决方法
      采用预剪枝/后剪枝的方法来进行处理
      周志华p81-p83对于此讲解十分清楚,感兴趣可以去拜读一下

    下面介绍sklearn 官方文档

    • criterion 可以使用"gini"或者"entropy",前者就是上文代表的基尼系数,后者代表信息增益。一般说使用默认的基尼系数"gini"就可以了,即CART算法。
    • splitter 可以使用"best"或者"random"。前者在特征的所有划分点中找出最优的划分点。后者是随机的在部分划分点中找局部最优的划分点。 默认的"best"适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐"random"
    • max_depth 决策树的最大深度, 决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间
    • min_samples_split 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分默认是2 如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值
    • min_samples_leaf 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数
    • min_weight_fraction_leaf 这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
    • max_leaf_nodes 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。
    • max_features The number of features to consider when looking for the best split 用于划分选取的最大特征值的个数

    methods

    • apply(X, check_input=True) Returns the index of the leaf that each sample is predicted as.
    • decision_path(X, check_input=True) Return the decision path in the tree
    • fit(X, y, sample_weight=None, check_input=True, X_idx_sorted=None) 其中,X为样本集合,y为所属的类标签,参数sample_weight 为样本的权重,默认为None,权重相同
    • get_params(deep=True) 得到评估器的参数,deep 默认为True ,表示输出所有参数
    • predict_log_proba(X) Predict class log-probabilities of the input samples X. 得到预测属于某一类别的log 值
    • predict_proba(X, check_input=True) Predict class probabilities of the input samples X 得到预测属于某一类别的值
    • score(X, y, sample_weight=None) X为测试集, y为测试集的真实的类别标签,返回的是测试结果准确度(即多少判断正确,多少判断错误)

    下面来看一个简单的demo

    import  sklearn
    from sklearn import tree#输出决策树
    
    x=[[0,0],[2,2]]
    y=[0,1]
    clf=tree.DecisionTreeClassifier()#这是用于进行分类问题
    clf=clf.fit(x,y)
    #print (clf.predict_proba([[1,1]]))
    #print (clf.apply(x))  返回叶节点所在位置的索引
    #print (clf.predict([[3,4]]))
    
    x=[[0,0],[2,2]]
    y=[0.5,2.5]#注意这时候标签是浮点类型的,且是不连续的
    clf=tree.DecisionTreeRegressor()#就要用到回归决策树分类器
    clf=clf.fit(x,y)
    #print (clf.predict_proba([[1,1]]))
    #print (clf.apply(x))  返回叶节点所在位置的索引
    print (clf.predict([[3,4]]))
    

    最后是一个官方的实例,结合matplotlib的呈现

    import  sklearn
    from sklearn.tree import DecisionTreeRegressor#输出回归决策树
    import numpy as np
    import matplotlib.pyplot  as plt
    
    rng=np.random.RandomState(1)#其中1为伪随机种子。只要随机种子一样,那么生成的序列就相同
    x=np.sort(5*rng.rand(80,1),axis=0)#其中random.rand 的用处是生成一个指定形状的数组,np.sort 参数axis默认为-1,表示按照最后一行排序
    #print (x)  最终生成了一组80个由小到大排列的数
    """
    >>> a = np.array([[1,4],[3,1]])
    >>> np.sort(a)                # sort along the last axis
    array([[1, 4],
           [1, 3]])
    >>> np.sort(a, axis=None)     # sort the flattened array
    array([1, 1, 3, 4])
    >>> np.sort(a, axis=0)        # sort along the first axis
    array([[1, 1],
           [3, 4]])
    """
    y=np.sin(x).ravel()#np.sin(np.pi/2)得到[[1]],ravel的作用是降维的作用
    y[::5]+=3*(0.5-rng.rand(16))# 80/5=16 利用rand 产生16个一维数组
    # #print (y)
    regr_1=DecisionTreeRegressor(max_depth=2)
    regr_2=DecisionTreeRegressor(max_depth=5)#产生两个深度不同的树
    regr_1.fit(x,y)
    regr_2.fit(x,y)#分别训练两棵树
    
    
    #ppredict
    x_test=np.arange(0.0,5.0,0.01)[:,np.newaxis]#将1行多列的数组转化为多行一列的数组
    y_1=regr_1.predict(x_test)
    y_2=regr_2.predict(x_test)
    
    #picture
    plt.figure()#画布搭建
    plt.scatter(x,y, s=20,marker='<',edgecolor='black',c='darkorange',label='data')
    """
    其中的s可以理解为点的大小,c为颜色序列,当有多个点的时候,可以接受一个颜色组成的列表,每个点的颜色按照序列颜色生成
    marker 表示生成的点的形状,默认为'o'
    label 图像标签
    """
    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()
    

    最终的图像展示如下

    未完待续。。。。。。

    相关文章

      网友评论

          本文标题:机器学习---决策树(随机森林)

          本文链接:https://www.haomeiwen.com/subject/fbylnftx.html