决策树的创建与分类

决策树的创建与分类

  • 决策树的定义
    决策树(Decision Tree)是一种基本的分类与回归方法 。
  • 工作原理
    由判断模板到终止模板的流程,类似与你问我答的小游戏,答案也是只能用对或错回答,下图表示原理
    决策树的创建与分类_第1张图片
  • 优点
    计算复杂度不高,输出易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。
  • 缺点
    可能会产生过度匹配问题
  • 适用数据类型
    数值型和标称型
  • 决策树的构造
    (1)收集数据:可以使用任何方法。
    (2)准备数据:树构造算法只适用于标称型数据,因此数据型数据必须离散化。
    (3)分析数据:可以使用任何方法,构造数据完成之后,我们应该检查图形是否符合预期。
    (4)训练算法:构造树的数据结构。
    (5)测试算法:使用经验树计算错误率。
    (6)使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义。
  • 信息增益
    在划分数据集之前之后信息发生的变化
    计算信息增益需要了解熵(信息的期望值)
    决策树的创建与分类_第2张图片 - 决策树的实现
  • 收集数据
    决策树的创建与分类_第3张图片
  • 构造数据集
    我们把不浮出水面是否生存和是否有脚蹼用(0,1)表示,属于鱼类用(yes,no)表示。
def createDataSet():
    dataSet = [[1,1,'yes'],
            [1,1,'yes'],
            [1,0,'no'],
            [0,1,'no'],
            [0,1,'no']]
    labels = ['no surfacing ','flippers']
    return dataSet,labels
  • 计算熵值
import operator
from numpy import *
from math import log

def createDataSet():
    data=[[1,1,'yes'],
          [1,1,'yes'],
          [1,0,'no'],
          [0,1,'no'],
          [0,1,'no']]
    feature_label=['no surfacing','flippers']
    return data,feature_label

def calshang(dataSet):
    numEntry=len(dataSet)  #统计所有实例数
    label_list=[example[-1] for example in dataSet] #遍历每一行元素,取每一行最后一个元素构成标签列表。['yes', 'yes', 'no', 'no', 'no']
    classCount={}  #创建字典,对数据集中分类情况进行统计。
    for label in label_list: 
        if label not in classCount.keys():
            classCount[label]=0
        classCount[label]+=1      
    # print(classCount)  #{'yes': 2, 'no': 3}
    shang=0.0
    for key in classCount:  #遍历类别字典,计算熵值
        prob=classCount[key]/numEntry  #float(classCount[key])/numEntry
        shang+=-prob*log(prob,2)
    return shang
    
dataSet,feature_label=createDataSet()
print('原始数据集为 %s'%(dataSet))
print('特征名称为:%s'%(feature_label))
print("熵为:")
print(calshang(dataSet))

结果显示:
在这里插入图片描述

  • 划分数据集函数:
def split_dataSet(dataSet,featureX_axis,value):
    reduced_dataSet=[]   #划分后的数据集
    for data in dataSet: 
        if data[featureX_axis]==value:  #特征X值为value的,划分到一个子集中
            reduced_data=data[0:featureX_axis]   
            reduced_data.extend(data[featureX_axis+1:])   #去除特征X对应的列
            reduced_dataSet.append(reduced_data)  
    return reduced_dataSet
    
##测试函数功能
dataSet,feature_label=createDataSet()
split_dataSet(dataSet,1,1) #以索引为1的特征(是否有脚蹼)进行划分,返回特征对应为1的数据样本。注意:返回的数据中只剩下一个特征(索引为0的特征,即"不浮出水面是否可以生存"),因为以索引为1的特征进行划分,接下来的划分中不能再使用这个特征,所以数据会减少一个特征。
print(split_dataSet(dataSet,1,1))

结果显示:
在这里插入图片描述

  • 特征提取
def chooseBestSplit(dataSet):
     num_dataSet=len(dataSet)  #计算划分前的数据集的实例个数
     num_feature=len(dataSet[0])-1   #计算划分前的数据集的特征个数
     base_shang=calshang(dataSet)  #计算划分前的数据集的熵
     bestInfoGain=0.0               #初始化信息增益为0
     bestFeature=-1                 #记录最佳划分的特征的索引
     for i in range(num_feature):    #遍历所有特征,寻求最佳特征划分
         feature=[example[i] for example in dataSet]  #得到第i个特征,对应的所有实例的数据
         uniqueValue=set(feature)   #第i个特征所有可能的取值
         newEntropy=0.0  
         for value in uniqueValue:  #遍历第i个特征所有可能的取值,计算按照第i个特征划分后数据集的信息熵
             subDataSet=split_dataSet(dataSet,i,value)  
             prob=len(subDataSet)/float(num_dataSet)
             newEntropy+=prob*calshang(subDataSet)
         infoGain=base_shang-newEntropy  #计算按照第i个特征划分后数据集的信息增益
         print("以索引为"+str(i)+"的特征进行划分,信息增益为:"+str(infoGain))
         if infoGain>bestInfoGain:
             bestInfoGain=infoGain
             bestFeature=i     #记录最佳划分特征索引号
     #print("bestFeature is %d" %(bestFeature))
     return bestFeature
     
###函数功能测试
myDat,label=createDataSet()
bestFeature=chooseBestSplit(myDat)
print("bestFeature index  is %d" %(bestFeature))

结果显示:
在这里插入图片描述
由结果得出:先选择特征”不浮出水面是否可以生存“时,对应的信息增益要大于选择特征”是否有脚蹼"“。

你可能感兴趣的:(决策树,python)