ID3决策树代码见CreatTree.py。请结合算法原理,通过认真阅读、单步调试等方法,掌握ID3决策树的代码实现,并根据自己的理解,对代码进行详细注释。
时间: 2024-02-01 16:13:07 浏览: 102
好的,下面是对CreatTree.py代码的详细注释:
```python
from math import log
import operator
```
首先导入了两个模块,math中的log函数用于计算信息熵,operator模块用于进行一些操作,如获取字典中value值最大的key。
```python
# 计算给定数据集的香农熵
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCounts = {}
# 为所有可能分类创建字典
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:
prob = float(labelCounts[key])/numEntries
shannonEnt -= prob * log(prob, 2)
return shannonEnt
```
这是计算香农熵的函数,输入参数为数据集。首先获取数据集的长度,然后使用字典统计数据集中各类别的数量。接着遍历字典,根据公式计算香农熵并返回。
```python
# 创建测试数据集
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
```
这个函数是用于创建一个简单的数据集,包括两个特征和一个目标变量。
```python
# 按照给定特征划分数据集
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
```
这个函数用于按照给定特征进行数据集的划分,输入参数为数据集、特征、特征值。遍历数据集,将符合要求的数据存储在一个新的列表中并返回。
```python
# 选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1
baseEntropy = calcShannonEnt(dataSet)
bestInfoGain = 0.0
bestFeature = -1
for i in range(numFeatures):
featList = [example[i] for example in dataSet]
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
```
这个函数是选择最好的数据集划分方式的函数,输入参数为数据集。首先获取数据集中特征数量,计算数据集的香农熵。接着遍历每个特征,获取该特征下的值,计算每个值下的子数据集的香农熵,最后计算信息增益。如果信息增益大于之前的最大信息增益,就更新最大信息增益和最佳特征。最后返回最佳特征。
```python
# 多数表决的方法决定叶子节点的分类
def majorityCnt(classList):
classCount={}
for vote in classList:
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]
```
这个函数是采用多数表决的方式来确定叶子节点的分类,输入参数为分类标签列表。统计分类标签列表中各类别的数量,并根据数量从大到小排序。最后返回数量最多的类别。
```python
# 创建决策树
def createTree(dataSet, labels):
classList = [example[-1] for example in dataSet]
# 如果类别完全相同则停止继续划分
if classList.count(classList[0]) == len(classList):
return classList[0]
# 遍历完所有特征时返回出现次数最多的类别
if len(dataSet[0]) == 1:
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet)
bestFeatLabel = labels[bestFeat]
myTree = {bestFeatLabel:{}}
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]
uniqueVals = set(featValues)
for value in uniqueVals:
subLabels = labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
return myTree
```
这个函数是创建决策树的函数,输入参数为数据集和标签列表。首先获取数据集中的类别列表,如果所有类别都相同,就返回该类别。如果遍历完所有特征,还存在不同的类别,就返回数量最多的类别。接着选择最佳特征进行划分,创建一个新的字典用于存储决策树,将最佳特征作为字典的key。然后删除该特征的标签,获取该特征下的所有值,创建一个集合。遍历每个值,将标签列表拷贝一份并递归创建决策树。最后返回决策树。
```python
if __name__ == '__main__':
dataSet, labels = createDataSet()
myTree = createTree(dataSet, labels)
print(myTree)
```
这段代码是主函数,用于测试我们创建的决策树。首先使用createDataSet函数创建测试数据集,然后使用createTree函数创建决策树,最后打印决策树。
阅读全文