1、理論知識html
一、基本流程python
斷定樹/決策樹 (decision tree) 是一類常見的機器學習方法。
算法
每一個內部結點表示在一個屬性上的測試,每一個分支表明一個屬性輸出,而每一個樹葉結點表明類或類分佈。樹的最頂層是根結點。決策樹學習的目的是爲了產生一棵泛化能力強,即處理未見示例能力強的決策樹,其基本流程遵循簡單且直觀的"分而治之" (divide-and-conquer)策略。
數組
二、劃分選擇app
在1948年,香農引入了信息熵,將其定義爲離散隨機事件出現的機率,一個系統越是有序,信息熵就越低,反之一個系統越是混亂,它的信息熵就越高。因此信息熵能夠被認爲是系統有序化程度的一個度量。機器學習
假如一個隨機變量X的取值爲X={x1,x2,……,xn},每一變量的機率分別爲{p1,p2,……,pn},那麼X的信息熵定義爲:ide
信息增益是針對一個特徵而言的,就是看一個特徵t,系統有它和沒有它時的信息量各是多少,二者的差值就是這個特徵給系統帶來的信息量,即信息增益。接下來,以一個屬性不一樣的人購買電腦的例子來講明什麼是信息增益。稍後,也會用Python代碼實現此例的決策樹算法。函數
從上圖能夠看出,一共14組數據,在最後一列的數據中是購買電腦的與否,一共是9個購買,5個非購買。學習
由此能夠獲得結果的信息熵爲 :測試
age分支有youth,middle_aged,senior,其信息熵爲:
所以age屬性的信息增益爲:
相似地,咱們能夠得出其它屬性的信息增益:
Gain(income) = 0.029, Gain(student) = 0.151, Gain(credit_rating)=0.048
值得一提的是,咱們應該忽略編號這一屬性,由於其產生了14個分支,每一個分支節點的純度以達到最大,以其做爲結點的決策樹不具備泛化能力,沒法進行有效預測。
相比較,咱們就能夠得出,age的信息增益最大,所以選擇age爲根結點,再選出其它的做爲結點,能夠畫出一個決策樹的圖。
在決策樹的每個非葉子結點劃分以前,先計算每個屬性所帶來的信息增益,選擇最大信息增益的屬性來劃分,由於信息增益越大,區分樣本的能力就越強,越具備表明性,很顯然這是一種自頂向下的貪心策略。以上就是ID3算法的核心思想。顯然,ID3算法是以信息增益爲準則來選擇劃分屬性。
三、剪枝處理
四、連續與缺失值
五、多變量決策樹
2、代碼
一、Python實現ID3算法,以上文購買電腦爲例。
# sklearn 是傳統機器學習的包 # python自帶處理csv文件的庫 from sklearn.feature_extraction import DictVectorizer import csv from sklearn import tree from sklearn import preprocessing # 讀取csv文件數據,CSV是以逗號間隔的文本文件,excel默認保存爲XLSX格式,包含文本、數值、公式、格式等,當不須要公式格式時,能夠保存爲CSV文件 allElectronicsData = open(r'AllElectronics.csv', 'rt') reader = csv.reader(allElectronicsData) # 讀出第一行的內容,並打印觀察 headers = next(reader) print(headers) # sklearn 只容許輸入的內容是數值,因此咱們要把表格裏的內容轉換爲數值,進而調用sklearn的包 # 創建兩個列表以存儲條件和結果 featureList = [] labelList = [] # labelList 裏存放表格裏的結果內容 # featureList 裏存放表格裏的條件屬性,必須是以字典形式存儲在列表中,這樣才能夠用DictVectorizer()函數,將列表中的字典轉化成數值 for row in reader: labelList.append(row[len(row)-1]) rowDict = {} for i in range(1, len(row)-1): rowDict[headers[i]] = row[i] featureList.append(rowDict) print(featureList) print(labelList) # 類DictVectorizer可用於將表示爲標準 Python dict對象列表的要素數組轉換爲scikit-learn估計量使用的NumPy/SciPy表示。 # 使用DictVectorizer裏的fit_transform函數轉換數值 vec = DictVectorizer() dummyX = vec.fit_transform(featureList).toarray() print("dummyX: " + str(dummyX)) print(vec.get_feature_names()) print("labelList: " + str(labelList)) lb = preprocessing.LabelBinarizer() dummyY = lb.fit_transform(labelList) print("dummyY: " + str(dummyY)) # 使用決策樹 # criterion='entropy' 此變量輸入則表明決策樹的算法是選取信息熵(ID3算法) clf = tree.DecisionTreeClassifier(criterion='entropy') clf = clf.fit(dummyX, dummyY) print("clf: " + str(clf)) # 新建doc文件,在其中顯示決策樹 with open("allElectronicInformationGainOri.dot", 'w') as f: f = tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f) oneRowX = dummyX[0, :] print("oneRowX: " + str(oneRowX)) newRowX = oneRowX newRowX[0] = 1 newRowX[2] = 0 print("newRowX: " + str(newRowX))
3、參考資料
一、《機器學習》——周志華老師
二、http://www.cnblogs.com/starfire86/p/5749328.html 內含C++代碼實現決策樹
ps:待更新。
本人初學者,有錯誤歡迎指出。感謝。