机器学习之决策树

1.构建决策树的算法有很多,比如:ID3、C4.5、CART,我们选择ID3。
       ID3算法的核心是在决策树各个节点上对应信息增益准则选择特征,递归的构建决策树。具体方法
从根节点开始,对节点计算所有可能的特征的增益,选择信息增益最大的特征作为节点的特征,由
该特征的不同取值建立子节点,再对子节点递归调用以上方法,构建决策树;直到所有特征的信息
增益均很小或没有特征可以选择为止,最后得到一个决策树。

       递归结束的条件是:程序遍历完所有的特征列,或者每个分支下的所有实例都具有相同的分类。
如果所有实例具有相同分类,则得到一个叶节点,任何到达叶节点的数据必然属于叶节点的分类,
即叶节点里面必须是标签。

2.信息熵:熵定义为信息的期望值,在信息论与概率统计中,熵是表示随机变量不确定性的度量。

熵越大,不确定性越大。

假定当前样本集合D中一共有n类样本,第i类样本为xi,那么xi的信息定义为:l\left ( x_{i} \right ) = -\log p\left ( x_{i} \right )

其中,p(xi)是选择该分类的概率。

所有类别所有可能值包含的信息期望值:Ent\left ( D \right ) = - \sum_{i=1}^{n}p\left ( x_{i} \right )\log p\left ({x_{i}} \right )

3.信息增益:就是父节点的信息熵与其下所有子节点总信息熵(赋予权重)之差。

计算公式:Gain\left ( D,a \right ) = Ent\left ( D \right )-\sum_{v=1}^{v} \left ( \left | D^{v} \right |/\left | D \right | \right )Ent\left ( \left D^{v} \right \right )

其中| D^{v} \right |/\left | D \right | \right )为子节点(某一特征)的权重。

4.python实战:

#决策树
import numpy as np
import pandas as pd

def createDataSet():
    row_data = {'no surfacing':[1,1,1,0,0],
                'flippers':[1,1,0,1,1],
                'fish':['yes','yes','no','no','no']}
    dataSet = pd.DataFrame(row_data)
    return dataSet
 
#信息熵
def calEnt(dataSet):
    n = dataSet.shape[0] #总样本数
    iset = dataSet.iloc[:,-1].value_counts() #不同标签的个数
    p = iset/n
    ent = (-p*np.log2(p)).sum()
    return ent

#选择最大的信息增益,即信息下降最快的方向
#选择最优的列进行切分
def bestSplit(dataSet):
    baseEnt = calEnt(dataSet)
    bestGain = 0
    axis = -1
    for i in range(dataSet.shape[1]-1):
        levels = dataSet.iloc[:,i].value_counts().index
        ents = 0
        for j in levels:
            childSet = dataSet[dataSet.iloc[:,i]==j]
            ent = calEnt(childSet)
            ents += (childSet.shape[0]/dataSet.shape[0])*ent
        infoGain = baseEnt-ents
        if (infoGain>bestGain):
            bestGain = infoGain
            axis = i #最大信息增益所在列的索引
    return axis

def mySplit(dataSet,axis,value):
    col = dataSet.columns[axis]
    redataSet = dataSet.loc[dataSet[col]==value,:].drop(col,axis=1)
    return redataSet

def createTree(dataSet):
    featlist = list(dataSet.columns)
    classlist = dataSet.iloc[:,-1].value_counts()
    #递归结束条件:判断最多标签数目是否等于数据集行数(只有一类),
    #或者数据集是否只有一列(只剩一个特征了)
    if classlist[0]==dataSet.shape[0] or dataSet.shape[1]==1:
        return classlist.index[0]
    axis = bestSplit(dataSet)
    bestfeat = featlist[axis]
    myTree = {bestfeat:{}}
    del featlist[axis]
    valuelist = set(dataSet.iloc[:,axis])
    for value in valuelist:
        myTree[bestfeat][value] = createTree(mySplit(dataSet,axis,value))
    return myTree

def classify(inputTree,labels,testVec):
    firstStr = next(iter(inputTree))  #获取决策树第一个节点
    secondDict = inputTree[firstStr]
    featIndex = labels.index(firstStr) #第一个节点所在列的索引
    for key in secondDict.keys():
        if testVec[featIndex] == key:
            if type(secondDict[key]) == dict:
                classLabel = classify(secondDict[key],labels,testVec)
            else:
                classLabel = secondDict[key]
    return classLabel

def acc_classify(train,test):
    inputTree = createTree(train) #根据训练集生成一棵树
    labels = list(train.columns) #数据集所有的列名称
    result = []
    for i in range(test.shape[0]):
        testVec = test.iloc[i,:-1] #测试集中的一个实例
        classLabel = classify(inputTree,labels,testVec) #预测该实例的分类
        result.append(classLabel)
    test['predict'] = result
    acc = (test.iloc[:,-1] == test.iloc[:,-2]).mean() #计算准确度
    print(f'模型预测准确率为{acc}')
    return test


if __name__ == '__main__':
    dataSet = createDataSet()
    train = dataSet
    #用训练集的前三个作为测试样本
    test = dataSet.iloc[:3,:]
    print(acc_classify(train,test))

输出结果:

5.sklearn:

#使用sklearn中graphviz包实现决策树的绘制
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier

#特征
xtrain = dataSet.iloc[:,:-1]
#标签
ytrain = dataSet.iloc[:,-1]
labels = ytrain.unique().tolist()
ytrain = ytrain.apply(lambda x:labels.index(x))
#绘制树模型
clf = DecisionTreeClassifier()
clf = clf.fit(xtrain,ytrain)
tree.export_graphviz(clf)

输出结果:

 

 

最后,感谢菊安酱在哔站的认真讲解!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值