机器学习实战笔记二——决策树

'''
决策树实例,决策树优点:
优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
缺点:可能会产生过度匹配问题
适用数据类型:数值型和标称型
'''

'''
决策树一般流程:
1、收集数据
2、准备数据
3、分析数据
4、训练数据
5、测试数据
6、使用算法
'''

from numpy import *
import operator
from os import listdir

from math import log

#创建数据集,标签集
def creatDataSet():  
    dataSet = [[1,1,'yes'],
               [1,1,'yes'],
               [1,0,'no'],
               [0,1,'no'],
               [0,1,'no']]
    labels = ['no surfacing','flippers']
    return dataSet,labels

#计算给定数据集的熵
#熵:信息的期望值(均值),熵越高数据越混乱
def calcShannonEnt(dataSet):  
    numEntries = len(dataSet)  #计算样本集中样本的个数,确定循环次数
    labelCounts = {}   

    for eachLine in dataSet:  #遍历dataSet的每一行
        currentLabel = eachLine[-1]  #提取样本集中每个样本的标签,每一行数据的最后一个为标签

        if currentLabel not in labelCounts.keys():   #labelCounts.keys()返回labelCounts所有键值
            labelCounts[currentLabel] = 0  #如果当前样本的标签不在labelCounts中,将其值赋为0,
        labelCounts[currentLabel] += 1   #如果在就加1,统计标签出现的次数

    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries  #计算p(x_i)
        shannonEnt -= prob * log(prob,2)   #计算熵值

    return shannonEnt

#按照给定属性划分数据集
# dataSet: 需要划分的数据集
# axis:    划分数据集的属性   0: 不浮出水面是否可以生存   1: 是否有脚蹼
# value:   需要返回的特征的值 0: 否  1:是
def splitDataSet(dataSet,axis,value):

    retDataSet = []   #创建新的列表对象,防止列表被修改

    for featVec in dataSet:  #dataSet中每个元素也为一个列表,遍历dataSet中每个元素
        if featVec[axis] == value:   #提取符合特征的数据
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

#选择最好的数据划分方式
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1   #dataSet第一行长度减去标签,即为属性个数
    baseEntropy = calcShannonEnt(dataSet) #计算整个数据集的熵
    bestInfoGain = 0.0; bestFeature = -1
    for i in range(numFeatures):  #遍历数据集中所有的特征
        featList = [example[i] for example in dataSet] #取出dataSet中每个元素(dataSet中元素为列表)中的第i个元素组成一个列表
        uniqueVals = set(featList)  #转为集合类型,集合类型各个元素互不相同,删选出各个特征的取值
        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
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

def majorityCnt(classList):  #返回出现次数最多的分类名称
    classCount = {}
    for vote in classCount:
        if vote not in classCount.keys():
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

def creatTree(dataSet,labels):
    classList = [example[-1] for example in dataSet] #取出dataSet中每个元素(dataSet中元素为列表)中的最后一列元素组成一个列表,即为类别
    if classList.count(classList[0]) == len(classList):  #count()方法统计classList中classList[0]出现的次数,如果与长度相等,则表明全为一类
        return classList[0]
    if len(classList) == 1 :
        return majorityCnt(classList)
    bestFeat = chooseBestFeatureToSplit(dataSet)
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}}
    del(labels[bestFeat])
    featValues = [example[bestFeat] for example in dataSet]
    uniqueValues = set(featValues)
    for value in uniqueValues:
        subLabels = labels[:]  #复制类标签
        myTree[bestFeatLabel][value] = creatTree(splitDataSet(dataSet,bestFeat,value),subLabels)  #递归创建决策树
    return myTree

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值