決策樹
決策樹的本質:
對數據進行分類,降低不確定性。
這裏,我們來判斷下面幾個人中是否喜歡打籃球。構建的決策樹如下:
所謂決策樹,樹在前面,決策在後面。
這裏,我們有假設一個美女相親進行決策的情況。呵呵
重點在找根節點。
熵
熵可以用來表示的是物體內部的混亂程度,事實上,這個說法在化學中比較常用,可以回憶一下;在這裏,我們可以認爲是表示分類的數據純與不純的度量。
這裏可以認爲,集合A的熵比較大,集合B的熵比較低。下面講一下熵的數學定義。
這裏n表示有n個類別,pi表示對應類別i出現的概率。不管是熵還是Gini係數,他們都是越小越好。
構造樹的基本想法是隨着樹深度的增加,節點的熵迅速地降低。熵降低的越快越好,這裏就需要我們選擇根節點;這樣我們有望得到一顆高度最矮的決策樹,只要三步就不走五步。
示例
play作爲標籤,其他的作爲特徵。
在沒有給定任何天氣信息的時候,根據歷史數據,我們只知道新的一天打球的概率是9/14,不打的概率是5/14。此時的熵爲:
下面我們來構造決策樹。
第一步,根據每個特徵進行劃分,對每個特徵進行相同的嘗試。
第二步,計算各特徵作爲根節點時每個分類的熵。
第三步,計算以outlook作爲根節點的熵和信息增溢;同理,可以計算其他特徵作爲根節點的熵。
信息增溢表示熵值的變化,信息增溢越大,表示熵的變化越快,即當前劃分中,哪個特徵使劃分信息增溢最大,那麼這個節點就可以作爲根節點,即此時,outlook應該作爲根節點。
之後,進行第二個根節點的判斷,原理如上,相當於一個遞歸的過程。
決策樹劃分依據之一: 信息增益
基尼係數:劃分更加仔細
需要注意的是,對於特徵的選擇 還需要認真的考慮並選擇符合實際需求的特徵。
sklearn決策樹API
class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
決策樹分類器
criterion:默認是’gini’係數,也可以選擇信息增益的熵’entropy’
max_depth:樹的深度大小
random_state:隨機數種子
method:decision_path:返回決策樹的路徑
決策樹的結構、本地保存
1、sklearn.tree.export_graphviz() 該函數能夠導出DOT格式tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
2、工具:(能夠將dot文件轉換爲pdf、png)安裝graphvizubuntu:sudo apt-get install graphviz Mac:brew install graphviz3
3、運行命令然後我們運行這個命令$ dot -Tpng tree.dot -o tree.png
決策樹的優缺點以及改進
優點:
簡單的理解和解釋,樹木可視化。
需要很少的數據準備,其他技術通常需要數據歸一化,
缺點:
決策樹學習者可以創建不能很好地推廣數據的過於複雜的樹,
這被稱爲過擬合。決策樹可能不穩定,因爲數據的小變化可能會導致完全不同的樹被生成
改進:
減枝cart算法
隨機森林(集成學習)
集成學習方法-隨機森林
1、什麼是隨機森林
2、隨機森林的過程、優勢
3、泰坦尼克號乘客生存分類分析
集成學習方法
集成學習通過建立幾個模型組合的來解決單一預測問題。它的工作原理是生成多個分類器/模型,各自獨立地學習和作出預測。這些預測最後結合成單預測,因此優於任何一個單分類的做出預測。
什麼是隨機森林
定義:在機器學習中,隨機森林是一個包含多個決策樹的分類器,並且其輸出的類別是由個別樹輸出的類別的衆數而定。
學習算法
根據下列算法而建造每棵樹:
用N來表示訓練用例(樣本)的個數,M表示特徵數目。
輸入特徵數目m,用於確定決策樹上一個節點的決策結果;其中m應遠小於M。
從N個訓練用例(樣本)中以有放回抽樣(bootstrop)的方式,取樣N次,形成一個訓練集(即bootstrap取樣),並用未抽到的用例(樣本)作預測,評估其誤差。
隨機森林建立多個決策樹的過程:
N個樣本,M個特徵
單個樹建立過程:
1,隨機在N個樣本中選擇一個樣本,重複N次(樣本有可能重複)
2,隨機在M個特徵中選出m個特徵
建立10棵決策樹,樣本和特徵大多不一樣
爲什麼要隨機抽樣訓練集?
如果不進行隨機抽樣,每棵樹的訓練集都一樣,那麼最終訓練出的樹分類結果也是完全一樣的.
爲什麼要有放回地抽樣?
如果不是有放回的抽樣,那麼每棵樹的訓練樣本都是不同的,都是沒有交集的,這樣每棵樹都是“有偏的”,都是絕對“片面的”(當然這樣說可能不對),也就是說每棵樹訓練出來都是有很大的差異的;而隨機森林最後分類取決於多棵樹(弱分類器)的投票表決。
集成學習API
class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None)
隨機森林分類器
n_estimators:integer,optional(default = 10) 森林裏的樹木數量
criteria:string,可選(default =“gini”)分割特徵的測量方法
max_depth:integer或None,可選(默認=無)樹的最大深度
bootstrap:boolean,optional(default = True)是否在構建樹時使用放回抽樣
需要注意的是上述參數基本都是超參數:
n_estimator:決策樹數量
max_depth:最大深度
然後,在調優過程中,超參數的作用就可以具體體現了。
隨機森林的優點
在當前所有算法中,具有極好的準確率
能夠有效地運行在大數據集上
能夠處理具有高維特徵的輸入樣本,而且不需要降維
能夠評估各個特徵在分類問題上的重要性對於缺省值問題也能夠獲得很好得結果
分析示例
## 泰坦尼克號乘客生存分類
from sklearn.datasets import load_iris, fetch_20newsgroups, load_boston
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
def decision():
"""
決策樹對泰坦尼克號進行預測生死
:return: None
"""
# 獲取數據
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
# 處理數據,找出特徵值和目標值
x = titan[['pclass', 'age', 'sex']]
y = titan['survived']
print(x)
# 缺失值處理,用平均數填充
x['age'].fillna(x['age'].mean(), inplace=True)
# 分割數據集到訓練集合測試集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# 進行處理(特徵工程)特徵-》類別-》one_hot編碼
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient="records"))
print(dict.get_feature_names())
x_test = dict.transform(x_test.to_dict(orient="records"))
# print(x_train)
# 用決策樹進行預測
# dec = DecisionTreeClassifier()
#
# dec.fit(x_train, y_train)
#
# # 預測準確率
# print("預測的準確率:", dec.score(x_test, y_test))
#
# # 導出決策樹的結構
# export_graphviz(dec, out_file="./tree.dot", feature_names=['年齡', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
# 隨機森林進行預測 (超參數調優)
rf = RandomForestClassifier()
param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}
# 網格搜索與交叉驗證
gc = GridSearchCV(rf, param_grid=param, cv=2)
gc.fit(x_train, y_train)
print("準確率:", gc.score(x_test, y_test))
print("查看選擇的參數模型:", gc.best_params_)
return None
if __name__ == "__main__":
decision()
## 鶯尾花示例
from sklearn.cross_validation import train_test_split
all_inputs = iris_data[['sepal_length_cm', 'sepal_width_cm',
'petal_length_cm', 'petal_width_cm']].values
all_classes = iris_data['class'].values # 注意這裏是取值
(training_inputs,
testing_inputs,
training_classes,
testing_classes) = train_test_split(all_inputs, all_classes, train_size=0.75, random_state=1)
from sklearn.tree import DecisionTreeClassifier
# 1.criterion gini or entropy
# 2.splitter best or random 前者是在所有特徵中找最好的切分點 後者是在部分特徵中(數據量大的時候)
# 3.max_features None(所有),log2,sqrt,N 特徵小於50的時候一般使用所有的
# 4.max_depth 數據少或者特徵少的時候可以不管這個值,如果模型樣本量多,特徵也多的情況下,可以嘗試限制下
# 5.min_samples_split 如果某節點的樣本數少於min_samples_split,則不會繼續再嘗試選擇最優特徵來進行劃分
# 如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。
# 6.min_samples_leaf 這個值限制了葉子節點最少的樣本數,如果某葉子節點數目小於樣本數,則會和兄弟節點一起被
# 剪枝,如果樣本量不大,不需要管這個值,大些如10W可是嘗試下5
# 7.min_weight_fraction_leaf 這個值限制了葉子節點所有樣本權重和的最小值,如果小於這個值,則會和兄弟節點一起
# 被剪枝默認是0,就是不考慮權重問題。一般來說,如果我們有較多樣本有缺失值,
# 或者分類樹樣本的分佈類別偏差很大,就會引入樣本權重,這時我們就要注意這個值了。
# 8.max_leaf_nodes 通過限制最大葉子節點數,可以防止過擬合,默認是"None”,即不限制最大的葉子節點數。
# 如果加了限制,算法會建立在最大葉子節點數內最優的決策樹。
# 如果特徵不多,可以不考慮這個值,但是如果特徵分成多的話,可以加以限制
# 具體的值可以通過交叉驗證得到。
# 9.class_weight 指定樣本各類別的的權重,主要是爲了防止訓練集某些類別的樣本過多
# 導致訓練的決策樹過於偏向這些類別。這裏可以自己指定各個樣本的權重
# 如果使用“balanced”,則算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。
# 10.min_impurity_split 這個值限制了決策樹的增長,如果某節點的不純度
# (基尼係數,信息增益,均方差,絕對差)小於這個閾值
# 則該節點不再生成子節點。即爲葉子節點 。
decision_tree_classifier = DecisionTreeClassifier()
# Train the classifier on the training set
decision_tree_classifier.fit(training_inputs, training_classes)
# Validate the classifier on the testing set using classification accuracy
decision_tree_classifier.score(testing_inputs, testing_classes)