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
    
    
    
     
  • 相关阅读:
    NES游戏历史
    NES资料
    Spring的自动装配
    springmvc框架如何将模型数据传递给视图 也就是Model>view参数的传递
    拆分Spring的配置文件
    Springmvc框架前台传值给controller @Requestparam @RequestMapping
    SpringMVC框架传入Map集合
    SpringMVC框架使用注解编写的处理请求和映射@Controller @RequestMapping
    SpringMVC初尝试
    MVC设计模式
  • 原文地址:https://www.cnblogs.com/fd-682012/p/11584859.html
Copyright © 2011-2022 走看看