决策树与随机森林
1.決策樹(shù)基本概念:
? ? ? ? 決策樹(shù)(Decision Tree)是在已知各種情況發(fā)生概率的基礎(chǔ)上,通過(guò)構(gòu)成決策樹(shù)來(lái)求取凈現(xiàn)值的期望值大于等于零的概率,評(píng)價(jià)項(xiàng)目風(fēng)險(xiǎn),判斷其可行性的決策分析方法,是直觀運(yùn)用概率分析的一種圖解法。由于這種決策分支畫(huà)成圖形很像一棵樹(shù)的枝干,故稱決策樹(shù)。在機(jī)器學(xué)習(xí)中,決策樹(shù)是一個(gè)預(yù)測(cè)模型,他代表的是對(duì)象屬性與對(duì)象值之間的一種映射關(guān)系。
例子:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
這其中右邊彩色樹(shù)狀就是決策樹(shù),從圖中我們還可以看出決策樹(shù)是if-else的邏輯?
2.信息論基礎(chǔ):熵,信息熵
什么是熵:熵的概念源于物理學(xué),用于度量一個(gè)熱力學(xué)系統(tǒng)的無(wú)序程度。
信息熵:1948年,香農(nóng)提出了“信息熵”的概念!在信息論里面,信息熵衡量信息量的大小,也就是對(duì)隨機(jī)變量不確定度的一個(gè)衡量。熵越大,不確定性越大;
? 案例:? ? 32支球隊(duì),在完全未知的情況下,求壓中冠軍的信息熵:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
其中 n=32,概率p? =???,最后為比特
3.決策樹(shù)的劃分依據(jù)之一:信息增益(ID3)
? ? 即:當(dāng)?shù)弥粋€(gè)特征條件之后,減少的信息熵的大小
? ?特征A對(duì)訓(xùn)練集D的信息增益g(D,A),定義為集合D的信息熵H(D)與特征A給定條件D的信息條件熵H(D|A)之差,即公式為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ?其中H(D)為初始信息熵大小。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
案例:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
求當(dāng)前所給信息的信息熵(以下都是針對(duì)類別):
?H(D) = -(9/15*log9/15+6/15log(6/15))?= 0.971
假設(shè)年齡為特征A1,A2,A3,A4分別為有工作,有自己父子,信貸情況,求信息熵:
?g(D,年齡) = H(D) - H(D'|年齡) = H(D) - [1/3H(青年)+1/3H(中年)+1/3H(老年)]
? ? H(青年) = -(2/5log(2/5)+3/5log(3/5))
? ? H(中年) = -(2/5log(2/5)+3/5log(3/5))
? ? H(老年) = -(4/5log(4/5)+1/5log(1/5))
這樣求得g(D,A2) = 0.324,g(D,A3) = 0.420,g(D,A4) = 0.363
特征A3(有自己的房子)的信息增益最大,所有我們選有自己房子為最有特征。
4.決策樹(shù)的劃分依據(jù)之一:C4.5
? ? 信息增益比 最大的準(zhǔn)則
5.決策樹(shù)的劃分依據(jù)之一:CART
?回歸樹(shù):平方誤差最小
分類樹(shù):基尼系數(shù) 最小的準(zhǔn)則,在sklearn中可以選擇劃分的默認(rèn)原則
6.API
class sklearn.tree.DecisionTreeClassifier(criterion="gini",max_depth=None,random_state=None)
? ? .決策樹(shù)分類器
? ? .criterion:默認(rèn)是gini系數(shù),也可以是信息增益的熵"entropy"
? ? .max_depth:樹(shù)的深度大小
? ? .random_state:隨機(jī)種子數(shù)
? ? .method
? ? .decision_path:返回決策樹(shù)的路徑
7.案例: 泰坦尼克號(hào)乘客生存分類
數(shù)據(jù)集地址:??http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt
泰坦尼克號(hào)數(shù)據(jù)
在泰坦尼克號(hào)和titanic2數(shù)據(jù)幀描述泰坦尼克號(hào)上的個(gè)別乘客的生存狀態(tài)。在泰坦尼克號(hào)的數(shù)據(jù)幀不包含從劇組信息,但它確實(shí)包含了乘客的一半的實(shí)際年齡。關(guān)于泰坦尼克號(hào)旅客的數(shù)據(jù)的主要來(lái)源是百科全書(shū)Titanica。這里使用的數(shù)據(jù)集是由各種研究人員開(kāi)始的。其中包括許多研究人員創(chuàng)建的旅客名單,由Michael A. Findlay編輯。
我們提取的數(shù)據(jù)集中的特征是票的類別,存活,乘坐班,年齡,登陸,home.dest,房間,票,船和性別。乘坐班是指乘客班(1,2,3),是社會(huì)經(jīng)濟(jì)階層的代表。
其中age數(shù)據(jù)存在缺失。
Python 代碼實(shí)現(xiàn):
# -*- coding: utf-8 -*- '''@Author :Jason 1、pd讀取數(shù)據(jù)2、選擇有影響的特征,處理缺失值3、進(jìn)行特征工程,pd轉(zhuǎn)換字典,特征抽取x_train.to_dict(orient="records")4、決策樹(shù)估計(jì)器流程 ''' import pandas as pd from sklearn.feature_extraction import DictVectorizer from sklearn.tree import DecisionTreeClassifier, export_graphvizdef decision():"""決策樹(shù)對(duì)泰坦尼克號(hào)進(jìn)行預(yù)測(cè)生死:return: None"""# 獲取數(shù)據(jù)titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")# 處理數(shù)據(jù),找出特征值和目標(biāo)值x = titan[['pclass', 'age', 'sex']]y = titan['survived']print(x)# 缺失值處理x['age'].fillna(x['age'].mean(), inplace=True)# 分割數(shù)據(jù)集到訓(xùn)練集合測(cè)試集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)# 進(jìn)行處理(特征工程)特征-》類別-》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)# 用決策樹(shù)進(jìn)行預(yù)測(cè)max_depth = n 會(huì)影響決策樹(shù)的結(jié)果dec = DecisionTreeClassifier()dec.fit(x_train, y_train)# 預(yù)測(cè)準(zhǔn)確率print("預(yù)測(cè)的準(zhǔn)確率:", dec.score(x_test, y_test))# 導(dǎo)出決策樹(shù)的結(jié)構(gòu)export_graphviz(dec, out_file="./tree.dot",feature_names=['年齡', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])return Noneif __name__ == "__main__":decision()結(jié)果:?
pclass age sex 0 1st 29.0000 female 1 1st 2.0000 female 2 1st 30.0000 male 3 1st 25.0000 female 4 1st 0.9167 male 5 1st 47.0000 male 6 1st 63.0000 female 7 1st 39.0000 male 8 1st 58.0000 female 9 1st 71.0000 male 10 1st 47.0000 male 11 1st 19.0000 female 12 1st NaN female 13 1st NaN male 14 1st NaN male 15 1st 50.0000 female 16 1st 24.0000 male 17 1st 36.0000 male 18 1st 37.0000 male 19 1st 47.0000 female 20 1st 26.0000 male 21 1st 25.0000 male 22 1st 25.0000 male 23 1st 19.0000 female 24 1st 28.0000 male 25 1st 45.0000 male 26 1st 39.0000 male 27 1st 30.0000 female 28 1st 58.0000 female 29 1st NaN male... ... ... 1283 3rd NaN female 1284 3rd NaN male 1285 3rd NaN male 1286 3rd NaN male 1287 3rd NaN male 1288 3rd NaN male 1289 3rd NaN male 1290 3rd NaN male 1291 3rd NaN male 1292 3rd NaN male 1293 3rd NaN female 1294 3rd NaN male 1295 3rd NaN male 1296 3rd NaN male 1297 3rd NaN male 1298 3rd NaN male 1299 3rd NaN male 1300 3rd NaN male 1301 3rd NaN male 1302 3rd NaN male 1303 3rd NaN male 1304 3rd NaN female 1305 3rd NaN male 1306 3rd NaN female 1307 3rd NaN female 1308 3rd NaN male 1309 3rd NaN male 1310 3rd NaN male 1311 3rd NaN female 1312 3rd NaN male [1313 rows x 3 columns]['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male'] 預(yù)測(cè)的準(zhǔn)確率: 0.8115501519756839運(yùn)行代碼后在本地生成的tree.dot文件:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
用word打開(kāi)查看數(shù)據(jù):
? ? ? ? ? ? ? ? ? ? ? ? ? ?
并不是很直觀,
方法一:我們借助graphviz將其轉(zhuǎn)換為pdf或者png格式
?決策樹(shù)的結(jié)構(gòu)、本地保存
1、sklearn.tree.export_graphviz()?該函數(shù)能夠?qū)С鯠OT格式 tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])2、工具:(能夠?qū)ot文件轉(zhuǎn)換為pdf、png) 安裝graphviz ubuntu:sudo apt-get install graphviz??????????????????? Mac:brew install graphviz3、運(yùn)行命令 然后我們運(yùn)行這個(gè)命令 $ dot -Tpng tree.dot -o tree.png方法二:(我們這里采用的方法二)
import os os.environ['PATH'] = os.environ['PATH'] + (r';C:\Program Files (x86)\Graphviz2.38\bin') (graph,) = pydot.graph_from_dot_file('tree.dot',encoding="utf-8")# Write graph to a png file graph.write_png('tree.png')下載?graphviz-2.38.msi?直接安裝即可
解決 FileNotFoundError: [WinError 2] "dot" not found in path. 參考FileNotFoundError: [WinError 2] "dot" not found in path.
?
8.決策樹(shù)的優(yōu)缺點(diǎn)以及改進(jìn)
? ? 優(yōu)點(diǎn):
? ? ? ? .簡(jiǎn)單的理解和解釋,數(shù)木可視化
? ? ? ? .需要很少的數(shù)據(jù)準(zhǔn)備,其他技術(shù)通常需要數(shù)據(jù)歸一化
? ? 缺點(diǎn):
? ? ? ? .決策樹(shù)學(xué)習(xí)者可以創(chuàng)建不能很好地推廣數(shù)據(jù)的過(guò)于復(fù)雜的樹(shù),這唄稱為過(guò)擬合
? ? 改進(jìn):
? ? ? ? .減枝cart算法(決策樹(shù)API當(dāng)中已經(jīng)實(shí)現(xiàn),隨機(jī)森林參數(shù)調(diào)優(yōu))
? ? ? ? .隨機(jī)森林
? 企業(yè)重要決策,由于決策樹(shù)很好的分析能力,在決策過(guò)程應(yīng)用較多
9.隨機(jī)森林
集成學(xué)習(xí)方法-隨機(jī)森林
集成學(xué)習(xí)方法
集成學(xué)習(xí)通過(guò)建立幾個(gè)模型組合的來(lái)解決單一預(yù)測(cè)問(wèn)題。它的工作原理是生成多個(gè)分類器/模型,各自獨(dú)立地學(xué)習(xí)和作出預(yù)測(cè)。這些預(yù)測(cè)最后結(jié)合成單預(yù)測(cè),因此優(yōu)于任何一個(gè)單分類的做出預(yù)測(cè)。
什么是隨機(jī)森林
定義:在機(jī)器學(xué)習(xí)中,隨機(jī)森林是一個(gè)包含多個(gè)決策樹(shù)的分類器,并且其輸出的類別是由個(gè)別樹(shù)輸出的類別的眾數(shù)而定。
例如, 如果你訓(xùn)練了5個(gè)樹(shù), 其中有4個(gè)樹(shù)的結(jié)果是True, 1個(gè)數(shù)的結(jié)果是False, 那么最終結(jié)果會(huì)是True.
學(xué)習(xí)算法
根據(jù)下列算法而建造每棵樹(shù):
? ? ?用N來(lái)表示訓(xùn)練用例(樣本)的個(gè)數(shù),M表示特征數(shù)目。
? ? ?輸入特征數(shù)目m,用于確定決策樹(shù)上一個(gè)節(jié)點(diǎn)的決策結(jié)果;其中m應(yīng)遠(yuǎn)小于M。
? ? ?從N個(gè)訓(xùn)練用例(樣本)中以有放回抽樣的方式,取樣N次,形成一個(gè)訓(xùn)練集(即bootstrap取樣),并用未抽到的用例(樣本)作預(yù)測(cè),評(píng)估其誤差。
?為什么要隨機(jī)抽樣訓(xùn)練集?
? ? ? ?如果不進(jìn)行隨機(jī)抽樣,每棵樹(shù)的訓(xùn)練集都一樣,那么最終訓(xùn)練出的樹(shù)分類結(jié)果也是完全一樣的
?為什么要有放回地抽樣?
如果不是有放回的抽樣,那么每棵樹(shù)的訓(xùn)練樣本都是不同的,都是沒(méi)有交集的,這樣每棵樹(shù)都是“有偏的”,都是絕對(duì)“片面的”(當(dāng)然這樣說(shuō)可能不對(duì)),也就是說(shuō)每棵樹(shù)訓(xùn)練出來(lái)都是有很大的差異的;而隨機(jī)森林最后分類取決于多棵樹(shù)(弱分類器)的投票表決。
隨機(jī)森林API
class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None):隨機(jī)森林分類器參數(shù): n_estimators:integer,optional(default = 10) 多少棵決策樹(shù) criteria:string,可選(default =“gini”)分割特征的測(cè)量方法 max_depth:integer或None,可選(默認(rèn)=無(wú))樹(shù)的最大深度 max_features="auto":每個(gè)決策樹(shù)的最大特征數(shù)量auto:max_feature=sqrt(n_features)sqrt:same as "auto"log2:max_feature=log2(n_features)None:max_feature=n_features bootstrap:boolean,optional(default = True)是否在構(gòu)建樹(shù)時(shí)使用放回抽樣Python 代碼實(shí)現(xiàn)優(yōu)化泰坦尼克號(hào)乘客生存分類
# -*- coding: utf-8 -*- ''' @Author :Jason 隨機(jī)森林算法優(yōu)化之前的泰坦尼克號(hào)生存分類 '''import pandas as pd from sklearn.ensemble import RandomForestClassifier from sklearn.feature_extraction import DictVectorizer from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.tree import DecisionTreeClassifier, export_graphvizdef decision():"""決策樹(shù)對(duì)泰坦尼克號(hào)進(jìn)行預(yù)測(cè)生死:return: None"""# 獲取數(shù)據(jù)titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")# 處理數(shù)據(jù),找出特征值和目標(biāo)值x = titan[['pclass', 'age', 'sex']]y = titan['survived']print(x)# 缺失值處理x['age'].fillna(x['age'].mean(), inplace=True)# 分割數(shù)據(jù)集到訓(xùn)練集合測(cè)試集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)# 進(jìn)行處理(特征工程)特征-》類別-》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)# 用決策樹(shù)進(jìn)行預(yù)測(cè)# dec = DecisionTreeClassifier()## dec.fit(x_train, y_train)## # 預(yù)測(cè)準(zhǔn)確率# print("預(yù)測(cè)的準(zhǔn)確率:", dec.score(x_test, y_test))## # 導(dǎo)出決策樹(shù)的結(jié)構(gòu)# export_graphviz(dec, out_file="./tree.dot", feature_names=['年齡', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])# 隨機(jī)森林進(jìn)行預(yù)測(cè) (超參數(shù)調(diào)優(yōu))rf = RandomForestClassifier(n_jobs=-1)param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}# 網(wǎng)格搜索與交叉驗(yàn)證gc = GridSearchCV(rf, param_grid=param, cv=2)gc.fit(x_train, y_train)print("準(zhǔn)確率:", gc.score(x_test, y_test))print("查看選擇的參數(shù)模型:", gc.best_params_)return Noneif __name__ == "__main__":decision()預(yù)測(cè)結(jié)果:
['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male'] 準(zhǔn)確率: 0.8267477203647416 查看選擇的參數(shù)模型: {'max_depth': 5, 'n_estimators': 500}最優(yōu)模型:深度5,決策樹(shù)數(shù)量:500
10. 隨機(jī)森林的優(yōu)點(diǎn):幾乎沒(méi)有缺點(diǎn),唯一缺點(diǎn)選不到合適參數(shù)
? ? ?在當(dāng)前所有算法中,具有極好的準(zhǔn)確率
? ? ?能夠有效地運(yùn)行在大數(shù)據(jù)集上(大:體現(xiàn)在一個(gè)是數(shù)據(jù)數(shù),一個(gè)是特征數(shù))
? ? ?能夠處理具有高維特征的輸入樣本,而且不需要降維
? ? ?能夠評(píng)估各個(gè)特征在分類問(wèn)題上的重要性
? ? ?對(duì)于缺省值問(wèn)題也能夠獲得很好得結(jié)果
參考:
https://baike.baidu.com/item/%E5%86%B3%E7%AD%96%E6%A0%91/10377049?fr=aladdin
https://baike.baidu.com/item/%E4%BF%A1%E6%81%AF%E7%86%B5/7302318?fr=aladdin
某機(jī)構(gòu)視頻
總結(jié)
- 上一篇: Python数据分析与挖掘实战总结
- 下一篇: 数据结构期末复习