機器學習之決策樹詳細講解及程式碼講解

yaohuan2017發表於2020-09-29

決策樹講解

決策樹是一種機器學習的方法。決策樹的生成演算法有ID3, C4.5和C5.0等。決策樹是一種樹形結構,其中每個內部節點表示一個屬性上的判斷,每個分支代表一個判斷結果的輸出,最後每個葉節點代表一種分類結果。

	機器學習中分類和預測演算法的評估:
	
	準確率
	速度
	強壯行
	可規模性
	可解釋性

1. 什麼是決策樹/判定樹(decision tree)?

判定樹是一個類似於流程圖的樹結構:其中,每個內部結點表示在一個屬性上的測試,每個分支代表一個屬性輸出,而每個樹葉結點代表類或類分佈。樹的最頂層是根結點。

2. 機器學習中分類方法中的一個重要演算法

  1. 構造決策樹的基本演算法 分支 根結點
    結點
    樹葉

    3.1 熵(entropy)概念:

      資訊和抽象,如何度量?
      1948年,夏農提出了 ”資訊熵(entropy)“的概念
      一條資訊的資訊量大小和它的不確定性有直接的關係,要搞清楚一件非常非常不確定的事情,或者          
      是我們一無所知的事情,需要了解大量資訊==>資訊量的度量就等於不確定性的多少
      
      例子:猜世界盃冠軍,假如一無所知,猜多少次?
      每個隊奪冠的機率不是相等的
      
      位元(bit)來衡量資訊的多少
    
      
    
      
    
      變數的不確定性越大,熵也就越大
    

    3.1 決策樹歸納演算法 (ID3)

      1970-1980, J.Ross. Quinlan, ID3演算法
    
      選擇屬性判斷結點
    
      資訊獲取量(Information Gain):Gain(A) = Info(D) - Infor_A(D)
      通過A來作為節點分類獲取了多少資訊
    
            
      
    
    
      
    
      
      
    
       類似,Gain(income) = 0.029, Gain(student) = 0.151, Gain(credit_rating)=0.048
    
      所以,選擇age作為第一個根節點
    

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

在這裡插入圖片描述

演算法:
	樹以代表訓練樣本的單個結點開始(步驟1)。
	如果樣本都在同一個類,則該結點成為樹葉,並用該類標號(步驟2 和3)。
	否則,演算法使用稱為資訊增益的基於熵的度量作為啟發資訊,選擇能夠最好地將樣本分類的屬性(步驟6)。該屬性成為該結點的“測試”或“判定”屬性(步驟7)。在演算法的該版本中,
	所有的屬性都是分類的,即離散值。連續屬性必須離散化。
	對測試屬性的每個已知的值,建立一個分枝,並據此劃分樣本(步驟8-10)。
	演算法使用同樣的過程,遞迴地形成每個劃分上的樣本判定樹。一旦一個屬性出現在一個結點上,就不必該結點的任何後代上考慮它(步驟13)。
	遞迴劃分步驟僅當下列條件之一成立停止:
	(a) 給定結點的所有樣本屬於同一類(步驟2 和3)。
	(b) 沒有剩餘屬性可以用來進一步劃分樣本(步驟4)。在此情況下,使用多數表決(步驟5)。
	這涉及將給定的結點轉換成樹葉,並用樣本中的多數所在的類標記它。替換地,可以存放結
	點樣本的類分佈。
	(c) 分枝
	test_attribute = a i 沒有樣本(步驟11)。在這種情況下,以 samples 中的多數類
	建立一個樹葉(步驟12)

           


 ## 3.1 其他演算法:
           C4.5:  Quinlan
           Classification and Regression Trees (CART): (L. Breiman, J. Friedman, R. Olshen, C. Stone)
           共同點:都是貪心演算法,自上而下(Top-down approach)
           區別:屬性選擇度量方法不同: C4.5 (gain ratio), CART(gini index), ID3 (Information Gain)

##  3.2 如何處理連續性變數的屬性? 

4. 樹剪枝葉 (避免overfitting)
     4.1 先剪枝
     4.2 後剪枝


5. 決策樹的優點:
     直觀,便於理解,小規模資料集有效     

6. 決策樹的缺點:
     處理連續變數不好
     類別較多時,錯誤增加的比較快
     可規模性一般

4.機器學習之決策樹python實際操作

  1. Python機器學習的庫:scikit-learn

    4.1: 特性:
    簡單高效的資料探勘和機器學習分析
    對所有使用者開放,根據不同需求高度可重用性
    基於Numpy, SciPy和matplotlib
    開源,商用級別:獲得 BSD許可

4.2 覆蓋問題領域:
分類(classification), 迴歸(regression), 聚類(clustering), 降維(dimensionality reduction)
模型選擇(model selection), 預處理(preprocessing)

4.3. 使用scikit-learn

source activate momo
conda install scikit-learn
conda  install six

4.5. 例子:
安裝 Graphviz: http://www.graphviz.org/

conda install graphviz
  轉化dot檔案至pdf視覺化決策樹:dot -Tpdf **.dot -o outpu.pdf

5.程式碼實現

在這裡插入圖片描述

# -*- coding:utf-8 -*-
# power by ylb
from sklearn.feature_extraction import DictVectorizer
import csv
from sklearn import tree
from sklearn import preprocessing
from six import StringIO


# Read in the csv file and put features into list of dict and list of class label
allElectronicsData = open(r'/home/ylb/python/AllElectronics.csv', 'rt')
reader = csv.reader(allElectronicsData)
headers = next(reader)

print(headers)

featureList = []
labelList = []

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)

# Vetorize features
vec = DictVectorizer()
dummyX = vec.fit_transform(featureList) .toarray()

print("dummyX: " + str(dummyX))
print(vec.get_feature_names())

print("labelList: " + str(labelList))

# vectorize class labels
lb = preprocessing.LabelBinarizer()
dummyY = lb.fit_transform(labelList)
print("dummyY: " + str(dummyY))

# Using decision tree for classification
# clf = tree.DecisionTreeClassifier()
clf = tree.DecisionTreeClassifier(criterion='entropy')
clf = clf.fit(dummyX, dummyY)
print("clf: " + str(clf))


# Visualize model
with open("/home/ylb/python/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] = 1
print("newRowX: " + str(newRowX))

# predictedY = clf.predict(newRowX)
predictedY = clf.predict(newRowX.reshape(1,-1))
print("predictedY: " + str(predictedY))


關於程式碼得講解請參考視訊
點我觀看視訊

相關文章