Machine Learning Notes-Decision Trees-Udacity

什么是 Decision Tree?

Decision Tree 可以把 Input 映射到離散的 Labels。對每個節點上的 Attribute 提問,取不同的 Value 走向不同的 Children,最終得到結果。

例如,這是一個不能 Linearly Separated 的問題,但是可以被 Decision Tree 分開。

當 instances 是連續的時候也可以用 DT。

怎樣構建 Decision Tree?

先要找到最佳的 Attribute,然后提出合適的問題,可以把數據盡量地分成兩份。

ID3 Algorithm 可以用來尋找 Best Attribute。

什么是 Best Attribute?

通俗地講,就是最好可以直接把數據分成目標類別,用數學的角度衡量就是用 Entropy 來計算 Information Gain。


用 sklearn 來 create 和 train Decision Trees。

Step-1: Decision Tree Classifier

Resources:
http://scikit-learn.org/stable/modules/tree.html#classification

def classify(features_train, labels_train):
    
    ### your code goes here--should return a trained decision tree classifer
    from sklearn import tree
    
    clf=tree.DecisionTreeClassifier()
    clf=clf.fit(features_train, labels_train)
    
    
    return clf
#!/usr/bin/python

""" lecture and example code for decision tree unit """

import sys
from class_vis import prettyPicture, output_image
from prep_terrain_data import makeTerrainData

import matplotlib.pyplot as plt
import numpy as np
import pylab as pl
from classifyDT import classify

features_train, labels_train, features_test, labels_test = makeTerrainData()



### the classify() function in classifyDT is where the magic
### happens--fill in this function in the file 'classifyDT.py'!
clf = classify(features_train, labels_train)


#### grader code, do not modify below this line

prettyPicture(clf, features_test, labels_test)
output_image("test.png", "png", open("test.png", "rb").read())

Decision Tree Boundary 很獨特,像現代藝術,還有一些小島。
但是有些 Overfitting,

Step-2: Accuracy

Resources:
http://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html

import sys
from class_vis import prettyPicture
from prep_terrain_data import makeTerrainData

import numpy as np
import pylab as pl

features_train, labels_train, features_test, labels_test = makeTerrainData()

#################################################################################

########################## DECISION TREE #################################

#### your code goes here
from sklearn import tree
clf=tree.DecisionTreeClassifier()
clf=clf.fit(features_train, labels_train)
labels_predict=clf.predict(features_test)

from sklearn.metrics import accuracy_score


acc = accuracy_score(labels_test,labels_predict)
### you fill this in!
### be sure to compute the accuracy on the test set


    
def submitAccuracies():
  return {"acc":round(acc,3)}

上述 Classifier 得到準確率大約在 91%,在這里有一些 Overfitting,我們也許可以通過 Tuning some Parameters 來改善這個精度。

Step-3: 接下來看哪些 Parameters 可以 Tune

Resource:
Parameters of Decision Tree
http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier

DecisionTreeClassifier 有如下幾個 Parameters

class sklearn.tree.
DecisionTreeClassifier
(
criterion='gini'
,
splitter='best',
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.0,
max_features=None,
random_state=None,
max_leaf_nodes=None,
class_weight=None,
presort=False)

其中 min_samples_split 如果太小,可能會造成 Overfitting,因為它的意思是,當 Node 上的值小于什么時就不能再分下去了,因此越小的話,分出來的層就越多。當把默認值改成 50 時,就看不到 Overfitting 的那條線了。

用代碼運行一下,看哪個值可以得到更高的準確率:

import sys
from class_vis import prettyPicture
from prep_terrain_data import makeTerrainData

import matplotlib.pyplot as plt
import numpy as np
import pylab as pl

features_train, labels_train, features_test, labels_test = makeTerrainData()



########################## DECISION TREE #################################


### your code goes here--now create 2 decision tree classifiers,
### one with min_samples_split=2 and one with min_samples_split=50
### compute the accuracies on the testing data and store
### the accuracy numbers to acc_min_samples_split_2 and
### acc_min_samples_split_50, respectively

from sklearn import tree
clf_2=tree.DecisionTreeClassifier(min_samples_split=2)
clf_2=clf_2.fit(features_train, labels_train)
labels_predict_2=clf_2.predict(features_test)

clf_50=tree.DecisionTreeClassifier(min_samples_split=50)
clf_50=clf_50.fit(features_train, labels_train)
labels_predict_50=clf_50.predict(features_test)

from sklearn.metrics import accuracy_score

acc_min_samples_split_2=accuracy_score(labels_test,labels_predict_2)
acc_min_samples_split_50=accuracy_score(labels_test,labels_predict_50)




def submitAccuracies():
  return {"acc_min_samples_split_2":round(acc_min_samples_split_2,3),
          "acc_min_samples_split_50":round(acc_min_samples_split_50,3)}

比較 min_samples_split 等于50 的時候,精度比 2 的時候大。

{"message": "{'acc_min_samples_split_50': 0.912, 'acc_min_samples_split_2': 0.908}"}

熵,很重要,決定著 Decision Tree 如何劃分 data。

Definition: measure of impurity of a bunch of examples.

Formular:

例:
下面這個例子,計算它的 Entropy:

最后的 Entropy 結果如下:


那么熵是如何影響 Decision Tree 的呢?
Information Gain:

Decision Tree 就是要最大化 Information Gain

現在看 grade 這個node上,當 grade=steep 時,slow和fast的熵是多少,當 grade=flat 時,這個熵=0,因為只有一類 fast,取對數時=0. Remember we are calculating entropy, not counting observations. What is the entropy of a set that contains observations of the same class?

例:

數據:


要計算Information Gain:

Entropy of Parent,即 speed

Entropy of Children,即 grade

其中 flat children的熵是:


其中 steep children的熵是:


接著計算公式的后半部分:


最后得到 Information gain=1-3/4*0.9184-0=0.3112

接著計算下一個Children

所以 bumpiness 的 Information Gain=0,也就是我們沒有從 bumpiness 得到任何有用的信息。

接著看 speed limit 這個children的 Information Gain=1,也就是非常的 Pure,這是我們希望用來 split 的因素。

綜上,
steep children 的 Information gain=0.3112
bumpiness 的 Information Gain=0
speed limit 的 Information Gain=1
所以選擇 speed limit 來作為split node。


此外 Decision Tree 的這個Parameter :criterion='gini' 也是可以 Tune 的,gini index 是類似于 metric of impurity,它和 Entropy Information Gain 略有不同,但是效果是一樣的。


Bias and Variance


Strengths and Weakness

Weakness:

prone to overfitting: when lots of features, complicate tree
so, need to tune parameters, stop the growth of trees at appropriate time.

Strengths:

Ensemble method: Build bigger classifier out of decision trees,

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 多年后,有人問她,你最愛的人為你做過的最讓你感動的一件事是什么,她眼角微溢出一點不可控制了的笑意——“他為了...
    爵堯目閱讀 230評論 0 1
  • 數據刷新 添加數據 刪除數據 更改數據 全局刷新方法(最常用) [self.tableViewreloadData...
    iOS_Cqlee閱讀 603評論 0 2
  • 引語:你有沒想過,有一天突然驚醒,發現自己在高中的課堂上睡著了。現在經歷的所有其實只是一場夢。陽光照的你臉皺成一團...
    肆年ForYou閱讀 805評論 2 6