《机器学习实战》学习(三)——决策树实例

实例一 《机器学习》书中4.3习题

1、问题描述

试编程实现基于信息熵进行划分选择的决策树算法,并为表4.3中数据生成一棵决策树,表4.3数据如下:

‘色泽’,’根蒂’,’敲声’,’纹理’,’脐部’,’触感’,’密度’,’含糖率’
青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.46 是
乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376 是
乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264 是
青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318 是
浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215 是
青绿 稍蜷 浊响 清晰 稍凹 软粘 0.403 0.237 是
乌黑 稍蜷 浊响 稍糊 稍凹 软粘 0.481 0.149 是
乌黑 稍蜷 浊响 清晰 稍凹 硬滑 0.437 0.211 是
乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑 0.666 0.091 否
青绿 硬挺 清脆 清晰 平坦 软粘 0.243 0.267 否
浅白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 否
浅白 蜷缩 浊响 模糊 平坦 软粘 0.343 0.099 否
青绿 稍蜷 浊响 稍糊 凹陷 硬滑 0.639 0.161 否
浅白 稍蜷 沉闷 稍糊 凹陷 硬滑 0.657 0.198 否
乌黑 稍蜷 浊响 清晰 稍凹 软粘 0.36 0.37 否
浅白 蜷缩 浊响 模糊 平坦 硬滑 0.593 0.042 否
青绿 蜷缩 沉闷 稍糊 稍凹 硬滑 0.719 0.103 否

2、问题分析

观测数据可以发现,表中数据存在离散属性数据以及两列’密度’,’含糖率’的两个属性,且这两个属性都是连续数据。因此采用上一章实现的ID3算法(只解决了离散数据)因此需要一些修改。决策树本身是对离散数据的分类决策,那题中存在连续数据,那我们又该如何进行构建决策树呢?我在代码中参考了http://blog.csdn.net/wzmsltw/article/details/51039928这篇对本题解答的问题。不过此代码我在使用过程中任然存在一些问题。困惑我最久的无非是Labels数据在创建树的结构中出现的问题。后来采用深拷贝解决此问题。另外博主可能不是采用的python3.5的版本,有很多运行出错,我稍加修改并加入了个人的一些理解。将代码进行了详细的注释,以便以后自己回顾。
博主在处理连续数据问题时,任然采用了计算增益的方式,将选择对连续数据最好的划分值,从而使得信息增益最大。最后再与全局比较信息增益。获得最优划分。

3、代码实现

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 10 20:09:11 2016

@file trees.py
@brief 决策树算法实现 实现西瓜案例 改进
在上一个tree.py版本中无法对连续属性进行处理,西瓜案例中的密度与含糖度两个属性是连续数据,那该如何处理呢
@version V1.1
"""

"""
@brief 计算给定数据集的信息熵
@param dataSet 数据集
@return 香农熵
"""

import operator  
import copy
from math import log
def calcShannonEnt(dataSet):
    numEntries = len(dataSet)#求取数据集的行数
    labelCounts = {}
    for featVec in dataSet:#读取数据集中的一行数据
        currentLabel = featVec[-1] #取featVec中最后一列的值
        #以一行数据中的最后一列值为键值进行统计
        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)#求取数据集的香农熵
    return shannonEnt

"""
@brief 划分数据集 按照给定的特征划分数据集
@param[in] dataSet 待划分的数据集
@param[in] axis  划分数据集的特征
@param[in] value 需要返回的特征的值
@return retDataSet 返回划分后的数据集
"""
def splitDataSet(dataSet, axis, value):
    retDataSet = []#返回的划分后的数据集
    for featVec in dataSet:
        #抽取符合划分特征的值
        if featVec[axis] == value:
            #如何符合此特征值 则存储,存储划分后的数据集时 不需要存储选为划分的特征
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+
  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值