如何用sklearn機器學習,來預測泰坦尼克號生存概率?

前言

  • 本文為新手入門筆記,適用於剛入門的朋友參照閱讀練習,大神請繞道,謝謝!
  • 本文共八個章節,是本人在練習2遍的基礎上寫成,分享出來供大家參考;
  • 閱讀大約需要20分鐘。

一,理解項目概況

1.1 登陸官網查看項目概況

泰坦尼克號沉船事件作為歷史上最著名的海難事件,想必大家都很清楚了,具體經過可網上百度了解詳情,這不是本文的重點,不在這裡細數。

言歸正傳,首先登陸sklearn官網,看看介紹:

Titanic: Machine Learning from Disaster?

www.kaggle.com

該文中有項目的詳細介紹,在這裡可下載後面學習需要的數據:

這裡將這三個數據下載下來,以備後面之用,具體三個數據是什麼內容,我們在下一章中再細看。

1.2 查看官網對變數的解釋

查看官網上對變數的解釋:

這裡有個大致了解即可,不必急於看懂,可先截圖保存下來,後面要用到的時候細看也不遲。

1.3 理清分析思路和需求

了解了官網的介紹後,我大致理了下本項目的分析思路,並做了一個思維導圖如下:

下面將根據上圖,逐步實施分析。


二,數據理解、準備

2.1 數據查看、合併

由於第一章已經下載好了數據,則可導入數據先:

可見train.csv比test.csv多了一列,則分別查看兩個數據的列名是什麼:

可見,train.csv比test.csv多了一列Survived,即是否生存,這正是我們要解決的問題:本文即是通過對train.csv的機器學習,來預測test.csv的Survived水平

因此,後面會基於train.csv提取特徵並結合其Survived數據來預測,則test.csv的數據特徵在預測的時候一定要與train.cs的特徵數據一致。只有test.csv的特徵與訓練數據train.csv的特徵一致時才能直接應用訓練模型進行預測,所以要將二者合併起來一起清洗,這樣保證了後面test.csv的特徵數據可直接帶入進行預測。理解了這一點非常重要,有助於我們理清分析思路,同時高屋建瓴,避免走回頭路。

接下來合併兩個數據集,同時注意:test.csv少了一列,合併時忽略,用NaN填充

2.2 理解數據

首先看看數據集full的行、列形狀:

1309行,12列,與前兩個數據集的行之和、列數相符,說明合併成功。

再看看full的數據類型和缺失值情況:

如上圖,有四個缺失值,其中

float64類型數據Age,Fare缺失;

object類型數據Cabin,Embarked缺失,

這為後面數據清洗指明了方向,下面進一步看看數值型數據的描述性統計信息:

顯示與前文分析的缺失值一致,表示目前是進程正確,下面進行數據清洗部分。


三,數據清洗,準備

3.1 處理float64缺失值:Age,Fare

這部分是數值型數據,用均值填充較合理:

如上統計信息顯示,填充成功。

3.2 處理object缺失:Cabin,Embarked

這部分是類型數據,其中cabin缺失的較多,達到了77.46%,則此時其眾數就是unknown,這時直接用U表示unknown較合適;而Embarked只有2條缺失,用出現頻率最高的,即眾數來填充較合理。首先獲取下Embarked的眾數:

如上所示,Embarked列的眾數為S,則可用U、S分別進行填充,如下:

根據info顯示,填充成功。

至此,數據的清洗、準備工作已完成,下一步就是特徵工程了。


四,特徵工程

數據分析、機器學習中,最重要的就是選取合適的數據特徵,供模型演算法訓練。若訓練的特徵相關性高,則能事半功倍,故而特徵工程是整個項目的核心所在,這一步做得好後面模型的正確率就高。

那麼什麼是特徵工程?特徵工程就是最大限度地從原始數據中提取能表徵原始數據的特徵,以供機器學習演算法和模型使用。

下面,結合本例中的變數,先對其進行分類,然後逐個提取特徵。

4.1 對各個變數進行分類

根據前文的info可知,數據可基本分為分類數據、數值數據和序列數據,如下圖所示:

感謝猴子老師的總結圖片,如上可知三種類型數據的處理方法,本文的變數分類為:

而具體提取數據特徵的步驟大致為:

主要是特徵選取和降維,下面一一處理。

4.2 分類數據特徵提取

分類數據主要有Sex,Cabin,Embarked,Pclass,Parch,SibSp,下面逐個清理。

(1)性別Sex

數據Sex在原數據中填充的是female、male,為了方便後面模型訓練,將其轉換成數值型的0、1:

如上所示,轉換成功。這裡要特別注意的是map函數,其表示把其之前的對象按後面的規則逐個映射一遍,後面也將用到map函數,要特別掌握。

(2)登錄港口Embarked

接下來處理登錄港口Embarked,首先看Embarked數據的前五行,了解情況:

如上,Embarked顯示的是乘客在那個港口登陸,而這又是類別數據,這時可用one-hot編碼對這一列數據進行降維。即:給登陸港口C、S、Q分別建一列,如果是在該港口登陸則值為1,否則為0。這樣每個乘客,即每一行,只會在三列中的一列為1,其餘為0,這就實現了類別數據向數值型數據的額轉化,且也實現了數據降維。

具體可用pandas的get_dummies方法實現:

如上EmbarkedDF就是轉換後的Embarked數據,將其添加到full中,並刪除原full中的Embarked列,則Embarked的特徵就準備好了,如下。

需要強調的一點是,contact具有合併數據的功能(axis=1表示按列合併),但python中並不是只有這一個函數具有合併功能,各個函數合併的特點各異,詳見下面兩篇文章:

PANDAS 數據合併與重塑(concat篇)?

blog.csdn.net圖標PANDAS 數據合併與重塑(join/merge篇)?

blog.csdn.net圖標

(感謝原作者的總結~~)

關於數據的合併和重塑,上面兩篇文章說的很清楚,大家可以收藏起來,有需求了打開看也不遲。

言歸正傳,我們看下EmbarkedDF添加到full後的情形,如下:

(3)船艙等級Pclass

下面處理船艙等級Pclass,官網中介紹Pclass分為高中低,數值分別對應為1、2、3,與Embarked數據一致,也對其用get_dummies方法實現one-hot編碼,如下:

將PclassDF更新到full中並刪除原Pclass列,則Pclass數據的特徵也準備好了,如下:

(4)船艙號Cabin

下面處理船艙號Cabin數據,先看Cabin的前5行:

可見,Cabin數據列並不規整,但也不是全無規律可循,可取每個元素的首字母進行填充,然後用新的首字母進行one-hot編碼生存特徵數據CabinDF,最後更新到full中。

這裡要重點注意一個重要的知識點匿名函數lambda,上圖代碼中"lambda a:a[0]"表示返回a的第一個元素,再結合map函數,表示對"full[Cabin]"中的每一個元素都應用一下該匿名函數,即返回首字母,從而實現提取首字母的目的。

關於匿名函數lambda,這裡不再詳述。不過這是個重要的知識點,在python中經常用到,其能用一行代碼優雅的實現函數定義,非常實用,應重點練習。

到了這一步,繼續用get_dummies方法實現one-hot編碼,如下:

將CabinDF更新到full中,並刪除full中的Cabin列,則船艙號Cabin數據特徵也準備好了,如下:

(5)Parch,SibSp數據

接下來處理Parch,SibSp數據,先理解下這兩個數據是什麼意思,再來想如下下手。

SibSp:表示船上兄弟姐妹數和配偶數量,理解為同代直系親屬數量,

Parch:表示船上父母數和子女數,理解為不同代直系親屬數量。

據此,這兩個數據可用來衡量乘客的家庭大小,而家庭的大小規模肯定會影響乘客的生還幾率,因此可創建衡量家庭規模的變數familySize。

familySize應等於:同代直系親屬數量SibSp+不同代直系親屬數量Parch+乘客本人,則有:

如上,可計算出乘客在船上的家庭人數familySize,但此時的familySize各不相同,沒有標準,這並不能直接反應出家庭的規模,因此根據familySize的大小將家庭數量分為大、中、小三種,如下:

如上,當familySize為1時,認定其為小型家庭;

當人數為2至4人時認定其為中等家庭;

當人數大於等於5人時認定其為大型家庭。

到這裡,可將FamilyDF添加到full中,而Parch,SibSp數據可以刪除也可不刪除,本文沒有刪除,後面計算相關係數的時候再看,並不影響後面的分析。至此,Parch,SibSp數據特徵準備好了。

4.3 字元串數據提取特徵

根據前文所述,字元串數據有Name,Ticket兩列。船票Ticket表示的是船票號,由於前文已經對乘客的等級做了處理,故這裡不需要處理Ticket數據;再來看Name數據列:

仔細觀察發現,每一個Name中都含有稱謂,如Mr,Mrs,Miss等,可用split分割字元串提取出這些稱謂:

其中,可用strip方法去除稱謂的前綴、後綴,本文中的前後綴是空格。接下來定義函數,把Name列的所有元素都按上述方法處置:

得到這些稱謂如上圖所示,對提取後的稱謂進行統計,看有多種,每種出現的次數分別是多少?

如上所示,這些稱謂很多,有些出現的次數很少,這不足以將人群分類。有沒有更加簡潔的分類,將上述稱謂分類,以便更加直觀的反應乘客的社會地位?

經網上查西方人對頭銜的分類,可將頭銜分為6類Officer,Royalty,Master,Mr,Mrs,Miss六種,這樣將大大的簡化乘客身份的分類。所以,定義字典,並用map函數完成上述轉換,如下:

完成上述轉換後,可繼續用前面用過的get_dummies方法實現one-hot編碼:

加下來,將titleDF更新到full中,以便後面繼續分析用:

到這裡,完成了Name列數據特徵的提取。

數值型數據有Age,Fare,PassengerId列,其中PassengerId表示乘客的編號,在提交文件中有涉及,不適合做特徵;Age,Fare的數值可直接作為數據特徵使用。

所以,至此完成了所有數據特徵的提取,那麼我們看一下此時的full,都有哪些特徵?

如上所示,共有34列。下一章將獲取這些特徵之間的相關性,並敲定選取哪些特徵作為樣本訓練的特徵。


五,獲取特徵相關性

第四章中獲取的眾多數據特徵,互相之間的是否相關?更進一步,是否生存Survived與哪些特徵相關?這是本章要解決的問題。

5.1 獲取corr矩陣

用dataframe的corr方法,獲取full中所有元素之間的相關性矩陣corrDF:

圖片很大,這裡沒能全部顯示。然而我們的重點是獲取Survived與各個元素之間的相關性,則提取Survived與各個數據的相關係數,並按降序排列,如下:

各個相關係數如上,根據正負相關性強弱,選取特徵Title,Pclass,Fare,Cabin,Embarked,FamilyDF,Age,Sex為特徵,則可據此重組特徵數據,按列選取的話則包含了樣本數據特徵和預測數據的特徵,後面會細說,此處按下不表。

至此,根據相關性選取特徵也準備好了。


六,準備數據

在做好了上述工作之後,將要進行建模、訓練、預測,在這之前必須準備好數據。根據上一章中選取Title,Pclass,Fare,Cabin,Embarked,FamilyDF,Age,Sex為特徵,則首先將這些特徵數據選取出來,命名為full_x,如下:

這裡有個重要的問題要理清楚,就是各個數據集。

  1. 首先,就是要分清楚用於訓練的特徵數據source_x和標籤數據source_y,這倆必須含有上述特徵和標籤Survived數據;
  2. 同時full中還含有test.csv的數據,這一部分數據沒有Survived列。本文正是要預測這一部分Survived情況,因此將full中test.csv部分提取出來,重命名為預測數據特徵pre_x,以備後面預測用。

理清了思路之後,開始準備各個數據集:

這一步至關重要,一定要理解清楚:

  1. 樣本特徵數據是用於模型訓練的,應含完整的選中特徵,即28列數據;
  2. 樣本標籤數據是用於模型根據樣本特徵數據的特徵與樣本標籤數據的一一對應關係來訓練模型用的,故只有Survived列數據這一列,但其行數一定與樣本特徵數據的行數一致;
  3. 預測特徵數據是後面帶入到預測模型進行預測其預測標籤的,故其形式一定要與樣本特徵數據一致,否則後面一定會出錯。如果你做到這一步發現二者不一致,立刻停下來檢查,否則後面走不通。

這裡整通了之後,後面完成後就可用train_test_split拆分樣本數據為訓練數據train和測試數據test,其中訓練數據train用於模型訓練,而測試數據test用於測試該訓練的效果。

此時,可放慢腳步,兩個數據集的特徵和標籤,對應樣本特徵數據和樣本特徵標籤再進一步理解下,一定要理清思路再往後做,這樣後面才能心如明鏡。

準備好上述這些數據後,就可以開始建立模型,並訓練了。


七,模型建立、訓練

用sklearn的linear_model的邏輯回歸演算法建立模型,並開始用拆分好的數據進行訓練:


八,模型的評估、預測

8.1 模型正確率評估

用模型model的score方法,查看其正確率,看看該模型預測的test_y與預留的test_y對比後,正確的比例有多少:

模型的正確率為86%,表明擬合的很好,正確率高,可以使用來預測。

8.2 用模型進行預測

將前面準備的預測數據特徵pre_x,用模型的predict方法預測生存數據pre_y,並整理成整數型int數據:

8.3 按項目要求收集數據

還記得第一章中下載好的三個數據集中的gender_submission.csv嗎?根據官網釋義,這個是要提交的預測數據的要求格式,則我們上傳的數據應與這個樣式數據完全一致,其中的列名「PassengerId」「Survived」的大小寫也應完全一致,否則系統會因無法讀取數據而報錯,後面的截圖中就有兩次提交系統顯示的error,都是這個原因導致的。

言歸正傳,我們看過要求的數據格式後,開始準備:

經過上述運算,可到電腦上查看得出的數據是否與式樣中要求的一樣,然後就可以提交預測結果到sklearn官網,看看自己的排名了。

這個項目,我做了兩遍,提交了兩次:

其中第二次的排名更高一些,本文中所用即是第二次的練習過程。

至此,本項目已經全部做完了。我是第一次做這種項目,如果有朋友看到這裡可多練習幾遍,多提交幾次,這樣才能更好的理解。

最後附上我的sklearn的my-profile頁面,希望自己後面能多做一些類似的項目,讓這個界面看起來更豐滿一些,哈哈。


小結

  • 一定要理清思路了再下手;
  • 多練習兩遍自然就清楚了;
  • 數據分析的思維培養,正是在這樣的項目過程中形成,所以我應該多總結反思。

以上就是本文的全部,如果您竟然看到了這裡請多多點贊支持哈,謝謝了朋友~~


推薦閱讀:

TAG:數據分析 | 數據分析師 | Python入門 |