用決策樹和隨機(jī)森林解決泰坦尼克號(hào)沉沒問題

決策樹和隨機(jī)森林既可以解決分類問題荡灾,也可以解決預(yù)測問題。

隨機(jī)森林的構(gòu)建有兩個(gè)方面:數(shù)據(jù)的隨機(jī)性選取拓轻,以及待選特征的隨機(jī)選取。
數(shù)據(jù)的隨機(jī)選染铩:
第一扶叉,從原始的數(shù)據(jù)集中采取有放回的抽樣,構(gòu)造子數(shù)據(jù)集帕膜,子數(shù)據(jù)集的數(shù)據(jù)量是和原始數(shù)據(jù)集相同的枣氧。不同子數(shù)據(jù)集的元素可以重復(fù),同一個(gè)子數(shù)據(jù)集中的元素也可以重復(fù)垮刹。
第二达吞,利用子數(shù)據(jù)集來構(gòu)建子決策樹,將這個(gè)數(shù)據(jù)放到每個(gè)子決策樹中荒典,每個(gè)子決策樹輸出一個(gè)結(jié)果酪劫。最后,如果有了新的數(shù)據(jù)需要通過隨機(jī)森林得到分類結(jié)果寺董,就可以通過對(duì)子決策樹的判斷結(jié)果的投票覆糟,得到隨機(jī)森林的輸出結(jié)果了。

待選特征的隨機(jī)選日诳А:
與數(shù)據(jù)集的隨機(jī)選取類似滩字,隨機(jī)森林中的子樹的每一個(gè)分裂過程并未用到所有的待選特征,而是從所有的待選特征中隨機(jī)選取一定的特征御吞,之后再在隨機(jī)選取的特征中選取最優(yōu)的特征麦箍。這樣能夠使得隨機(jī)森林中的決策樹都能夠彼此不同,提升系統(tǒng)的多樣性陶珠,從而提升分類性能挟裂。

隨機(jī)森林屬于集成算法,森林從字面理解就是由多棵決策樹構(gòu)成的集合揍诽,而且這些子樹都是經(jīng)過充分生長的CART樹话瞧;隨機(jī)表示構(gòu)成多棵決策樹的數(shù)據(jù)是隨機(jī)生成的嫩与,生成過程采用的是Bootstrap抽樣法,運(yùn)行速度快交排,預(yù)測準(zhǔn)確高划滋。

隨機(jī)性具體體現(xiàn)在:一、每棵樹的訓(xùn)練樣本隨機(jī)埃篓;二处坪、樹中每個(gè)節(jié)點(diǎn)的分裂字段也是隨機(jī)選擇的,從而不容易產(chǎn)生過擬合架专。

優(yōu)點(diǎn):
決策樹易于理解和解釋同窘,可以可視化分析,容易提取出規(guī)則部脚;
計(jì)算復(fù)雜度不高想邦,對(duì)中間值的缺失不敏感,可以處理不相關(guān)特征數(shù)據(jù)委刘;
測試數(shù)據(jù)集時(shí)丧没,運(yùn)行速度比較快;
決策樹可以很好的擴(kuò)展到大型數(shù)據(jù)庫中锡移,同時(shí)它的大小獨(dú)立于數(shù)據(jù)庫大信煌;
不需要任何領(lǐng)域知識(shí)或參數(shù)假設(shè)淆珊。

缺點(diǎn):
容易出現(xiàn)過擬合問題夺饲。
對(duì)缺失數(shù)據(jù)處理比較困難。
忽略數(shù)據(jù)集中屬性的相互關(guān)聯(lián)施符。
ID3 算法計(jì)算信息增益時(shí)結(jié)果偏向數(shù)值比較多的特征往声。

改進(jìn)措施(主要解決過擬合問題):
對(duì)決策樹進(jìn)行剪枝,可以采用交叉驗(yàn)證法和正則化的方法戳吝;
使用基于決策樹的 combination 算法烁挟,如 Bagging,Random Forest 等骨坑。

應(yīng)用領(lǐng)域:
企業(yè)管理實(shí)踐撼嗓,企業(yè)投資決策,由于決策樹很好的分析能力欢唾,在決策過程應(yīng)用較多且警。

**隨機(jī)森林的優(yōu)點(diǎn): **
可以處理高維數(shù)據(jù),不同進(jìn)行特征選擇(特征子集是隨機(jī)選擇)
模型的泛化能力較強(qiáng)
訓(xùn)練模型時(shí)速度快礁遣,成并行化方式斑芜,即樹之間相互獨(dú)立
模型可以處理不平衡數(shù)據(jù),平衡誤差
最終訓(xùn)練結(jié)果祟霍,可以對(duì)特種額排序杏头,選擇比較重要的特征
隨機(jī)森林有袋外數(shù)據(jù)(OOB)盈包,因此不需要單獨(dú)劃分交叉驗(yàn)證集
對(duì)缺失值、異常值不敏感
模型訓(xùn)練結(jié)果準(zhǔn)確度高
相對(duì)Bagging能夠收斂于更小的泛化誤差

數(shù)據(jù)預(yù)處理

# 導(dǎo)入第三方模塊
import pandas as pd
# 讀入數(shù)據(jù)
Titanic = pd.read_csv('F:\Titanic.csv')
Titanic.shape

891個(gè)觀測醇王,12個(gè)變量

Titanic.head()

數(shù)據(jù)有下面幾列:
PassengerId呢燥,乘客的標(biāo)識(shí)符;
Survived寓娩,他(她)是否存活了下來,為因變量叛氨,1表示存活,0表示未存活
Pclass棘伴,艙室類別寞埠,也許 1 表示經(jīng)濟(jì)艙,2 表示商務(wù)艙焊夸,3 表示頭等艙仁连;
Name,乘客的名字阱穗;
Sex饭冬,性別;
Age颇象,年齡伍伤;
SibSp并徘,即兄弟姐妹(siblings)或配偶(spouses)遣钳,表示在船上的兄弟姐妹以及配偶的數(shù)目;
Parch麦乞,即父母(Parents)或子女(Children)蕴茴,表示在船上的父母子女的數(shù)目;
Ticket姐直,船票詳情倦淀;
Cabin,艙號(hào)声畏,NaN 表示未知撞叽;
Embarked,登船的起始地插龄,S 表示南安普頓(Southampton)愿棋,Q 表示皇后鎮(zhèn)(Queenstown),C 表示瑟堡(Cherbourg)

PassengerID均牢、Name糠雨、Ticket、Cabin無意義徘跪,此處刪除

# 刪除無意義的變量
Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace = True)
#檢查剩余自字是否含有缺失值甘邀,并按行統(tǒng)計(jì)缺失值個(gè)數(shù)
Titanic.isnull().sum(axis = 0)

數(shù)據(jù)清理中最常用的技術(shù)是填充缺失數(shù)據(jù)琅攘。可以用眾數(shù)松邪、平均數(shù)或中位數(shù)來填充缺失數(shù)據(jù)坞琴。選擇這些數(shù)據(jù)沒有絕對(duì)規(guī)則,可以一一嘗試测摔,然后看看它們的表現(xiàn)如何置济。但是根據(jù)經(jīng)驗(yàn)來講,分類數(shù)據(jù)只能用眾數(shù)锋八,連續(xù)數(shù)據(jù)可以用中位數(shù)或平均數(shù)

Age缺失比較多篡撵,不可用均值直接填充琳疏,按照性別對(duì)客戶的缺失年齡分組填充

# 對(duì)Sex分組,用各組乘客的平均年齡填充各組中的缺失年齡
Titanic.Sex.unique()
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)
fillna_Titanic

Embarked缺失較少,此處用眾數(shù)填充

Titanic = pd.concat(fillna_Titanic)
# 使用Embarked變量的眾數(shù)填充缺失值
Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=True)
Titanic.head()

將數(shù)據(jù)集中的離散變量Pclass冀宴、Sex、Embarked進(jìn)行啞變量處理
以登船地?cái)?shù)據(jù)為例——這是用 Q牢硅、S 或 C 填充的數(shù)據(jù)蒙谓。Python 庫不能處理這個(gè),因?yàn)樗荒芴幚頂?shù)字欺嗤。所以需要獨(dú)熱向量化(One Hot Vectorization)來處理参萄,它可以把一列變成三列。用 0 或 1 填充 Embarked_Q煎饼、Embarked_S 和 Embarked_C讹挎,來表示這個(gè)人是不是從這個(gè)港口出發(fā)的。

# 將數(shù)值型的Pclass轉(zhuǎn)換為類別型吆玖,否則無法對(duì)其啞變量處理
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()

表中右邊8個(gè)變量為啞變量

構(gòu)建決策樹模型

# 導(dǎo)入第三方包
from sklearn import model_selection
# 取出所有自變量名稱
predictors = Titanic.columns[1:]
predictors
# 將數(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)

為防止構(gòu)建決策樹過擬合沾乘,需進(jìn)行預(yù)剪枝怜奖,限制樹生長的最大深度,中間節(jié)點(diǎn)能夠繼續(xù)分支的最小樣本量翅阵,葉節(jié)點(diǎn)的最小樣本量

Python提供了網(wǎng)格搜索法歪玲,即調(diào)用GridSearch類選擇最佳的參數(shù)組合

# 導(dǎo)入第三方模塊
from sklearn.model_selection import GridSearchCV
from sklearn import tree
# 預(yù)設(shè)各參數(shù)的不同選項(xiàng)值
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}
parameters
# 網(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_

經(jīng)過十重交叉驗(yàn)證掷匠,可得最佳組合值:3,4,2

# 導(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)
decision_tree
# 模型在測試集上的預(yù)測
pred = CART_Class.predict(X_test)
pred
# 模型的準(zhǔn)確率
print('模型在測試集的預(yù)測準(zhǔn)確率:\n',metrics.accuracy_score(y_test, pred))

此時(shí)因變量為離散變量(分類變量)滥崩,使用準(zhǔn)確率指標(biāo)

當(dāng)因變量為連續(xù)型的數(shù)值,使用均方誤差MSE或者均方根誤差RMSE槐雾,越小代表擬合效果越好夭委,即metrics.mean_squared_error(y_test,pred),在隨機(jī)森林中類似,不再用準(zhǔn)確率,也用MSE株灸。即tree.DecisionTreeClassifier改為Regressor

預(yù)測精度比較高崇摄,但無法體現(xiàn)正例和負(fù)例的覆蓋率,為進(jìn)一步驗(yàn)證模型在測試集上預(yù)測效果慌烧,繪制ROC曲線

# 導(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)
# 計(jì)算AUC的值
roc_auc = metrics.auc(fpr,tpr)
roc_auc
# 繪制面積圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加邊際線
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加對(duì)角線
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()

ROC曲線下的面積AUC為0.85逐抑,超過0.8,模型擬合效果比較好

下面將決策樹進(jìn)行可視化屹蚊,需要在電腦中安裝Graphviz厕氨, 然后將解壓文件中的bin設(shè)置到環(huán)境變量中

# 導(dǎo)入第三方模塊
from sklearn.tree import export_graphviz
from IPython.display import Image
import pydotplus
from sklearn.externals.six 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()) 

構(gòu)建隨機(jī)森林模型

# 導(dǎo)入第三方包
from sklearn import ensemble
# 構(gòu)建隨機(jī)森林
RF_class = ensemble.RandomForestClassifier(n_estimators=200, random_state=1234)
# 隨機(jī)森林的擬合
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))

用隨機(jī)森林確實(shí)提高了測試數(shù)據(jù)集上的預(yù)測準(zhǔn)確率

同樣,也繪制ROC曲線

# 計(jì)算繪圖數(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()

AUC的值為0.87汹粤,同樣比單棵決策樹的AUC高

再挑選出重要因素

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

年齡命斧,票價(jià),是否為女性是最重要的前三個(gè)因素嘱兼,從而在一定程度上體現(xiàn)婦女和兒童優(yōu)先的原則

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末国葬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子芹壕,更是在濱河造成了極大的恐慌汇四,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踢涌,死亡現(xiàn)場離奇詭異通孽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)睁壁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門背苦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人堡僻,你說我怎么就攤上這事糠惫∫咛辏” “怎么了钉疫?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巢价。 經(jīng)常有香客問我牲阁,道長,這世上最難降的妖魔是什么壤躲? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任城菊,我火速辦了婚禮,結(jié)果婚禮上碉克,老公的妹妹穿的比我還像新娘凌唬。我一直安慰自己,他們只是感情好漏麦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布客税。 她就那樣靜靜地躺著况褪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪更耻。 梳的紋絲不亂的頭發(fā)上测垛,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音秧均,去河邊找鬼食侮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛目胡,可吹牛的內(nèi)容都是我干的锯七。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼誉己,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼起胰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巫延,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤效五,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后炉峰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畏妖,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年疼阔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戒劫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡婆廊,死狀恐怖迅细,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淘邻,我是刑警寧澤茵典,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站宾舅,受9級(jí)特大地震影響统阿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜筹我,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一扶平、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔬蕊,春花似錦结澄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呼巷。三九已至,卻和暖如春赎瑰,著一層夾襖步出監(jiān)牢的瞬間王悍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工餐曼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留压储,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓源譬,卻偏偏與公主長得像集惋,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子踩娘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355