01 決策樹節(jié)點字段的選擇
模型介紹
決策樹屬于經(jīng)典的十大數(shù)據(jù)挖掘算法之一,是一種類似于流程圖的樹結(jié)構(gòu),其規(guī)則就是IF...THEN...的思想,可以用于數(shù)值型因變量的預(yù)測和離散型因變量的分類。
該算法簡單直觀、通俗易懂,不需要研究者掌握任何領(lǐng)域知識或復(fù)雜的數(shù)學(xué)推理,而且算法的結(jié)果輸出具有很強的解釋性。

圖中的決策樹呈現(xiàn)自頂向下的生長過程,深色的橢圓表示樹的根節(jié)點;淺色的橢圓表示樹的中間節(jié)點;方框則表示樹的葉節(jié)點。
對于所有的非葉節(jié)點來說,都是用來表示條件判斷,而葉節(jié)點則存儲最終的分類結(jié)果,例如中年分支下的葉節(jié)點(4,0)表示4位客戶購買,0位客戶不購買。
信息增益
熵原本是物理學(xué)中的一個定義,后來香農(nóng)將其引申到了信息論領(lǐng)域,用來表示信息量的大小。信息量越大(分類越不“純凈”),對應(yīng)的熵值就越大,反之亦然。信息熵的計算公式如下:

在實際應(yīng)用中,會將概率p_k的值用經(jīng)驗概率替換,所以經(jīng)驗信息熵可以表示為:

舉例:以產(chǎn)品是否被購買為例,假設(shè)數(shù)據(jù)集一共包含14個樣本,其中購買的用戶有9個,沒有購買的用戶有5個,所以對于是否購買這個事件來說,它的經(jīng)驗信息熵為:

條件熵

其中,
P(A_i)表示 A事件的第i種值對應(yīng)的概率;H(D_k|A_i)為已知A_i的情況下,D事件為k值的條件熵,其對應(yīng)的計算公式為P(D_k|A_i)log_2P(D_k|A_i);|D_i|表示A_i的頻數(shù),|D_i|/|D|表示A_i在所有樣本中的頻率;|D_ik|表示A_i下D事件為k值的頻數(shù),|D_ik|/|D_i|表示所有A_i中,D事件為k值的頻率。Gain_A(D)=H(D)?H(D|A):對于已知的事件A來說,事件D的信息增益就是D的信息熵與A事件下D的條件熵之差,事件A對事件D的影響越大,條件熵H(D|A)就會越?。ㄔ谑录嗀的影響下,事件D被劃分得越“純凈”),體現(xiàn)在信息增益上就是差值越大,進而說明事件D的信息熵下降得越多。
所以,在根節(jié)點或中間節(jié)點的變量選擇過程中,就是挑選出各自變量下因變量的信息增益最大的。

決策樹中的ID3算法使用信息增益指標(biāo)實現(xiàn)根節(jié)點或中間節(jié)點的字段選擇,但是該指標(biāo)存在一個非常明顯的缺點,即信息增益會偏向于取值較多的字段。
為了克服信息增益指標(biāo)的缺點,提出了信息增益率的概念,它的思想很簡單,就是在信息增益的基礎(chǔ)上進行相應(yīng)的懲罰。信息增益率的公式可以表示為:

其中,
H_A為事件A的信息熵。事件A的取值越多, Gain_A(D)可能越大,但同時H_A也會越大,這樣以商的形式就實現(xiàn)了Gain_A(D)的懲罰。

從上面的計算結(jié)果可知,Age變量的信息增益率仍然是最大的,所以在根節(jié)點處仍然選擇Age變量進行判斷和分支。
基尼指數(shù)
決策樹中的C4.5算法使用信息增益率指標(biāo)實現(xiàn)根節(jié)點或中間節(jié)點的字段選擇,但該算法與ID3算法一致,都只能針對離散型因變量進行分類,對于連續(xù)型的因變量就顯得束手無策了。
為了能夠讓決策樹預(yù)測連續(xù)型的因變量,Breiman等人在1984年提出了CART算法,該算法也稱為分類回歸樹,它所使用的字段選擇指標(biāo)是基尼指數(shù)。


假設(shè)表中的Edu表示客戶的受教育水平,Credit為客戶在第三方的信用記錄,Loan為因變量,表示銀行是否對其發(fā)放貸款。根據(jù)基尼指數(shù)的公式,可以計算Loan變量的基尼指數(shù)值:

條件基尼指數(shù)

其中,
P(A_i)表示 A變量在某個二元劃分下第i組的概率,其對應(yīng)的經(jīng)驗概率為|D_i|/|D|,即A變量中第i組的樣本量與總樣本量的商;Gini(D_k|A_i)表示在已知分組A_i的情況下,變量D取第k種值的條件基尼指數(shù),其中|D_ik|/|D_i|表示分組A_i內(nèi)變量D取第k種值的頻率。
基尼指數(shù)增益
與信息增益類似,還需要考慮自變量對因變量的影響程度,即因變量的基尼指數(shù)下降速度的快慢,下降得越快,自變量對因變量的影響就越強。下降速度的快慢可用下方式子衡量:

決策樹模型的Python函數(shù)
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,
min_impurity_decrease=0.0, min_impurity_split=None,
class_weight=None, presort=False)
criterion:用于指定選擇節(jié)點字段的評價指標(biāo),對于分類決策樹,默認(rèn)為'gini',表示采用基尼指數(shù)選擇節(jié)點的最佳分割字段;對于回歸決策樹,默認(rèn)為'mse',表示使用均方誤差選擇節(jié)點的最佳分割字段
splitter:用于指定節(jié)點中的分割點選擇方法,默認(rèn)為'best',表示從所有的分割點中選擇最佳分割點;如果指定為'random',則表示隨機選擇分割點
max_depth:用于指定決策樹的最大深度,默認(rèn)為None,表示樹的生長過程中對深度不做任何限制
min_samples_split:用于指定根節(jié)點或中間節(jié)點能夠繼續(xù)分割的最小樣本量, 默認(rèn)為2
min_samples_leaf:用于指定葉節(jié)點的最小樣本量,默認(rèn)為1
min_weight_fraction_leaf:用于指定葉節(jié)點最小的樣本權(quán)重,默認(rèn)為None,表示不考慮葉節(jié)點的樣本權(quán)值
max_features:用于指定決策樹包含的最多分割字段數(shù),默認(rèn)為None,表示分割時使用所有的字段,與指定'auto'效果一致;如果為具體的整數(shù),則考慮使用對應(yīng)的分割字段數(shù);如果為0~1的浮點數(shù),則考慮對應(yīng)百分比的字段個數(shù);如果為'sqrt',則表示最多考慮√P個字段;如果為'log2',則表示最多使用log_2P個字段
random_state:用于指定隨機數(shù)生成器的種子,默認(rèn)為None,表示使用默認(rèn)的隨機數(shù)生成器
max_leaf_nodes:用于指定最大的葉節(jié)點個數(shù),默認(rèn)為None,表示對葉節(jié)點個數(shù)不做任何限制
min_impurity_decrease:用于指定節(jié)點是否繼續(xù)分割的最小不純度值,默認(rèn)為0
min_impurity_split:同參數(shù)min_impurity_decrease含義一致,該參數(shù)已在0.21版本剔除
class_weight:用于指定因變量中類別之間的權(quán)重,默認(rèn)為None,表示每個類別的權(quán)重都相等;如果為balanced,則表示類別權(quán)重與原始樣本中類別的比例成反比;還可以通過字典傳遞類別之間的權(quán)重差異,其形式為{class_label:weight}
presort:bool類型參數(shù),是否對數(shù)據(jù)進行預(yù)排序,默認(rèn)為False。如果數(shù)據(jù)集的樣本量比較小,設(shè)置為True可以提高模型的執(zhí)行速度;如果數(shù)據(jù)集的樣本量比較大,則不易設(shè)置為True
02 決策樹的剪枝技術(shù)
誤差降低剪枝法

- 將決策樹的某個非葉子節(jié)點作為剪枝的候選對象(如圖中的x_3處節(jié)點),如果將其子孫節(jié)點刪除(對應(yīng)的兩個葉節(jié)點),則x_3處的節(jié)點就變成了葉節(jié)點。
- 利用投票原則,將此處葉節(jié)點中頻數(shù)最高的類別用作分類標(biāo)準(zhǔn)(如圖中剪枝后該葉節(jié)點屬于類A)。
- 利用剪枝后的新樹在測試數(shù)據(jù)集上進行預(yù)測,然后對比新樹與老樹在測試集上的誤判樣本量,如果新樹的誤判樣本量低于老樹的誤判樣本量,則將x_3處的中間節(jié)點替換為葉節(jié)點,否則不進行剪枝。
- 重復(fù)前面的三步,直到新的決策樹能夠最大限度地提高測試數(shù)據(jù)集上的預(yù)測準(zhǔn)確率。
悲觀剪枝法

其中,
e^′(T)表示剪枝后中間節(jié)點T被換成葉節(jié)點的誤判率;e^′(T_t)表示中間節(jié)點T剪枝前其對應(yīng)的所有葉節(jié)點的誤判率;E(T)為中間節(jié)點T處的誤判個數(shù);E(t_i)為節(jié)點T下的所有葉節(jié)點誤判個數(shù);L表示中間節(jié)點T對應(yīng)的所有葉節(jié)點個數(shù);N表示中間節(jié)點T的樣本個數(shù);N_i表示各葉節(jié)點中的樣本個數(shù),其實∑_i^L N_{i=1}=N。
剪枝標(biāo)準(zhǔn):
對比剪枝前后葉節(jié)點誤判率的標(biāo)準(zhǔn)就是,如果剪枝后葉節(jié)點的誤判率期望在剪枝前葉節(jié)點誤判率期望的一個標(biāo)準(zhǔn)差內(nèi),則認(rèn)為剪枝是合理的,否則不能剪枝。
在決策樹圖中,假設(shè)以T_2節(jié)點為例,剪枝前對應(yīng)了3個葉節(jié)點,誤判個數(shù)分別為3,2,0;如果將其所有葉節(jié)點都剪掉,T_2便成為了T_1的葉節(jié)點,誤判樣本數(shù)為7。根據(jù)計算公式,可以得到:

代價復(fù)雜度剪枝法
從字面理解,該剪枝方法涉及兩則信息,一則是代價,是指將中間節(jié)點替換為葉節(jié)點后誤判率會上升;另一則是復(fù)雜度,是指剪枝后葉節(jié)點的個數(shù)減少,進而使模型的復(fù)雜度下降。為了平衡上升的誤判率與下降的復(fù)雜度,需要加入一個系數(shù)a,故可以將代價復(fù)雜度剪枝法的目標(biāo)函數(shù)寫成:

其中,
C(T)=∑_{i=1}^L N_i×H(i);i表示節(jié)點T下第i個葉節(jié)點;N_i為第i個葉節(jié)點的樣本量;H(i)為第i個葉節(jié)點的信息熵;|N_leaf|為節(jié)點T對應(yīng)的所有葉節(jié)點個數(shù);a就是調(diào)節(jié)參數(shù)。問題是參數(shù)a該如何計算呢?節(jié)點T剪枝前的目標(biāo)函數(shù)值為:

節(jié)點T剪枝后的目標(biāo)函數(shù)值為:

令
C_α(T)_before=C_α(T)_after,得到:

剪枝過程
(1)對于一棵充分生長的樹,不妨含有4個非葉子節(jié)點和5個葉子節(jié)點,根據(jù)計算a值的公式,可以得到所有非葉子節(jié)點對應(yīng)的a值。
(2)挑選出最小的a值,不妨為α_3,然后對T_3進行剪枝,使其成為葉子節(jié)點,便得到一棵新樹。
(3)接下來重新計算剩余非葉子節(jié)點所對應(yīng)的a值。
(4)不斷重復(fù)(2)和(3),直到?jīng)Q策樹被剪枝成根節(jié)點,最終得到N棵新樹。
(5)將測試數(shù)據(jù)集運用到N棵新樹中,再從中挑選出誤判率最低的樹作為最佳的決策樹。
03 隨機森林的思想解讀
思想解讀

- 利用Bootstrap抽樣法,從原始數(shù)據(jù)集中生成k個數(shù)據(jù)集,并且每個數(shù)據(jù)集都含有N個觀測和P個自變量。
- 針對每一個數(shù)據(jù)集,構(gòu)造一棵CART決策樹,在構(gòu)建子樹的過程中,并沒有將所有自變量用作節(jié)點字段的選擇,而是隨機選擇p個字段。
- 讓每一棵決策樹盡可能地充分生長,使得樹中的每個節(jié)點盡可能“純凈”,即隨機森林中的每一棵子樹都不需要剪枝。
- 針對k棵CART樹的隨機森林,對分類問題利用投票法,將最高得票的類別用于最終的判斷結(jié)果;對回歸問題利用均值法,將其用作預(yù)測樣本的最終結(jié)果。
隨機森林的Python函數(shù)
RandomForestClassifier(n_estimators=10, criterion='gini', max_depth=None,
min_samples_split=2, min_samples_leaf=1,
min_weight_fraction_leaf=0.0, max_features='auto',
max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, bootstrap=True,
oob_score=False, n_jobs=1, random_state=None,
verbose=0, warm_start=False, class_weight=None)
n_estimators:用于指定隨機森林所包含的決策樹個數(shù)
criterion:用于指定每棵決策樹節(jié)點的分割字段所使用的度量標(biāo)準(zhǔn),用于分類的隨機森林,默認(rèn)的criterion值為'gini';用于回歸的隨機森林,默認(rèn)的criterion值為'mse'
max_depth:用于指定每棵決策樹的最大深度,默認(rèn)不限制樹的生長深度
min_samples_split:用于指定每棵決策樹根節(jié)點或中間節(jié)點能夠繼續(xù)分割的最小樣本量, 默認(rèn)為2
min_samples_leaf:用于指定每棵決策樹葉節(jié)點的最小樣本量,默認(rèn)為1
min_weight_fraction_leaf:用于指定每棵決策樹葉節(jié)點最小的樣本權(quán)重,默認(rèn)為None,表示不考慮葉節(jié)點的樣本權(quán)值
max_features:用于指定每棵決策樹包含的最多分割字段數(shù),默認(rèn)為None,表示分割時使用所有的字段
max_leaf_nodes:用于指定每棵決策樹最大的葉節(jié)點個數(shù),默認(rèn)為None,表示對葉節(jié)點個數(shù)不做任何限制
min_impurity_decrease:用于指定每棵決策樹的節(jié)點是否繼續(xù)分割的最小不純度值,默認(rèn)為0
bootstrap:bool類型參數(shù),是否對原始數(shù)據(jù)集進行bootstrap抽樣,用于子樹的構(gòu)建,默認(rèn)為True
oob_score:bool類型參數(shù),是否使用包外樣本計算泛化誤差,默認(rèn)為False,包外樣本是指每次bootstrap抽樣時沒有被抽中的樣本
n_jobs:用于指定計算隨機森林算法的CPU個數(shù),默認(rèn)為1
random_state:用于指定隨機數(shù)生成器的種子,默認(rèn)為None,表示使用默認(rèn)的隨機數(shù)生成器
verbose:用于指定隨機森林計算過程中是否輸出日志信息,默認(rèn)為0,表示不輸出
warm_start:bool類型參數(shù),是否基于上一次的訓(xùn)練結(jié)果進行本次的運算,默認(rèn)為False
class_weight:用于指定因變量中類別之間的權(quán)重,默認(rèn)為None,表示每個類別的權(quán)重都相等
04 決策樹與隨機森林的應(yīng)用實戰(zhàn)
Titanic幸存分類--決策樹
# 導(dǎo)入第三方模塊
import pandas as pd
# 讀入數(shù)據(jù)
Titanic = pd.read_csv('./Titanic.csv')
Titanic.head()
# 刪除無意義的變量,并檢查剩余自字是否含有缺失值
Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace = True)
Titanic.isnull().sum(axis = 0)
# 對Sex分組,用各組乘客的平均年齡填充各組中的缺失年齡
fillna_Titanic = []
for i in Titanic.Sex.unique():
update = Titanic.loc[Titanic.Sex == i,].fillna(value = {'Age': Titanic.Age[Titanic.Sex == i].mean()}, inplace = False)
fillna_Titanic.append(update)
Titanic = pd.concat(fillna_Titanic)
# 使用Embarked變量的眾數(shù)填充缺失值
Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=True)
Titanic.head()
# 將數(shù)值型的Pclass轉(zhuǎn)換為類別型,否則無法對其啞變量處理
Titanic.Pclass = Titanic.Pclass.astype('category')
# 啞變量處理
dummy = pd.get_dummies(Titanic[['Sex','Embarked','Pclass']])
# 水平合并Titanic數(shù)據(jù)集和啞變量的數(shù)據(jù)集
Titanic = pd.concat([Titanic,dummy], axis = 1)
# 刪除原始的Sex、Embarked和Pclass變量
Titanic.drop(['Sex','Embarked','Pclass'], inplace=True, axis = 1)
Titanic.head()
讀入數(shù)據(jù)清洗結(jié)果:
In [2]: # 導(dǎo)入第三方模塊
...: import pandas as pd
...: # 讀入數(shù)據(jù)
...: Titanic = pd.read_csv('./Titanic.csv')
...: Titanic.head()
Out[2]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
[5 rows x 12 columns]
In [3]: # 刪除無意義的變量,并檢查剩余自字是否含有缺失值
...: Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace
...: = True)
...: Titanic.isnull().sum(axis = 0)
...:
Out[3]:
Survived 0
Pclass 0
Sex 0
Age 177
SibSp 0
Parch 0
Fare 0
Embarked 2
dtype: int64
In [4]: # 對Sex分組,用各組乘客的平均年齡填充各組中的缺失年齡
...: fillna_Titanic = []
...: for i in Titanic.Sex.unique():
...: update = Titanic.loc[Titanic.Sex == i,].fillna(value = {'Age': Titan
...: ic.Age[Titanic.Sex == i].mean()}, inplace = False)
...: fillna_Titanic.append(update)
...: Titanic = pd.concat(fillna_Titanic)
...: # 使用Embarked變量的眾數(shù)填充缺失值
...: Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=
...: True)
...: Titanic.head()
Out[4]:
Survived Pclass Sex Age SibSp Parch Fare Embarked
0 0 3 male 22.000000 1 0 7.2500 S
4 0 3 male 35.000000 0 0 8.0500 S
5 0 3 male 30.726645 0 0 8.4583 Q
6 0 1 male 54.000000 0 0 51.8625 S
7 0 3 male 2.000000 3 1 21.0750 S
In [5]: # 將數(shù)值型的Pclass轉(zhuǎn)換為類別型,否則無法對其啞變量處理
...: Titanic.Pclass = Titanic.Pclass.astype('category')
...: # 啞變量處理
...: dummy = pd.get_dummies(Titanic[['Sex','Embarked','Pclass']])
...: # 水平合并Titanic數(shù)據(jù)集和啞變量的數(shù)據(jù)集
...: Titanic = pd.concat([Titanic,dummy], axis = 1)
...: # 刪除原始的Sex、Embarked和Pclass變量
...: Titanic.drop(['Sex','Embarked','Pclass'], inplace=True, axis = 1)
...: Titanic.head()
Out[5]:
Survived Age SibSp Parch ... Embarked_S Pclass_1 Pclass_2 Pclass_3
0 0 22.000000 1 0 ... 1 0 0 1
4 0 35.000000 0 0 ... 1 0 0 1
5 0 30.726645 0 0 ... 0 0 0 1
6 0 54.000000 0 0 ... 1 1 0 0
7 0 2.000000 3 1 ... 1 0 0 1
[5 rows x 13 columns]
# 導(dǎo)入第三方包
from sklearn import model_selection
# 取出所有自變量名稱
predictors = Titanic.columns[1:]
# 將數(shù)據(jù)集拆分為訓(xùn)練集和測試集,且測試集的比例為25%
X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived,
test_size = 0.25, random_state = 1234)
# 導(dǎo)入第三方模塊
from sklearn.model_selection import GridSearchCV
from sklearn import tree
# 預(yù)設(shè)各參數(shù)的不同選項值
max_depth = [2,3,4,5,6]
min_samples_split = [2,4,6,8]
min_samples_leaf = [2,4,8,10,12]
# 將各參數(shù)值以字典形式組織起來
parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf}
# 網(wǎng)格搜索法,測試不同的參數(shù)值
grid_dtcateg = GridSearchCV(estimator = tree.DecisionTreeClassifier(), param_grid = parameters, cv=10)
# 模型擬合
grid_dtcateg.fit(X_train, y_train)
# 返回最佳組合的參數(shù)值
grid_dtcateg.best_params_
# 導(dǎo)入第三方模塊
from sklearn import metrics
# 構(gòu)建分類決策樹
CART_Class = tree.DecisionTreeClassifier(max_depth=3, min_samples_leaf = 4, min_samples_split=2)
# 模型擬合
decision_tree = CART_Class.fit(X_train, y_train)
# 模型在測試集上的預(yù)測
pred = CART_Class.predict(X_test)
# 模型的準(zhǔn)確率
print('模型在測試集的預(yù)測準(zhǔn)確率:\n',metrics.accuracy_score(y_test, pred))
在ipython中的結(jié)果:
In [6]: # 導(dǎo)入第三方包
...: from sklearn import model_selection
...: # 取出所有自變量名稱
...: predictors = Titanic.columns[1:]
...: # 將數(shù)據(jù)集拆分為訓(xùn)練集和測試集,且測試集的比例為25%
...: X_train, X_test, y_train, y_test = model_selection.train_test_split(Tita
...: nic[predictors], Titanic.Survived,
...: test_size = 0.25, random_state = 1234)
In [7]: # 導(dǎo)入第三方模塊
...: from sklearn.model_selection import GridSearchCV
...: from sklearn import tree
...: # 預(yù)設(shè)各參數(shù)的不同選項值
...: max_depth = [2,3,4,5,6]
...: min_samples_split = [2,4,6,8]
...: min_samples_leaf = [2,4,8,10,12]
...: # 將各參數(shù)值以字典形式組織起來
...: parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_spl
...: it, 'min_samples_leaf':min_samples_leaf}
...: # 網(wǎng)格搜索法,測試不同的參數(shù)值
...: grid_dtcateg = GridSearchCV(estimator = tree.DecisionTreeClassifier(), p
...: aram_grid = parameters, cv=10)
...: # 模型擬合
...: grid_dtcateg.fit(X_train, y_train)
...: # 返回最佳組合的參數(shù)值
...: grid_dtcateg.best_params_
Out[7]: {'max_depth': 6, 'min_samples_leaf': 8, 'min_samples_split': 4}
In [8]: # 導(dǎo)入第三方模塊
...: from sklearn import metrics
...: # 構(gòu)建分類決策樹
...: CART_Class = tree.DecisionTreeClassifier(max_depth=3, min_samples_leaf =
...: 4, min_samples_split=2)
...: # 模型擬合
...: decision_tree = CART_Class.fit(X_train, y_train)
...: # 模型在測試集上的預(yù)測
...: pred = CART_Class.predict(X_test)
...: # 模型的準(zhǔn)確率
...: print('模型在測試集的預(yù)測準(zhǔn)確率:\n',metrics.accuracy_score(y_test, pred
...: ))
模型在測試集的預(yù)測準(zhǔn)確率:
0.8295964125560538
繪圖:
# 導(dǎo)入第三方包
import matplotlib.pyplot as plt
y_score = CART_Class.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 計算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 繪制面積圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加邊際線
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加對角線
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x軸與y軸標(biāo)簽
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 顯示圖形
plt.show()

Titanic幸存分類--隨機森林
需要在電腦中安裝Graphviz,在下面的鏈接中下載適合自己電腦的版本
https://graphviz.gitlab.io/download/
mac下的Graphviz安裝及使用參考:https://blog.csdn.net/qq_36847641/article/details/78224910
windows下Graphviz安裝及入門教程:https://www.cnblogs.com/onemorepoint/p/8310996.html
Titanic幸存分類--決策樹
# 需要在電腦中安裝Graphviz,在下面的鏈接中下載適合自己電腦的版本
# https://graphviz.gitlab.io/download/
# 然后將解壓文件中的bin設(shè)置到環(huán)境變量中
# 導(dǎo)入第三方模塊
from sklearn.tree import export_graphviz
from IPython.display import Image
import pydotplus
from io import StringIO
# 繪制決策樹
dot_data = StringIO()
export_graphviz(
decision_tree,
out_file=dot_data,
feature_names=predictors,
class_names=['Unsurvived','Survived'],
# filled=True,
rounded=True,
special_characters=True
)
# 決策樹展現(xiàn)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
Image(graph.create_png())

# 導(dǎo)入第三方包
from sklearn import ensemble
# 構(gòu)建隨機森林
RF_class = ensemble.RandomForestClassifier(n_estimators=200, random_state=1234)
# 隨機森林的擬合
RF_class.fit(X_train, y_train)
# 模型在測試集上的預(yù)測
RFclass_pred = RF_class.predict(X_test)
# 模型的準(zhǔn)確率
print('模型在測試集的預(yù)測準(zhǔn)確率:\n',metrics.accuracy_score(y_test, RFclass_pred))
# 計算繪圖數(shù)據(jù)
y_score = RF_class.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 繪圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

構(gòu)建隨機森林
# 變量的重要性程度值
importance = RF_class.feature_importances_
# 構(gòu)建含序列用于繪圖
Impt_Series = pd.Series(importance, index = X_train.columns)
# 對序列排序繪圖
Impt_Series.sort_values(ascending = True).plot(kind='barh')
plt.show()

# 讀入數(shù)據(jù)
NHANES = pd.read_excel('./NHANES.xlsx')
NHANES.head()
print(NHANES.shape)
# 取出自變量名稱
predictors = NHANES.columns[:-1]
# 將數(shù)據(jù)集拆分為訓(xùn)練集和測試集
X_train, X_test, y_train, y_test = model_selection.train_test_split(NHANES[predictors], NHANES.CKD_epi_eGFR,
test_size = 0.25, random_state = 1234)
# 預(yù)設(shè)各參數(shù)的不同選項值
max_depth = [18,19,20,21,22]
min_samples_split = [2,4,6,8]
min_samples_leaf = [2,4,8]
parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf}
# 網(wǎng)格搜索法,測試不同的參數(shù)值
grid_dtreg = GridSearchCV(estimator = tree.DecisionTreeRegressor(), param_grid = parameters, cv=10)
# 模型擬合
grid_dtreg.fit(X_train, y_train)
# 返回最佳組合的參數(shù)值
grid_dtreg.best_params_
# 構(gòu)建用于回歸的決策樹
CART_Reg = tree.DecisionTreeRegressor(max_depth = 20, min_samples_leaf = 2, min_samples_split = 4)
# 回歸樹擬合
CART_Reg.fit(X_train, y_train)
# 模型在測試集上的預(yù)測
pred = CART_Reg.predict(X_test)
# 計算衡量模型好壞的MSE值
metrics.mean_squared_error(y_test, pred)
# 構(gòu)建用于回歸的隨機森林
RF = ensemble.RandomForestRegressor(n_estimators=200, random_state=1234)
# 隨機森林?jǐn)M合
RF.fit(X_train, y_train)
# 模型在測試集上的預(yù)測
RF_pred = RF.predict(X_test)
# 計算模型的MSE值
metrics.mean_squared_error(y_test, RF_pred)
# 構(gòu)建變量重要性的序列
importance = pd.Series(RF.feature_importances_, index = X_train.columns)
# 排序并繪圖
importance.sort_values().plot(kind='barh')
plt.show()
