zoukankan      html  css  js  c++  java
  • 决策树(一)

    #决策树
    1.定义
    分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点和有向边组成。
    结点有两种类型:内部节点和叶节点,内部节点表示一个特征或属性,叶节点表示一个类。
    分类的时候,从根节点开始,对实例的某一个特征进行测试,根据测试结果,将实例分配到其子结点;
    此时,每一个子结点对应着该特征的一个取值。如此递归向下移动,直至达到叶结点,最后将实例分配到叶结点的类中。
    #优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关特征数据
    #缺点:可能会产生过度匹配问题
    #适用数据类型:数值型和标称型
    '''
    createBranch()函数伪代码
    检测数据集中的每个子项是否属于同一类分类:
    If so return 类标签:
    Else
    寻找划分数据集的最好特征
    划分数据集
    创建分支节点
    for 每个划分的子类
    调用函数createBranch并增加返回结果到分支节点中
    return 分支节点

    决策树一般流程:
    收集-准备-分析数据-训练-测试-使用算法

    信息增益:在划分数据集之前之后信息发生的变化
    获得信息增益最高的特征就是最好的选择
    香农熵(熵):集合信息的度量方式
    熵定义为信息的期望值
    '''
     1 #计算给定数据集的香农熵
     2 from math import log
     3 from matplotlib.font_manager import FontProperties
     4 import matplotlib.pyplot as plt
     5 import operator
     6 from importlib import reload
     7 def calcShannonEnt(dataSet):
     8     numEntries = len(dataSet)
     9     labelCounts = {}    #创建一个数据字典,它的键值是最后一列的数值
    10     for featVec in dataSet:
    11         currentLabel = featVec[-1]
    12         if currentLabel not in labelCounts.keys():
    13             labelCounts[currentLabel] = 0
    14             labelCounts[currentLabel] += 1
    15         shannonEnt = 0.0
    16         for key in labelCounts: #使用所有类标签的发生频率计算类别出现的概率
    17             prob = float(labelCounts[key])/numEntries   #利用这个概率计算香农熵
    18             shannonEnt -= prob * log(prob,2)
    19         return shannonEnt
    20 def createDataSet():
    21     dataSet = [[1,1,'yes'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no']]
    22     labels = ['no surfacing','flippers']
    23     return dataSet, labels
    24 
    25 #划分数据集
    26 def splitDataSet(dataSet, axis, value): #待划分数据集,划分数据集的特征,特征的返回值
    27     retDataSet = [] #创建新的列表对象
    28     for featVec in dataSet:
    29         if featVec[axis] == value:  #将符合特征的数据抽取出来
    30             reducedFeatVec = featVec[:axis]
    31             reducedFeatVec.extend(featVec[axis+1:])
    32             retDataSet.append(reducedFeatVec)
    33     return retDataSet
    34 
    35 def chooseBestFeatureToSplitByID3(dataSet):
    36     '''
    37     选择最好的数据集划分方式
    38     param dataSet:数据集
    39     return: 划分结果
    40     '''
    41     numFeatures = len(dataSet[0]) - 1  # 最后一列yes分类标签,不属于特征向量
    42     baseEntropy = calcShannonEnt(dataSet)
    43     bestInfoGain = 0.0
    44     bestFeature = -1
    45     for i in range(numFeatures):  # 遍历所有特征
    46         featList = [example[i] for example in dataSet]
    47         uniqueVals = set(featList)
    48         newEntropy = 0.0
    49         for value in uniqueVals:    #创建唯一的分类标签列表
    50             subDataSet = splitDataSet(dataSet, i, value)
    51             prob = len(subDataSet)/float(len(dataSet))
    52             newEntropy += prob * calcShannonEnt(subDataSet)
    53         infoGain = baseEntropy - newEntropy     # 计算信息增益
    54         if (infoGain > bestInfoGain):  # 选择最大的信息增益
    55             bestInfoGain = infoGain
    56             bestFeature = i
    57     return bestFeature  # 返回最优特征对应的维度
    58 
    59 #递归构建决策树
    60 def majorityCnt(classList):
    61 #采用多数表决的方法决定叶结点的分类,param: 所有的类标签列表,return: 出现次数最多的类
    62     classCount = {}
    63     for vote in classList:                  # 统计所有类标签的频数
    64         if vote not in classCount.keys():
    65             classCount[vote] = 0
    66         classCount[vote] += 1       #利用operation操作键值排序字典,并返回出现次数最多的分类名称
    67     sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # 排序
    68     return sortedClassCount[0][0]
    69 
    70 #创建数的函数代码
    71 def createTree(dataSet,labels):
    72     #param: dataSet:训练数据集
    73     #return: labels:所有的类标签
    74     classList = [example[-1] for example in dataSet]
    75     if classList.count(classList[0]) == len(classList):
    76         return classList[0]             # 第一个递归结束条件:所有的类标签完全相同
    77     if len(dataSet[0]) == 1:
    78         return majorityCnt(classList)   # 第二个递归结束条件:用完了所有特征
    79     bestFeat = chooseBestFeatureToSplitByID3(dataSet)   # 最优划分特征
    80     bestFeatLabel = labels[bestFeat]
    81     myTree = {bestFeatLabel:{}}         # 使用字典类型储存树的信息
    82     del(labels[bestFeat])
    83     featValues = [example[bestFeat] for example in dataSet]
    84     uniqueVals = set(featValues)
    85     for value in uniqueVals:
    86         subLabels = labels[:]       # 复制所有类标签,保证每次递归调用时不改变原始列表的内容
    87         myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
    88     return myTree
    
    
    
     
  • 相关阅读:
    Java程序:从命令行接收多个数字,求和并输出结果
    大道至简读后感
    大道至简第一章读后感Java伪代码
    Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010
    声明式验证超时问题
    Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"
    Upgrading or Redeploying SharePoint 2010 Workflows
    Upgrade custom workflow in SharePoint
    SharePoint 2013中Office Web Apps的一次排错
    How to upgrade workflow assembly in MOSS 2007
  • 原文地址:https://www.cnblogs.com/fd-682012/p/11584859.html
Copyright © 2011-2022 走看看