決策樹--熵計算--特徵分類
# 引入log計算熵
from math import log
# 熵越高,則混合的數據也越多
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
# 1.計算數據集中實例的總是,也就是樣本的總數。我們把這個值保存成一格單獨的變量以便之後方便使用,提高代碼的效率
# 2.創建字典,用於保存類別信息。在整個數據集當中有多少個類別,每個類別的個數是多少
# 3. 在我們創建的數據字典中,它的鍵是我們數據集中最後一列的值。如果當前鍵不存在則把這個鍵加入到字典當中,依次統計出現類別的次數
# 4. 最後使用所有類標籤對應的次數來計算它們的概論
# 5.計算香農熵
def calcShannonEnt(dataSet):
# 獲取數據長度
countDataSet = len(dataSet)
# 定義集合,用來存放label
labelCounts = {}
for featVec in dataSet:
# label爲最後一列
currentLabel = featVec[-1]
if currentLabel not in labelCounts.keys():
# 注意,集合value增加方式
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1
shannonEnt = 0.0
for key in labelCounts:
# 每個label出現的概率
prob = float(labelCounts[key]) / countDataSet
# shannonEnt -= prob * log(prob, 2)這個同下
shannonEnt = shannonEnt - prob * log(prob, 2)
return shannonEnt
# 劃分數據集
def splitDataSet(dataSet, axis, value):
# dataset是鏈表,爲了不改變外部數據,重新新建鏈表
retDataSet = []
for featVec in dataSet:
# axis特徵,value特徵值
if featVec[axis] == value:
# 除去特徵然後創建一個子特徵
reducedFeatVec = featVec[:axis]
reducedFeatVec.extend(featVec[axis + 1:])
# 將滿足條件的樣本放入新建的樣本中
retDataSet.append(reducedFeatVec)
return retDataSet
if __name__ == '__main__':
dataSet, labels = createDataSet()
print(dataSet)
print(calcShannonEnt(dataSet))
retDataSet = splitDataSet(dataSet, 0, 1)
print(retDataSet)
retDataSet = splitDataSet(dataSet, 0, 0)
print(retDataSet)
計算結果如下: