《机器学习实战》——决策树

在这篇博文中,总结了决策树的基本用法和用python写的测试demo

1. 决策树的定义
分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点(Node)和有向边(directed edge)组成。结点有两种类型:内部结点(internal node)和叶节点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类。

2. 决策树测试过程

用决策树分类,从根结点开始,对实例的某一特征进行测试,根据测试结果,将实例分配到其子结点;这时,每一个子结点对应着该特征的一个取值,如此递归地对实例进行测试并分配,直至达到叶结点,最终将实例分到叶结点的类中。

决策树模型的简单表示:


3.决策树的构造

在构造决策树时,我们首先需要选择哪个特征作为分类特征,为了找到决定性特征,我们需要评估每一个特征,具体评估方法将在下一节中介绍。

在选择完分类特征后,用该特征对数据进行划分为几个数据子集,这些数据子集会分布在第一个决策点的所有分支上。如果某个分支下的数据属于同一类型,则已经正确地划分数据分类,无需再进一步对数据集进行分割了。如果数据子集内的数据不属于同一类型,则需要重复划分数据子集,直到数据属于同一类型。

上述决策树的构造过程伪代码函数createBranch()如下:

检测数据集中的每个子项是否属于同一分类:
If so return 类标签
Else
     寻找划分数据集的最好特征
     划分数据集
     创建分支节点
           for 每个划分的子集
                调用函数createBranch并增加返回结果到分支节点中
     return 分支节点

4.划分数据集的特征选择

划分数据的最大原则是:将无序的数据变得更加有序

常用的特征选择方法有:ID3、C4.5、CART算法,本文将介绍ID3算法进行特征选择。


  • 信息增益
在划分数据集前后数据信息的变化称为信息增益。

那么如何表示信息,又如何表示信息增益呢?

信息的定义:

l(xi)=-log2(p(xi))

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



由图可知,数据的信息随着某类别xi的概率增加而减小,当概率为1时,信息量为0。


熵的定义:

在信息论与概率统计中,熵表示随机变量不确定性的度量。我们用类别所有可能值包含的信息的数学期望来计算熵:

H(p(xi)=-∑p(xi)log2(p(xi))


条件熵H(Y|X):

表示随机变量X的条件下随机变量Y的不确定性,定义为X给定条件下Y的条件概率分布的熵对X的数学期望:

H(Y|X)=∑piH(Y|X=xi)   (其中:pi=P(X=xi))


计算熵的Python程序:

from math import log
def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet: #the the number of unique elements and their occurance
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries
        shannonEnt -= prob * log(prob,2) #log base 2
    return shannonEnt


信息增益的定义:

信息增益表示已知特征X的信息而使得类Y的信息的不确定性(也就是熵)减小的程度。

用公式表达就是:

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

(g(D,A):特征A对训练数据集D的信息增益,H(D):数据集D的经验熵,H(D|A):特征A条件下D的经验条件熵)

通过计算信息增益,找到使信息增益最大的特征,先给上Python程序:

def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]     #chop out axis used for splitting
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet
    
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1      #the last column is used for the labels
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0; bestFeature = -1
    for i in range(numFeatures):        #iterate over all the features
        featList = [example[i] for example in dataSet]#create a list of all the examples of this feature
        uniqueVals = set(featList)       #get a set of unique values
        newEntropy = 0.0
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)     
        infoGain = baseEntropy - newEntropy     #calculate the info gain; ie reduction in entropy
        if (infoGain > bestInfoGain):       #compare this to the best gain so far
            bestInfoGain = infoGain         #if better than current best, set to best
            bestFeature = i
    return bestFeature                      #returns an integer

例子:

样本数据:

(5个样本,具有2个特征:'no surfacing', 'flippers',每个特征都只取1或0;样本分类结果有2种:‘yes'、'no'

>>> dataSet

[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]

>>> labels

['no surfacing', 'flippers']


(1)计算整个数据集的原始熵

>>> baseEntropy =trees. calcShannonEnt(dataSet)

>>> baseEntropy

0.9709505944546686


(2)计算第一个特征的信息增益

第一个特征中所有类别:

uniqueVals = set([0, 1])

第一个特征取0时划分的数据集;并求出概率和条件熵:

>>> subDataSet=[[1, 'no'], [1, 'no']]

>>> prob = len(subDataSet)/float(len(dataSet)) = 0.4

条件熵:newEntropy += prob * calcShannonEnt(subDataSet) = 0

第一个特征取1时划分的数据集;并求出概率和条件熵:

>>> subDataSet=[[1, 'yes'], [1, 'yes'], [0, 'no']]

>>> prob = len(subDataSet)/float(len(dataSet)) = 0.6

条件熵:newEntropy += prob * calcShannonEnt(subDataSet) = 0.5509775004326937

第一个特征的信息增益

infoGain = baseEntropy - newEntropy = 0.4199730940219749


(3)相同的算法计算出其他特征的信息增益

(4)找到使信息增益最大的特征,即为选择的特征。


5.递归构建决策树

我们根据上一节的方法选择特征后,就可以把数据集划分到树分支的下一个节点中了,在下个节点中,我们又用相同的算法进行划分,直到程序遍历完所有划分数据集的属性,或者,每个分支下的所有实例属于相同的类

创建树的Python代码:

def majorityCnt(classList):
    classCount={}
    for vote in classList:
        if vote not in classCount.keys(): classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

def createTree(dataSet,labels):
    classList = [example[-1] for example in dataSet]
    if classList.count(classList[0]) == len(classList): 
        return classList[0]#stop splitting when all of the classes are equal 输出相同的类
    if len(dataSet[0]) == 1: #stop splitting when there are no more features in dataSet 投票表决输出频率最高的类
        return majorityCnt(classList)
    bestFeat = chooseBestFeatureToSplit(dataSet)
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}}
    del(labels[bestFeat])
    featValues = [example[bestFeat] for example in dataSet]
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLabels = labels[:]       #copy all of labels, so trees don't mess up existing labels
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
    return myTree  

6.使用决策树进行分类

使用决策树和决策树上的标签向量,程序比较测试数据与决策树上的数值,递归执行该过程直到进入叶子节点,最后把测试数据定义为叶子节点所属的类。

def classify(inputTree,featLabels,testVec):
    firstStr = inputTree.keys()[0]
    secondDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr)
    key = testVec[featIndex]
    valueOfFeat = secondDict[key]
    if isinstance(valueOfFeat, dict): 
        classLabel = classify(valueOfFeat, featLabels, testVec)
    else: classLabel = valueOfFeat
    return classLabel

7.实例

决策树的直观表示:




8.其他

过度细分的决策树可能会出现过度匹配数据的过拟合问题,我们可以通过裁剪决策树,合并相邻叶节点等方式解决

还有C4.5和CART等其他决策树构造算法,将在以后博文中总结。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 机器学习是一门涉及数据处理和模式识别的学科,它通过构建和训练模型来进行预测和分类。而MATLAB作为一种功能强大的计算机编程语言,具备丰富的数据处理和分析工具,因此成为了机器学习中常用的工具之一。 MATLAB提供了多种机器学习的实践应用源码,供初学者进行入门学习和实践。学习者可以通过这些源码了解机器学习的基本原理和流程,以及如何将其应用于实际问题中。 MATLAB的机器学习实战源码通常涵盖以下内容: 1. 数据预处理:通过MATLAB的数据处理函数,对原始数据进行清洗、归一化等预处理操作,以减少噪声的影响,并保证数据的可靠性和一致性。 2. 特征选择:根据问题的需求和特征的相关性,选择最具代表性的特征集,以提高分类和预测的准确度。 3. 模型训练:使用MATLAB的机器学习工具箱,选择相应的模型算法进行训练。常见的算法包括线性回归、逻辑回归、支持向量机、决策树等。 4. 模型评估:使用交叉验证、混淆矩阵等评估指标,对训练出的模型进行评估,判断其预测和分类的准确度。 5. 结果可视化:利用MATLAB的绘图函数,对机器学习模型的结果进行可视化展示,以便更直观地理解和分析。 通过实践应用源码,学习者可以在实际操作中深入理解机器学习的原理和算法,并掌握如何使用MATLAB进行数据处理、模型训练和结果评估。这也为进一步深入研究和应用机器学习奠定了基础。 ### 回答2: 机器学习是人工智能领域的重要分支,通过训练模型和算法来使机器能够自动学习和提高性能。机器学习的应用非常广泛,包括图像识别、自然语言处理、推荐系统等等。 在机器学习的实践中,MATLAB 是一种常用的工具。MATLAB 具有丰富的机器学习函数和工具箱,可以帮助用户快速实现算法和模型。 要进行机器学习实战,首先需要学习一些基本的概念和算法。机器学习中的一些常见算法包括线性回归、逻辑回归、决策树、支持向量机、神经网络等。MATLAB 中都有相应的函数和工具箱可以使用。可以通过学习 MATLAB 的帮助文档和示例代码来掌握这些算法的使用方法和原理。 在实际应用中,可以使用 MATLAB 来处理数据、建立模型、进行训练和评估。首先,将数据导入到 MATLAB 环境中,可以使用 MATLAB 提供的数据处理函数进行数据清洗和预处理。然后,选择合适的算法和模型,使用 MATLAB 提供的函数进行训练和优化。训练完成后,可以使用测试数据对模型进行评估。MATLAB 提供了丰富的可视化函数,可以对结果进行可视化展示和分析。 除了基本的算法和模型,MATLAB 中还有一些专门的工具箱,例如深度学习工具箱和图像处理工具箱,可以更方便地进行相关任务的实现。 总而言之,MATLAB 是一个强大的工具,提供了丰富的函数和工具箱,可以帮助用户进行机器学习的入门到实战。通过学习 MATLAB 的相关函数和示例代码,掌握机器学习的基本概念和算法,并在实际应用中进行模型的训练和评估,可以更好地理解和应用机器学习的知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值