決策樹構建的思路非常清晰,由函式treegrow(dataset)的遞迴來實現決策樹左右子樹的構建,構建的順序為1->2->3->4->5->6->7,與使用其他語言實現決策樹演算法沒有差別。利用python中的字典資料型別,通過key,value的賦值,多層巢狀字典,實現決策樹的儲存。
決策樹的構建有3個基本的結束條件:
(1)用於構建決策樹的特徵使用完畢
(2)葉子結點中的標籤均為同一類別
(3)決策樹構建完成
def
treegrow
(dataset,features):
if len(classlist) == classlist.count(classlist[0]): #no more feature
return classifymaxlabel(classlist)
if len(dataset[0]) == 1: # pure dataset
return classlist[0]
bestfeature = findbestsplit(dataset)
del bestfeature
left_data,right_data = splitdataset(dataset, bestfeature)
tree['bestfeature-'] = treegrow(left_data,features)
tree['bestfeature+'] = treegrow(right_data,features)
return tree # finish tree
函式名功能
createdataset(data)
建立資料集
splitdataset(data,feature,value)
劃分用來訓練左右子樹的資料集
findbestsplit(dataset)
根據資訊增益找到最合適的屬性進行結點劃分
calcshannonent(dataset)
按照屬性分類計算資料的資訊熵
classfy(classlist)
找出類別列表中出現次數最多的類別
predict(tree,newobject)
實現決策樹的**功能
在執行時遇到了問題:決策樹所有的右子樹均為空。
原因分析:在pycharm裡除錯程式,發現構建失敗原因是構建右子樹時,屬性集feature_list為空。用於結點劃分的屬性儲存在屬性集feature_list中,在構建左右子樹時均會使用屬性集中的屬性進行結點劃分。決策樹構建的遞迴演算法與在c、c++其他語言實現是相同的,但c、c++中list為值型別,而python中列表list為引用型別,在函式遞迴構建左子樹的過程中使用過的屬性會從feature_list中刪除,feature_list的值會發生改變。因此,在構建右子樹時,屬性feature_list 為空,決策樹所有的右子樹沒能完成構建。
解決方法:通過copy模組的deepcopy函式對feature_list列表進行硬拷貝,拷貝在函式的當前層,在遞迴構建樹的時候採用硬拷貝的屬性集構建右子樹。
right_features = copy.deepcopy(features) # deepcopy the feature list
left_data,right_data = splitdataset(dataset, bestfeature)
tree['bestfeature-'] = treegrow(left_data,features)
tree['bestfeature+'] = treegrow(right_data,right_features)
小結: 關於列表是引用型別的問題,在之前的部落格裡也有提到過:python多維陣列初始化的兩種方式和淺拷貝問題,但是具體運用時,還是經常會忽略這些細節。python裡的引用型別主要就是列表。元組不能改變其中的元素,只能整個元組一起刪除或者和其他元組組合在一起。字典資料結構的value值要求是不能改變的資料型別,如整數、字串。
這個bug找了很久才找到原因,吃一塹長一智,以後對程式語言裡的引用型別的操作要多加注意,避免出現類似的錯誤。
決策樹演算法 python實現
定義 資訊增益 再劃分資料之前之後資訊發生的變化。香濃熵 簡稱熵 集合資訊的度量方式,熵是資訊的期望值。其實決策樹主要就是選擇最優劃分屬性對給定集合進行劃分,隨著花粉的不斷進行,我們希望最終決策樹所包含的樣本盡量屬於同一類別,即結點的 純度 越來越高。資訊增益的計算 1.資訊熵的計算ent d 越小...
Python實現決策樹演算法
決策樹的一般流程 檢測資料集中的每個子項是否屬於同乙個分類 if so return 類標籤 else 尋找劃分資料集的最好特徵 劃分資料集 建立分支 節點 from math import log import operator 生成樣本資料集 defcreatedataset dataset 1...
決策樹演算法 Python實現
import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import fetch california housing housing fetch california housing print housi...