决策树ID3算法和C4.5算法实战

简介: 决策树ID3算法和C4.5算法实战

老师给的题目:

代码实现【两种算法合在一个文件里】:

1. from numpy import *
2. 
3. def createDataSet():
4.     dataSet = [[1, 1, 1, 0, 'no'],
5.                [1, 1, 1, 1, 'no'],
6.                [0, 1, 1, 0, 'yes'],
7.                [-1, 0, 1, 0, 'yes'],
8.                [-1,-1,0,0,'yes'],
9.                [-1,-1,0,1,'no'],
10.                [0,-1,0,1,'yes'],
11.                [1,0,1,0,'no'],
12.                [1,-1,0,0,'yes'],
13.                [-1,0,0,0,'yes'],
14.                [1,0,0,1,'yes'],
15.                [0,0,1,1,'yes'],
16.                [0,1,0,0,'yes'],
17.                [-1,0,1,1,'no']]
18.     labels = ['weather','temperature','humidity','wind speed','activity']
19.     return dataSet, labels
20. 
21. #计算数据集的entropy
22. def calcEntropy(dataSet):
23.     totalNum = len(dataSet)
24.     labelNum = {}
25.     entropy = 0
26.     for data in dataSet:
27.         label = data[-1]
28.         if label in labelNum:
29.             labelNum[label] += 1
30.         else:
31.             labelNum[label] = 1
32. 
33.     for key in labelNum:
34.         p = labelNum[key] / totalNum
35.         entropy -= p * log2(p)
36.     return entropy
37. 
38. def calcEntropyForFeature(featureList):
39.     totalNum = len(featureList)
40.     dataNum = {}
41.     entropy = 0
42.     for data in featureList:
43.         if data in dataNum:
44.             dataNum[data] += 1
45.         else:
46.             dataNum[data] = 1
47. 
48.     for key in dataNum:
49.         p = dataNum[key] / totalNum
50.         entropy -= p * log2(p)
51.     return entropy
52. 
53. #选择最优划分属性ID3
54. def chooseBestFeatureID3(dataSet, labels):
55.     bestFeature = 0
56.     initialEntropy = calcEntropy(dataSet)
57.     biggestEntropyG = 0
58.     for i in range(len(labels)):
59.         currentEntropy = 0
60.         feature = [data[i] for data in dataSet]
61.         subSet = splitDataSetByFeature(i, dataSet)
62.         totalN = len(feature)
63.         for key in subSet:
64.             prob = len(subSet[key]) / totalN
65.             currentEntropy += prob * calcEntropy(subSet[key])
66.         entropyGain = initialEntropy - currentEntropy
67.         if(biggestEntropyG < entropyGain):
68.             biggestEntropyG = entropyGain
69.             bestFeature = i
70.     return bestFeature
71. 
72. #选择最优划分属性C4.5
73. def chooseBestFeatureC45(dataSet, labels):
74.     bestFeature = 0
75.     initialEntropy = calcEntropy(dataSet)
76.     biggestEntropyGR = 0
77.     for i in range(len(labels)):
78.         currentEntropy = 0
79.         feature = [data[i] for data in dataSet]
80.         entropyFeature = calcEntropyForFeature(feature)
81.         subSet = splitDataSetByFeature(i, dataSet)
82.         totalN = len(feature)
83.         for key in subSet:
84.             prob = len(subSet[key]) / totalN
85.             currentEntropy += prob * calcEntropy(subSet[key])
86.         entropyGain = initialEntropy - currentEntropy
87.         entropyGainRatio = entropyGain / entropyFeature
88. 
89.         if(biggestEntropyGR < entropyGainRatio):
90.             biggestEntropyGR = entropyGainRatio
91.             bestFeature = i
92.     return bestFeature
93. 
94. def splitDataSetByFeature(i, dataSet):
95.     subSet = {}
96.     feature = [data[i] for data in dataSet]
97.     for j in range(len(feature)):
98.         if feature[j] not in subSet:
99.             subSet[feature[j]] = []
100. 
101.         splittedDataSet = dataSet[j][:i]
102.         splittedDataSet.extend(dataSet[j][i + 1:])
103.         subSet[feature[j]].append(splittedDataSet)
104.     return subSet
105. 
106. def checkIsOneCateg(newDataSet):
107.     flag = False
108.     categoryList = [data[-1] for data in newDataSet]
109.     category = set(categoryList)
110.     if(len(category) == 1):
111.         flag = True
112.     return flag
113. 
114. def majorityCateg(newDataSet):
115.     categCount = {}
116.     categList = [data[-1] for data in newDataSet]
117.     for c in categList:
118.         if c not in categCount:
119.             categCount[c] = 1
120.         else:
121.             categCount[c] += 1
122.     sortedCateg = sorted(categCount.items(), key = lambda x:x[1], reverse = True)
123. 
124.     return sortedCateg[0][0]
125. 
126. #创建ID3树
127. def createDecisionTreeID3(decisionTree, dataSet, tmplabels):
128.     labels=[]
129.     for tmp in tmplabels:
130.         labels.append(tmp)
131.     bestFeature = chooseBestFeatureID3(dataSet, labels)
132.     decisionTree[labels[bestFeature]] = {}
133.     currentLabel = labels[bestFeature]
134.     subSet = splitDataSetByFeature(bestFeature, dataSet)
135.     del(labels[bestFeature])
136.     newLabels = labels[:]
137.     for key in subSet:
138.         newDataSet = subSet[key]
139.         flag = checkIsOneCateg(newDataSet)
140.         if(flag == True):
141.             decisionTree[currentLabel][key] = newDataSet[0][-1]
142.         else:
143.             if (len(newDataSet[0]) == 1): #无特征值可划分
144.                 decisionTree[currentLabel][key] = majorityCateg(newDataSet)
145.             else:
146.                 decisionTree[currentLabel][key] = {}
147.                 createDecisionTreeID3(decisionTree[currentLabel][key], newDataSet, newLabels)
148. 
149. # 创建C4.5树
150. def createDecisionTreeC45(decisionTree, dataSet, tmplabels):
151.     labels=[]
152.     for tmp in tmplabels:
153.         labels.append(tmp)
154.     bestFeature = chooseBestFeatureC45(dataSet, labels)
155.     decisionTree[labels[bestFeature]] = {}
156.     currentLabel = labels[bestFeature]
157.     subSet = splitDataSetByFeature(bestFeature, dataSet)
158.     del (labels[bestFeature])
159.     newLabels = labels[:]
160.     for key in subSet:
161.         newDataSet = subSet[key]
162.         flag = checkIsOneCateg(newDataSet)
163.         if (flag == True):
164.             decisionTree[currentLabel][key] = newDataSet[0][-1]
165.         else:
166.             if (len(newDataSet[0]) == 1):  # 无特征值可划分
167.                 decisionTree[currentLabel][key] = majorityCateg(newDataSet)
168.             else:
169.                 decisionTree[currentLabel][key] = {}
170.                 createDecisionTreeC45(decisionTree[currentLabel][key], newDataSet, newLabels)
171. 
172. 
173. #测试数据分类
174. def classify(inputTree, featLabels, testVec):
175.     firstStr = list(inputTree.keys())#得到节点所代表的属性eg:'flippers'
176.     firstStr = firstStr[0]
177.     secondDict = inputTree[firstStr]#得到该节点的子节点,是一个dict,eg:{0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}
178.     featIndex = featLabels.index(firstStr)#得到firstStr在所给的featLabels(属性)中的位置,以便将testVec中的值与相应的属性对应
179.     for key in secondDict.keys():#将testVec中的值放入决策树中进行判断
180.         if testVec[featIndex] == key:
181.             if type(secondDict[key]).__name__=='dict':#如果还有子节点则继续判断
182.                 classLabel = classify(secondDict[key],featLabels,testVec)
183.             else: classLabel = secondDict[key]#否则返回该节点的值
184.     return classLabel
185. 
186. if __name__ == '__main__':
187.     dataSetID3, labelsID3 = createDataSet()
188.     testData1 = [1, 1, 1, 0]
189.     testData2 = [1,-1,0,0]
190.     bestFeatureID3 = chooseBestFeatureID3(dataSetID3, labelsID3)
191.     decisionTreeID3 = {}
192.     createDecisionTreeID3(decisionTreeID3, dataSetID3, labelsID3)
193.     print("ID3 decision tree: ", decisionTreeID3)
194.     # category1ID3 = classifyTestData(decisionTreeID3, testData1)
195.     # print(testData1 , ", classified as by ID3: " , category1ID3)
196.     # category2ID3 = classifyTestData(decisionTreeID3, testData2)
197.     # print(testData2 , ", classified as by ID3: " , category2ID3)
198. 
199.     for tmp in dataSetID3:
200.         category = classify(decisionTreeID3,labelsID3,tmp[0:4])
201.         print(tmp[0:4], ", classified as by ID3: " , category)
202. 
203.     dataSetC45, labelsC45 = createDataSet()
204.     bestFeatureC45 = chooseBestFeatureC45(dataSetC45, labelsC45)
205.     decisionTreeC45 = {}
206.     createDecisionTreeC45(decisionTreeC45, dataSetC45, labelsC45)
207.     print("C4.5 decision tree: ", decisionTreeC45)
208.     # category1C45 = classifyTestData(decisionTreeC45, testData1)
209.     # print(testData1 , ", classified as by C4.5: " , category1C45)
210.     # category2C45 = classifyTestData(decisionTreeC45, testData2)
211.     # print(testData2 , ", classified as by C4.5: " , category2C45)
212. 
213.     for tmp in dataSetC45:
214.         category = classify(decisionTreeC45,labelsC45,tmp[0:4])
215.         print(tmp[0:4], ", classified as by C4.5: " , category)

 

AIEarth是一个由众多领域内专家博主共同打造的学术平台,旨在建设一个拥抱智慧未来的学术殿堂!【平台地址:https://devpress.csdn.net/aiearth】 很高兴认识你!加入我们共同进步!

目录
相关文章
|
7月前
|
算法 数据可视化 测试技术
HNSW算法实战:用分层图索引替换k-NN暴力搜索
HNSW是一种高效向量检索算法,通过分层图结构实现近似最近邻的对数时间搜索,显著降低查询延迟。相比暴力搜索,它在保持高召回率的同时,将性能提升数十倍,广泛应用于大规模RAG系统。
641 10
HNSW算法实战:用分层图索引替换k-NN暴力搜索
|
7月前
|
机器学习/深度学习 缓存 算法
微店关键词搜索接口核心突破:动态权重算法与语义引擎的实战落地
本文详解微店搜索接口从基础匹配到智能推荐的技术进阶路径,涵盖动态权重、语义理解与行为闭环三大创新,助力商家提升搜索转化率、商品曝光与用户留存,实现技术驱动的业绩增长。
|
7月前
|
存储 机器学习/深度学习 监控
网络管理监控软件的 C# 区间树性能阈值查询算法
针对网络管理监控软件的高效区间查询需求,本文提出基于区间树的优化方案。传统线性遍历效率低,10万条数据查询超800ms,难以满足实时性要求。区间树以平衡二叉搜索树结构,结合节点最大值剪枝策略,将查询复杂度从O(N)降至O(logN+K),显著提升性能。通过C#实现,支持按指标类型分组建树、增量插入与多维度联合查询,在10万记录下查询耗时仅约2.8ms,内存占用降低35%。测试表明,该方案有效解决高负载场景下的响应延迟问题,助力管理员快速定位异常设备,提升运维效率与系统稳定性。
334 4
|
8月前
|
机器学习/深度学习 资源调度 算法
遗传算法模型深度解析与实战应用
摘要 遗传算法(GA)作为一种受生物进化启发的优化算法,在复杂问题求解中展现出独特优势。本文系统介绍了GA的核心理论、实现细节和应用经验。算法通过模拟自然选择机制,利用选择、交叉、变异三大操作在解空间中进行全局搜索。与梯度下降等传统方法相比,GA不依赖目标函数的连续性或可微性,特别适合处理离散优化、多目标优化等复杂问题。文中详细阐述了染色体编码、适应度函数设计、遗传操作实现等关键技术,并提供了Python代码实现示例。实践表明,GA的成功应用关键在于平衡探索与开发,通过精心调参维持种群多样性同时确保收敛效率
|
7月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
8月前
|
机器学习/深度学习 边缘计算 人工智能
粒子群算法模型深度解析与实战应用
蒋星熠Jaxonic是一位深耕智能优化算法领域多年的技术探索者,专注于粒子群优化(PSO)算法的研究与应用。他深入剖析了PSO的数学模型、核心公式及实现方法,并通过大量实践验证了其在神经网络优化、工程设计等复杂问题上的卓越性能。本文全面展示了PSO的理论基础、改进策略与前沿发展方向,为读者提供了一份详尽的技术指南。
粒子群算法模型深度解析与实战应用
|
10月前
|
监控 算法 安全
基于 C# 基数树算法的网络屏幕监控敏感词检测技术研究
随着数字化办公和网络交互迅猛发展,网络屏幕监控成为信息安全的关键。基数树(Trie Tree)凭借高效的字符串处理能力,在敏感词检测中表现出色。结合C#语言,可构建高时效、高准确率的敏感词识别模块,提升网络安全防护能力。
262 2
|
12月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
296 17
|
11月前
|
机器学习/深度学习 算法 搜索推荐
决策树算法如何读懂你的购物心理?一文看懂背后的科学
"你为什么总能收到刚好符合需求的商品推荐?你有没有好奇过,为什么刚浏览过的商品就出现了折扣通知?
334 0