决策树与随机森林
1.決策樹基本概念:
? ? ? ? 決策樹(Decision Tree)是在已知各種情況發(fā)生概率的基礎(chǔ)上,通過構(gòu)成決策樹來求取凈現(xiàn)值的期望值大于等于零的概率,評價項(xiàng)目風(fēng)險,判斷其可行性的決策分析方法,是直觀運(yùn)用概率分析的一種圖解法。由于這種決策分支畫成圖形很像一棵樹的枝干,故稱決策樹。在機(jī)器學(xué)習(xí)中,決策樹是一個預(yù)測模型,他代表的是對象屬性與對象值之間的一種映射關(guān)系。
例子:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
這其中右邊彩色樹狀就是決策樹,從圖中我們還可以看出決策樹是if-else的邏輯?
2.信息論基礎(chǔ):熵,信息熵
什么是熵:熵的概念源于物理學(xué),用于度量一個熱力學(xué)系統(tǒng)的無序程度。
信息熵:1948年,香農(nóng)提出了“信息熵”的概念!在信息論里面,信息熵衡量信息量的大小,也就是對隨機(jī)變量不確定度的一個衡量。熵越大,不確定性越大;
? 案例:? ? 32支球隊(duì),在完全未知的情況下,求壓中冠軍的信息熵:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
其中 n=32,概率p? =???,最后為比特
3.決策樹的劃分依據(jù)之一:信息增益(ID3)
? ? 即:當(dāng)?shù)弥粋€特征條件之后,減少的信息熵的大小
? ?特征A對訓(xùn)練集D的信息增益g(D,A),定義為集合D的信息熵H(D)與特征A給定條件D的信息條件熵H(D|A)之差,即公式為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ?其中H(D)為初始信息熵大小。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
案例:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
求當(dāng)前所給信息的信息熵(以下都是針對類別):
?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.決策樹的劃分依據(jù)之一:C4.5
? ? 信息增益比 最大的準(zhǔn)則
5.決策樹的劃分依據(jù)之一:CART
?回歸樹:平方誤差最小
分類樹:基尼系數(shù) 最小的準(zhǔn)則,在sklearn中可以選擇劃分的默認(rèn)原則
6.API
class sklearn.tree.DecisionTreeClassifier(criterion="gini",max_depth=None,random_state=None)
? ? .決策樹分類器
? ? .criterion:默認(rèn)是gini系數(shù),也可以是信息增益的熵"entropy"
? ? .max_depth:樹的深度大小
? ? .random_state:隨機(jī)種子數(shù)
? ? .method
? ? .decision_path:返回決策樹的路徑
7.案例: 泰坦尼克號乘客生存分類
數(shù)據(jù)集地址:??http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt
泰坦尼克號數(shù)據(jù)
在泰坦尼克號和titanic2數(shù)據(jù)幀描述泰坦尼克號上的個別乘客的生存狀態(tài)。在泰坦尼克號的數(shù)據(jù)幀不包含從劇組信息,但它確實(shí)包含了乘客的一半的實(shí)際年齡。關(guān)于泰坦尼克號旅客的數(shù)據(jù)的主要來源是百科全書Titanica。這里使用的數(shù)據(jù)集是由各種研究人員開始的。其中包括許多研究人員創(chuàng)建的旅客名單,由Michael A. Findlay編輯。
我們提取的數(shù)據(jù)集中的特征是票的類別,存活,乘坐班,年齡,登陸,home.dest,房間,票,船和性別。乘坐班是指乘客班(1,2,3),是社會經(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、決策樹估計(jì)器流程 ''' import pandas as pd from sklearn.feature_extraction import DictVectorizer from sklearn.tree import DecisionTreeClassifier, export_graphvizdef decision():"""決策樹對泰坦尼克號進(jìn)行預(yù)測生死: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)練集合測試集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)# 用決策樹進(jìn)行預(yù)測max_depth = n 會影響決策樹的結(jié)果dec = DecisionTreeClassifier()dec.fit(x_train, y_train)# 預(yù)測準(zhǔn)確率print("預(yù)測的準(zhǔn)確率:", dec.score(x_test, y_test))# 導(dǎo)出決策樹的結(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ù)測的準(zhǔn)確率: 0.8115501519756839運(yùn)行代碼后在本地生成的tree.dot文件:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
用word打開查看數(shù)據(jù):
? ? ? ? ? ? ? ? ? ? ? ? ? ?
并不是很直觀,
方法一:我們借助graphviz將其轉(zhuǎn)換為pdf或者png格式
?決策樹的結(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)行這個命令 $ 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.決策樹的優(yōu)缺點(diǎn)以及改進(jìn)
? ? 優(yōu)點(diǎn):
? ? ? ? .簡單的理解和解釋,數(shù)木可視化
? ? ? ? .需要很少的數(shù)據(jù)準(zhǔn)備,其他技術(shù)通常需要數(shù)據(jù)歸一化
? ? 缺點(diǎn):
? ? ? ? .決策樹學(xué)習(xí)者可以創(chuàng)建不能很好地推廣數(shù)據(jù)的過于復(fù)雜的樹,這唄稱為過擬合
? ? 改進(jìn):
? ? ? ? .減枝cart算法(決策樹API當(dāng)中已經(jīng)實(shí)現(xiàn),隨機(jī)森林參數(shù)調(diào)優(yōu))
? ? ? ? .隨機(jī)森林
? 企業(yè)重要決策,由于決策樹很好的分析能力,在決策過程應(yīng)用較多
9.隨機(jī)森林
集成學(xué)習(xí)方法-隨機(jī)森林
集成學(xué)習(xí)方法
集成學(xué)習(xí)通過建立幾個模型組合的來解決單一預(yù)測問題。它的工作原理是生成多個分類器/模型,各自獨(dú)立地學(xué)習(xí)和作出預(yù)測。這些預(yù)測最后結(jié)合成單預(yù)測,因此優(yōu)于任何一個單分類的做出預(yù)測。
什么是隨機(jī)森林
定義:在機(jī)器學(xué)習(xí)中,隨機(jī)森林是一個包含多個決策樹的分類器,并且其輸出的類別是由個別樹輸出的類別的眾數(shù)而定。
例如, 如果你訓(xùn)練了5個樹, 其中有4個樹的結(jié)果是True, 1個數(shù)的結(jié)果是False, 那么最終結(jié)果會是True.
學(xué)習(xí)算法
根據(jù)下列算法而建造每棵樹:
? ? ?用N來表示訓(xùn)練用例(樣本)的個數(shù),M表示特征數(shù)目。
? ? ?輸入特征數(shù)目m,用于確定決策樹上一個節(jié)點(diǎn)的決策結(jié)果;其中m應(yīng)遠(yuǎn)小于M。
? ? ?從N個訓(xùn)練用例(樣本)中以有放回抽樣的方式,取樣N次,形成一個訓(xùn)練集(即bootstrap取樣),并用未抽到的用例(樣本)作預(yù)測,評估其誤差。
?為什么要隨機(jī)抽樣訓(xùn)練集?
? ? ? ?如果不進(jìn)行隨機(jī)抽樣,每棵樹的訓(xùn)練集都一樣,那么最終訓(xùn)練出的樹分類結(jié)果也是完全一樣的
?為什么要有放回地抽樣?
如果不是有放回的抽樣,那么每棵樹的訓(xùn)練樣本都是不同的,都是沒有交集的,這樣每棵樹都是“有偏的”,都是絕對“片面的”(當(dāng)然這樣說可能不對),也就是說每棵樹訓(xùn)練出來都是有很大的差異的;而隨機(jī)森林最后分類取決于多棵樹(弱分類器)的投票表決。
隨機(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) 多少棵決策樹 criteria:string,可選(default =“gini”)分割特征的測量方法 max_depth:integer或None,可選(默認(rèn)=無)樹的最大深度 max_features="auto":每個決策樹的最大特征數(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)建樹時使用放回抽樣Python 代碼實(shí)現(xiàn)優(yōu)化泰坦尼克號乘客生存分類
# -*- coding: utf-8 -*- ''' @Author :Jason 隨機(jī)森林算法優(yōu)化之前的泰坦尼克號生存分類 '''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():"""決策樹對泰坦尼克號進(jìn)行預(yù)測生死: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)練集合測試集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)# 用決策樹進(jìn)行預(yù)測# dec = DecisionTreeClassifier()## dec.fit(x_train, y_train)## # 預(yù)測準(zhǔn)確率# print("預(yù)測的準(zhǔn)確率:", dec.score(x_test, y_test))## # 導(dǎo)出決策樹的結(jié)構(gòu)# export_graphviz(dec, out_file="./tree.dot", feature_names=['年齡', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])# 隨機(jī)森林進(jìn)行預(yù)測 (超參數(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ù)測結(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ù)量:500
10. 隨機(jī)森林的優(yōu)點(diǎn):幾乎沒有缺點(diǎn),唯一缺點(diǎn)選不到合適參數(shù)
? ? ?在當(dāng)前所有算法中,具有極好的準(zhǔn)確率
? ? ?能夠有效地運(yùn)行在大數(shù)據(jù)集上(大:體現(xiàn)在一個是數(shù)據(jù)數(shù),一個是特征數(shù))
? ? ?能夠處理具有高維特征的輸入樣本,而且不需要降維
? ? ?能夠評估各個特征在分類問題上的重要性
? ? ?對于缺省值問題也能夠獲得很好得結(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数据分析与挖掘实战总结
- 下一篇: qq表情左右滑动php,基于jQuery