决策树代码python
ID3决策树
前言
最近学习决策树,看了周志华的西瓜书,也看了很多博客,此文记录一下学习心得,理论部分网上已经有很多了,此处不再赘述。由于本人对西瓜数据集的属性不太感冒,所以用的例子是男女,声音,头发。
划分流程
数据集8条 划分示意图
详细划分过程:
说明
伪代码说明递归建树过程
递归建树(数据集,标签):
# 结束条件
1. 该数据集中只有一个类,那判定结果就是这个类
2. 该数据集中不止一个类,但已无属性可以继续划分,结果为多的胜出
# 本层任务
找最优分类属性BestFeature(BF)
用BF切割数据集,并从标签列表删去BF
递归建树(切割后的数据集,删去BF的标签)
majorityCnt函数里,用到了字典按值排序,教程点这
完整代码
import math
'''创建实例数据集'''
def createDataSet1(): # 创造示例数据
dataSet = [['长', '粗', '男'],
['短', '粗', '男'],
['短', '粗', '男'],
['长', '细', '女'],
['短', '细', '女'],
['短', '粗', '女'],
['长', '粗', '女'],
['长', '粗', '女']]
labels = ['头发','声音'] #两个特征
return dataSet,labels
'''计算熵'''
def calcEntropy(dataSet):
numFeatures = len(dataSet[0])
#print('属性或特征个数 =', numFeatures)
numDataSet = len(dataSet)
#print('数据集长度 =', numDataset)
typeCount = {}
# pi = ni / n; ni:第i类样本数;n:总样本数
# 遍历每行,统计不同类别出现次数
for row in dataSet:
if row[-1] not in typeCount.keys():
typeCount[row[-1]] = 0 # row[-1]为类别,若类别还没统计过,加入字典,出现次数为0,后面 1
typeCount[row[-1]] = 1 # 若类别统计过,出现次数 1
print('每类样本出现个数', typeCount)
entropy = 0.0 # 熵
for num in typeCount.values():
p = num / numDataSet
entropy -= p * math.log(p,2)
print('entropy =', entropy)
return entropy
'''选择最优的分类特征'''
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1 # 不算最后一列,那是类别:男女
baseEntropy = calcEntropy(dataSet) #原始的信息熵
bestInfoGain = 0 # 信息增益
bestFeatIndex = -1 # 最优特征下标
for i in range(numFeatures):
featList = [row[i] for row in dataSet]# 第i列,特征组成的列表
uniqueFeatValues = set(featList) # 用集合去重,得到特征值,如{'短', '长'}
newEntropy = 0
for value in uniqueFeatValues: # 用特征值中的每一个 划分数据集
subDataSet = splitDataSet(dataSet,i,value)
print('划分后的子集 :',subDataSet)
weight = len(subDataSet)/float(len(dataSet))# 权重,子集个数/ 全集个数
newEntropy = weight * calcEntropy(subDataSet) # 按某个特征分类后的熵 = 累加 子集熵*weight
print('划分后的信息熵 :', newEntropy)
infoGain = baseEntropy - newEntropy # 信息增益, 越大越好
if infoGain > bestInfoGain:
bestInfoGain = infoGain
bestFeatIndex = i
return bestFeatIndex
'''
划分数据集
axis : 最优特征BestFeature(BF)所在下标
value : BF能取得值
'''
def splitDataSet(dataSet, axis, value): # 按某个特征分类后的数据
retDataSet = []
for row in dataSet:
if row[axis] == value:
reducedFeatvec = row[:axis] # 取出分裂特征前的数据集
reducedFeatvec.extend(row[axis 1:]) # 取出分裂特征后的数据集,合并两部分数据集
retDataSet.append(reducedFeatvec) # 本行取得的去除value的列表 加入总列表
return retDataSet
'''统计,多者胜出'''
def majorityCnt(typeList): #按分类后类别数量排序,比如:最后分类为2男1女,则判定为男;
typeCount={}
for t in typeList:
if t not in typeCount.keys():
typeCount[t] = 0
typeCount[t] = 1
print('typeCount =', typeCount)
sortedTypeCount = sorted(typeCount.items(),key=lambda x:x[1],reverse=True)# 从大到小排列,结果如[('女', 2), ('男', 1)]
print('少数服从多数,多数为 :',sortedTypeCount[0][0])
return sortedTypeCount[0][0]
'''递归建树'''
def createTree(dataSet, labels):
typeList = [row[-1] for row in dataSet] # 类别:男或女
if typeList.count(typeList[0]) == len(typeList):# 若只有一个类,直接返回
return typeList[0]
if len(dataSet[0]) == 1: # 若最后只剩下一个类别属性
return majorityCnt(typeList)
bestFeatIndex = chooseBestFeatureToSplit(dataSet) # 最优特征下标和对应特征
bestFeat = labels[bestFeatIndex]
print('bestFeatureIndex =', bestFeatIndex)
print('***********最优特征值 =', bestFeat, end='***********\n')
myTree={bestFeat:{}} # 分类结果以字典形式保存
del(labels[bestFeatIndex])
uniqueVals = set() # 最优特征能取的值,用set保证无重复
{uniqueVals.add(row[bestFeatIndex]) for row in dataSet}
print(f'{bestFeat} 能取的值 :',uniqueVals)
for value in uniqueVals:
subLabels = labels # labels里已经删去了最优特征,用subLabels为了区分更明显
myTree[bestFeat][value] = createTree(splitDataSet(dataSet,bestFeatIndex,value), subLabels)
return myTree
if __name__=='__main__':
dataset, labels = createDataSet1()
print(createTree(dataset, labels)) # 输出决策树模型结果
参考博客
把中间那些变量打印一下,就大致了解流程了,觉得本文有用的小伙伴可以点个赞呀~
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggcfhc
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13