"""
檔案說明:決策樹
"""from math import log
"""函式說明:建立測試資料集
parameters:
null
returns:
dataset - 資料集
labels - 分類屬性
author:
zhengyuxiao
modify:
2019-03-04
"""def createdataset():
dataset = [[0, 0, 0, 0, 'no'], # 資料集
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
labels = ['不放貸', '放貸'] # 分類屬性
return dataset, labels # 返回資料集和分類屬性
"""函式說明:計算給定資料集的經驗熵
paremeters:
dataset - 資料集
returns:
shannonent - 經驗熵 h(d)
author:
zhengyuxiao
modofy:
2019-03-04
"""def calcshannonent(dataset):
# 訓練集資料條數
numentires = len(dataset)
# 記錄訓練集中每個標籤出現次數的字典
labelcounts = {}
for featvec in dataset:
currentlabel = featvec[-1]
labelcounts[currentlabel] = labelcounts.get(currentlabel, 0) + 1
# 經驗熵
shannonent = 0.0
# k
# h(d) = -∑[p(xi)log2p(xi)] p(xi) = |ck|/|d|
# i=1
# |ck|:訓練集中標籤為ck的資料的條數
# |d|:訓練集資料總條數
for key in labelcounts:
prob = float(labelcounts[key]) / numentires
shannonent -= prob * log(prob, 2)
return shannonent
"""函式說明:按照給定特徵以及指定的特徵值劃分資料集(例:性別 男)
parameters:
dataset - 待劃分的資料集
axis - 劃分資料集的特徵的列數[0,1,2,3....]
value - 需要返回的特徵的值
returns:
returndataset - 指定特徵的值等於指定特徵值的資料的集合(例:性別為男的資料的集合)
author:
zhengyuxiao
modify:
2019-03-05
"""def splitdataset(dataset, axis, value):
# 儲存返回資料的列表
returndataset =
# 遍歷訓練集
for featvec in dataset:
# 如果該條資料中用來劃分訓練集的特徵的值等於指定值
# 則把這個特徵值從這條資料中去除,並把新資料儲存
if featvec[axis] == value:
# list[ start : end ] :python列表的切片操作
# 返回列表從start位置開始,到end位置前的元素組成的列表
# 例:print([1,3,5,7,9][1:3])
# 輸出:[3,5]
## list.extend( list2 ) :把列表list2中的元素新增到列表list的尾部
# 例子:list1 = [0, 1, 2, 3, 4, 5, 6][:2]
# list1.extend([0, 1, 2, 3, 4, 5, 6][3:])
# print(list1)
# 輸出:[0, 1, 3, 4, 5, 6]
reducedfeatvec = featvec[:axis]
reducedfeatvec.extend(featvec[axis + 1:])
return returndataset
"""函式說明:選擇劃分訓練集的最優特徵
parameters:
dataset - 資料集
returns:
bestfeature - 使資訊增益最大的特徵的索引值
author:
zhengyuxiao
modify:
2019-03-05
"""def choosebestfeaturetosplit(dataset):
# 特徵數量
numfeatures = len(dataset[0]) - 1
# 訓練集的夏農熵 h(d)
baseentropy = calcshannonent(dataset)
# 資訊增益
bestinfogain = 0.0
# 最優特徵(使訓練集資訊增益最大的特徵)的索引值
bestfeature = -1
## 資訊增益 = 集合的熵 - 特徵x給定條件下集合的熵
# g(d,x) = h(d) - h(d|x)
## 計算每乙個特徵對集合產生的資訊增益
for i in range(numfeatures):
# 把每一特徵整列取出:
# 性別 年級 及格 性別 年齡 及格
# | 男 1 y | |男| |1| |y|
# | 女 4 y | -> |女| |4| |y|
# | 女 3 n | |女| |3| |n|
# | 男 1 y | |男| |1| |y|
featlist = [example[i] for example in dataset]
# 建立集合,集合中的元素不能重複,set函式會自動去除重複的資料,
# 所以集合儲存——某一特徵的所有取值
uniquevals = set(featlist)
# 條件熵 h(d|x)
# n
# = ∑[ |di|/|d| * h(di) ]
# i=1
## n k
# = - ∑[ |di|/|d| * ∑[ |dik|/|di|] * log2(|dik|/|di|) ]
# i=1 k=1
#newentropy = 0.0
for value in uniquevals:
# 訓練集被某一特徵的某一特徵值劃分的子集
# 例:
# 年級 及格
# | 1 y |
# | 1 y |
subdataset = splitdataset(dataset, i, value)
# |di|/|d|
prob = len(subdataset) / float(len(dataset))
# 根據公式計算條件經驗熵 h(d|x):
# n
# ∑[ |di|/|d| * h(di) ]
# i=1
newentropy += prob * calcshannonent(subdataset)
# 計算資訊增益:
# 資訊增益 = 集合的熵 - 特徵x給定條件下集合的熵
# g(d,x) = h(d) - h(d|x)
infogain = baseentropy - newentropy
print("第", i, "個特徵的資訊增益為:", infogain)
if (infogain > bestinfogain):
bestinfogain = infogain
bestfeature = i
print("資訊增益最高的是第", bestfeature, "個特徵")
return bestfeature
if __name__ == '__main__':
dataset, features = createdataset()
print("訓練集=\n", dataset)
print("經驗熵=\n", calcshannonent(dataset))
choosebestfeaturetosplit(dataset)
決策樹資訊增益
決策樹和整合演算法都是樹模型 決策樹 從根節點一步步走到葉子節點,所有的資料都會落到葉子節點,既可以做分類也可以做回歸。一顆樹有三種節點組成,根節點,中間幾點,葉子節點。根節點是第乙個選擇節點,也是最重要的乙個選擇特徵。葉子節點是存放最終的結果。決策樹的訓練和測試 訓練是建立一棵樹。測試是讓資料從根...
機器學習 決策樹(求最優資訊增益)
emmmmmm.有點燒腦子 決策樹,通俗的理解就是根據每個問題進行判斷,然後最終往下找到答案的過程,類似於一棵樹,可以用下圖 相親物件的選擇 來理解 獲得一棵決策樹,首先要求的最優資訊增益,資訊增益就是求前邊每一列對最最後一列這個可能標籤的約束程度,熵代表了最後一列標籤取值的隨機性 貌似這樣吧,我是...
資訊增益與決策樹
決策樹是一種判別式模型。在一顆分類決策樹中,非葉子節點時決策規則,葉子節點是類別。當輸入乙個特徵向量時,按照決策樹上的規則從根節點向葉節點移動,最後根據葉節點的類別判定輸入向量的類別。決策樹也可以用來解決回歸問題。建立乙個決策樹模型主要有三個步驟 特徵選擇 決策樹的生成 決策樹的剪枝。而特徵選擇時要...