
本文实例讲述了Python机器学习之决策树算法。分享给大家供大家参考,具体如下:
决策树学习是应用最广泛的归纳推理算法之一,是一种逼近离散值目标函数的方法,在这种方法中学习到的函数被表示为一棵决策树。决策树可以使用不熟悉的数据集合,并从中提取出一系列规则,机器学习算法最终将使用这些从数据集中创造的规则。决策树的优点为:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。缺点为:可能产生过度匹配的问题。决策树适于处理离散型和连续型的数据。
在算法中一般选用ID3,D3算法的核心问题是选取在树的每个节点要测试的特征或者属性,希望选择的是最有助于分类实例的属性。如何定量地衡量一个属性的价值呢?这里需要引入熵和信息增益的概念。熵是信息论中广泛使用的一个度量标准,刻画了任意样本集的纯度。
假设有10个训练样本,其中6个的分类标签为yes,4个的分类标签为no,那熵是多少呢?在该例子中,分类的数目为2(yes,no),yes的概率为0.6,no的概率为0.4,则熵为 :
其中value(A)是属性A所有可能值的集合,是S中属性A的值为v的子集,即
。上述公式的第一项为原集合S的熵,第二项是用A分类S后熵的期望值,该项描述的期望熵就是每个子集的熵的加权和,权值为属于的样本占原始样本S的比例
。所以Gain(S, A)是由于知道属性A的值而导致的期望熵减少。
完整的代码:
# -*- coding: cp936 -*-
from numpy import *
import operator
from math import log
import operator
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
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCounts = {} # a dictionary for feature
for featVec in dataSet:
currentLabel = featVec[-1]
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1
shannonEnt = 0.0
for key in labelCounts:
#print(key)
#print(labelCounts[key])
prob = float(labelCounts[key])/numEntries
#print(prob)
shannonEnt -= prob * log(prob,2)
return shannonEnt
#按照给定的特征划分数据集
#根据axis等于value的特征将数据提出
def splitDataSet(dataSet, axis, value):
retDataSet = []
for featVec in 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 #剩下的是特征的个数
baseEntropy = calcShannonEnt(dataSet)#计算数据集的熵,放到baseEntropy中
bestInfoGain = 0.0;bestFeature = -1 #初始化熵增益
for i in range(numFeatures):
featList = [example[i] for example in dataSet] #featList存储对应特征所有可能得取值
uniqueVals = set(featList)
newEntropy = 0.0
for value in uniqueVals:#下面是计算每种划分方式的信息熵,特征i个,每个特征value个值
subDataSet = splitDataSet(dataSet, i ,value)
prob = len(subDataSet)/float(len(dataSet)) #特征样本在总样本中的权重
newEntropy = prob * calcShannonEnt(subDataSet)
infoGain = baseEntropy - newEntropy #计算i个特征的信息熵
#print(i)
#print(infoGain)
if(infoGain > bestInfoGain):
bestInfoGain = infoGain
bestFeature = i
return bestFeature
#如上面是决策树所有的功能模块
#得到原始数据集之后基于最好的属性值进行划分,每一次划分之后传递到树分支的下一个节点
#递归结束的条件是程序遍历完成所有的数据集属性,或者是每一个分支下的所有实例都具有相同的分类
#如果所有实例具有相同的分类,则得到一个叶子节点或者终止快
#如果所有属性都已经被处理,但是类标签依然不是确定的,那么采用多数投票的方式
#返回出现次数最多的分类名称
def majorityCnt(classList):
classCount = {}
for vote in classList:
if vote not in classCount.keys():classCount[vote] = 0
classCount[vote] += 1
sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
#创建决策树
def createTree(dataSet,labels):
classList = [example[-1] for example in dataSet]#将最后一行的数据放到classList中,所有的类别的值
if classList.count(classList[0]) == len(classList): #类别完全相同不需要再划分
return classList[0]
if len(dataSet[0]) == 1:#这里为什么是1呢?就是说特征数为1的时候
return majorityCnt(classList)#就返回这个特征就行了,因为就这一个特征
bestFeat = chooseBestFeatureToSplit(dataSet)
print('the bestFeatue in creating is :')
print(bestFeat)
bestFeatLabel = labels[bestFeat]#运行结果'no surfacing'
myTree = {bestFeatLabel:{}}#嵌套字典,目前value是一个空字典
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]#第0个特征对应的取值
uniqueVals = set(featValues)
for value in uniqueVals: #根据当前特征值的取值进行下一级的划分
subLabels = labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet,bestFeat,value),subLabels)
return myTree
#对上面简单的数据进行小测试
def testTree1():
myDat,labels=createDataSet()
val = calcShannonEnt(myDat)
print 'The classify accuracy is: %.2f%%' % val
retDataSet1 = splitDataSet(myDat,0,1)
print (myDat)
print(retDataSet1)
retDataSet0 = splitDataSet(myDat,0,0)
print (myDat)
print(retDataSet0)
bestfeature = chooseBestFeatureToSplit(myDat)
print('the bestFeatue is :')
print(bestfeature)
tree = createTree(myDat,labels)
print(tree)
对应的结果是:
>>> import TREE
>>> TREE.testTree1()
The classify accuracy is: 0.97%
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
[[1, 'yes'], [1, 'yes'], [0, 'no']]
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
[[1, 'no'], [1, 'no']]
the bestFeatue is :
0
the bestFeatue in creating is :
0
the bestFeatue in creating is :
0
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
最好再增加使用决策树的分类函数
同时因为构建决策树是非常耗时间的,因为最好是将构建好的树通过 python 的 pickle 序列化对象,将对象保存在磁盘上,等到需要用的时候再读出
def classify(inputTree,featLabels,testVec):
firstStr = inputTree.keys()[0]
secondDict = inputTree[firstStr]
featIndex = featLabels.index(firstStr)
key = testVec[featIndex]
valueOfFeat = secondDict[key]
if isinstance(valueOfFeat, dict):
classLabel = classify(valueOfFeat, featLabels, testVec)
else: classLabel = valueOfFeat
return classLabel
def storeTree(inputTree,filename):
import pickle
fw = open(filename,'w')
pickle.dump(inputTree,fw)
fw.close()
def grabTree(filename):
import pickle
fr = open(filename)
return pickle.load(fr)
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数据成为新时代“石油”的今天,几乎每个职场人都在焦虑: “为什么别人能用数据驱动决策、升职加薪,而我面对Excel表格却无从 ...
2025-10-18数据清洗是 “数据价值挖掘的前置关卡”—— 其核心目标是 “去除噪声、修正错误、规范格式”,但前提是不破坏数据的真实业务含 ...
2025-10-17在数据汇总分析中,透视表凭借灵活的字段重组能力成为核心工具,但原始透视表仅能呈现数值结果,缺乏对数据背景、异常原因或业务 ...
2025-10-17在企业管理中,“凭经验定策略” 的传统模式正逐渐失效 —— 金融机构靠 “研究员主观判断” 选股可能错失收益,电商靠 “运营拍 ...
2025-10-17在数据库日常操作中,INSERT INTO SELECT是实现 “批量数据迁移” 的核心 SQL 语句 —— 它能直接将一个表(或查询结果集)的数 ...
2025-10-16在机器学习建模中,“参数” 是决定模型效果的关键变量 —— 无论是线性回归的系数、随机森林的树深度,还是神经网络的权重,这 ...
2025-10-16在数字化浪潮中,“数据” 已从 “辅助决策的工具” 升级为 “驱动业务的核心资产”—— 电商平台靠用户行为数据优化推荐算法, ...
2025-10-16在大模型从实验室走向生产环境的过程中,“稳定性” 是决定其能否实用的关键 —— 一个在单轮测试中表现优异的模型,若在高并发 ...
2025-10-15在机器学习入门领域,“鸢尾花数据集(Iris Dataset)” 是理解 “特征值” 与 “目标值” 的最佳案例 —— 它结构清晰、维度适 ...
2025-10-15在数据驱动的业务场景中,零散的指标(如 “GMV”“复购率”)就像 “散落的零件”,无法支撑系统性决策;而科学的指标体系,则 ...
2025-10-15在神经网络模型设计中,“隐藏层层数” 是决定模型能力与效率的核心参数之一 —— 层数过少,模型可能 “欠拟合”(无法捕捉数据 ...
2025-10-14在数字化浪潮中,数据分析师已成为企业 “从数据中挖掘价值” 的核心角色 —— 他们既要能从海量数据中提取有效信息,又要能将分 ...
2025-10-14在企业数据驱动的实践中,“指标混乱” 是最常见的痛点:运营部门说 “复购率 15%”,产品部门说 “复购率 8%”,实则是两者对 ...
2025-10-14在手游行业,“次日留存率” 是衡量一款游戏生死的 “第一道关卡”—— 它不仅反映了玩家对游戏的初始接受度,更直接决定了后续 ...
2025-10-13分库分表,为何而生? 在信息技术发展的早期阶段,数据量相对较小,业务逻辑也较为简单,单库单表的数据库架构就能够满足大多数 ...
2025-10-13在企业数字化转型过程中,“数据孤岛” 是普遍面临的痛点:用户数据散落在 APP 日志、注册系统、客服记录中,订单数据分散在交易 ...
2025-10-13在数字化时代,用户的每一次行为 —— 从电商平台的 “浏览→加购→购买”,到视频 APP 的 “打开→搜索→观看→收藏”,再到银 ...
2025-10-11在机器学习建模流程中,“特征重要性分析” 是连接 “数据” 与 “业务” 的关键桥梁 —— 它不仅能帮我们筛选冗余特征、提升模 ...
2025-10-11在企业的数据体系中,未经分类的数据如同 “杂乱无章的仓库”—— 用户行为日志、订单记录、商品信息混杂存储,CDA(Certified D ...
2025-10-11在 SQL Server 数据库操作中,“数据类型转换” 是高频需求 —— 无论是将字符串格式的日期转为datetime用于筛选,还是将数值转 ...
2025-10-10