SKlearn機器學習入門(5決策樹(分類))
本文知乎鏈接:https://zhuanlan.zhihu.com/p/33786125
以上章節所使用的邏輯斯蒂回歸和支持向量機模型,都在某種程度上要求學習的數據特徵和目標之間遵照線性假設。然而,在許多現實的場景下,這種假設是不存在的。
比如,如果要藉由一個人的年齡來預測患流感的死亡率,如果採用線性模型假設,那麼只有兩種情況:年齡越大死亡率越高;或者年齡越小死亡率越高。然而,根據常識判斷,青壯年因為更加健全的免疫系統,相較於兒童和老年人不容易因患流感死亡,因此,年齡與因流感而死亡之間不存在線性關係。如果要用數學表達式描述這種非線性關係,使用分段函數最為合理;而在機器學習模型中,決策樹就是描述這種非線性關係的不二之選。
再比如,信用卡申請的審核及申請人的多項特徵,也是典型的決策樹模型。正如下圖所示:決策樹節點(node)代表數據特徵,如年齡(age)、身份是否是學生(student)、信用評級(credict_rating)等;每個節點下的分支代表對應特徵值的分類,如年齡包括年輕人(youth)、中年人(middle_aged)以及老年人(senior),身份區分是否是學生(student),等等;而決策樹的所有葉子節點(leaf)則顯示模型的決策結果。對於是否通過信用卡申請而言,這是二分類決策任務,因此只有yes和no兩種分類結果。
如下圖所示,這類使用多種不同特徵組合搭建多層決策樹的情況,模型在學習的時候就需要考慮特徵節點的選取順序。常用的度量方式包括信息熵(Information Gain)和基尼不純性(Gini Impurity)。
雖然很難獲取到信用卡公司客戶的資料,但是也有類似藉助於客戶檔案進行二分類的任務。本節要是用的數據來自於歷史上一件家喻戶曉的災難性事件:泰坦尼克號沉船事故。1912年,當時隸屬於英國的世界級豪華客輪泰坦尼克號,因為處女航行中不幸撞上北大西洋冰山而沉沒。這場事故使得1500多名乘客罹難。後來,這場震驚世界的慘劇被詳細地調查,而且遇難乘客的信息也逐漸被披露。在當時的救援條件下無法在短時間內確認每位乘客生還的可能性。而今,許多科學家通過計算機模擬和分析找出潛藏在數據背後的生還邏輯。以下代碼將嘗試揭開這塵封了100多年的數據的面紗。
#導入pandas用於數據分析import pandas as pd#利用pandas的read_csv模塊直接從網上收集泰坦尼克號乘客數據titanic=pd.read_csv(http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt)#觀察前幾行數據,可以發現,數據種類各異,數值型,類別型,甚至還有缺失數據titanic.head()
#使用pandas數據都轉入pandas獨有的dataframe格式(二維數據表格),直接使用info(),查看數據的統計特徵titanic.info()
以上代碼的一系列輸出表明:該數據共有1313條乘客信息,並且有些特徵數據是完整的(如pclass,name),有些則是字元串。
比起之前使用過的數據樣例,這次的數據年代更加久遠,難免會有信息丟失和不完整;甚至,許多數據特徵還沒有量化,因此,在使用決策樹模型進行訓練學習之前,需要對數據做一些預處理和分析工作,如以下代碼所示。
#特徵的選擇,這個需要基於一些背景知識,根據我們隊這場事故的了解,sex,age,pclass這些特徵都很有可能是#決定倖免與否的關鍵因素#對當前選擇的特徵進行探查X.info()
#藉由上面的輸出,我們設計如下幾個數據處理的任務:#1)age這個數據列,只有633個需要補充完#2)sex與pclass兩個數據列的值都是類別性的,需要轉化為數值特徵,用0/1代替#首先我們補充age里的數據,使用平均數或者中位數都是對模型偏離造成最小影響的策略X[age].fillna(X[age].mean(),inplace=True)#對補完的數據重新探查X.info()
#由此得知,age特徵得到了補完#數據分割from sklearn.cross_validation import train_test_splitX_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25, random_state=33)#使用scikit-learn.feature_extraction中的特徵轉換器from sklearn.feature_extraction import DictVectorizervec=DictVectorizer(aparse=False)#轉換特徵後,我們發現凡是類別型特徵都單獨剝離出來,獨成一列特徵,數值型的則保持不變X_train=vec.fit_transform(X_train.to_dict(orient=record))print(vec.feature_names_)
#同樣需要對測試數據的特徵進行轉換X_test=vec.transform(X_test.to_dict(orient=record))#從sklearn.tree中導入決策樹分類器from sklearn.tree import DecisionTreeClassifier#使用默認配置初始化決策樹分類器dtc.fit(X_train,y_train)#用訓練好的決策樹模型對測試特徵數據進行預測y_predict=dtc.predict(X_test)
使用同樣用於分類任務的多種性能測評指標,通過以下代碼對乘客是否生還的預測結果進行評價。
#從sklearn.metrics導入classification_reportfrom sklearn.metrics import classification_report#輸出預測準確性print(dtc.score(X_test,y_test))#輸出更加詳細的分類性能print(classification_report(y_predict,y_test,target_names=[died,survived]))
以上代碼的輸出表明:決策樹模型總體在測試集上的預測準確性約為78%。詳細的性能指標進一步說明,該模型在預測遇難者方面性能較好;卻需要在識別生還者的精確率方面下功夫。
相比於其他模型,決策樹在模型描述上有著絕大的優勢。決策樹的推斷邏輯非常直觀,具有清晰的可解釋性,也方面便了模型的可視化。這些特徵同時也保證在使用決策樹模型時,是無需考慮對數據的量化甚至標準化的。並且,與前一節K近鄰模型不同,決策樹仍然屬於有參數模型,需要花費更多的時間再訓練數據上。
參考文獻:《python機器學習及實踐》、《機器學習》西瓜書等。
本文知乎鏈接:https://zhuanlan.zhihu.com/p/33786125
推薦閱讀:
※吳甘沙的四次轉身
※「Google,不許聯想」
※自動駕駛硬體配置
※《無人值守商店運營指引》正式發布,看看首份監管文件都說了些啥
※以後失業就靠AI公司養活?半數美國人表示贊同