Kaggle實戰:泰坦尼克號生存預測

本次《泰坦尼克號生存預測》為學習+練習項目,旨在掌握一次完整的機器學習建模預測過程。為了能夠所向披靡,必須練就以下素質方可上路:

  • 武器:Python
  • 技能:邏輯回歸LogisticRegression
  • 狀態:sklearn

另外,還有一本通關秘籍:

好了,加滿技能,上路→→→


一、提出問題

這次任務要解決的問題嘛,其實很簡單,就是已知船上所有人的基本信息和一部分人的存活狀態,預測另一部分人的存活狀態。

二、理解數據

2.1 採集數據

Kaggle這個平台隸屬於Google,沒個啥啥工具,你會連數據都見不著的。這裡送你個道具:星際Rallets,註冊一下,送你10天口糧,足夠你打通本關了。

登上Kaggle平台,你仍需先註冊個角色,至於你選法師啊還是戰士啊,都無所謂,只要DPS高就行(我建議你選戰士,皮糙肉厚啊),郵件認證後,恭喜你,終於可以開打本關了。

直接搜「titanic」這一關,第一個跳出來的就是了:

點進去,把三個數據文件都下載下來:

2.2 導入數據

把剛剛下載的①②文件導入Python,解釋一下三個文件的意思:

① train.csv:包含了一部分人的基本信息和生存狀態

② test.csv:包含了另一部分人的基本信息(生存狀態等你來建模預測)

③ gender_submission.csv:給你提供一個提交格式的範本,必須按照格式來,否則無效

導入後,要第一時間把兩個數據集縱向合併為一個數據集,否則後面清洗數據會抓狂的。

2.3 查看數據

先來分別看看各個數據集的大小吧,有多少行數據、多少個變數都不知道的話,肯定見不到BOSS半路就被小兵KO了:

原始數據集source_df,在後面建模的時候,要被拆分成訓練集和測試集;

預測數據集test_df,需要用模型對其進行預測;

整個數據集=原始數據集+預測數據集。

下圖證明,預測數據集test_df正是缺少預測變數Survived:

查看數據前5行,看看都有啥變數,每個變數的數據都是什麼模樣,做到心中有「數」:

再看一下描述統計信息:

好吧,既然對非數值型數據無能為力,我就換個技能試試:

這下看清楚了:

float(3個)和int(4個)都屬於數值型變數,在建模時均屬於可直接使用的數據類型;

object(5個),是通用的字元串類型對象,想要用於模型構建,得先處理一下。

下面列個表格,匯總一下所有變數:

從數據框的info信息中,還可以順便得到缺失值情況:

接下來,是整個任務的攻堅階段,把這個階段熬過去,後面就會輕鬆幹掉BOSS,高高興興接公主回家了。


三、清洗數據

3.1 數據預處理

先把缺失值補全了,否則彈藥(數據框)裝不進武器(模型)啊。

在這裡,對於數值型缺失值,可採用平均值填補;對於非數值型,可採用眾數填補。

填補缺失值後,整體上檢查一下是否有問題:

數據框已經完好,繼續進入攻堅階段的核心難點--特徵工程:

特徵工程,就是從原始數據中,最大限度地提取特徵,經過特徵變換、特徵融合等微操,形成後期訓練模型的輸入自變數集合。

特徵工程決定了這個任務完成的好壞,如果持有一個好的特徵工程,哪怕演算法選的比較初級,仍然可以很好地做正確率高的預測。

3.2 特徵工程--特徵提取

前面說過,有實際意義的數值型變數可直接選入特徵。對於那些不乖的變數,下面開始一個一個、耐心地打怪升級。

3.2.1 將Cabin列重編碼為虛擬變數

觀察Cabin列的數據,乍一看去,有點雜亂,仔細一看,首字母比較有規律,可以提供一定的信息,先將首字母提取出來。

這裡介紹一個技能:map

Series的map方法,可以將Series的每個元素,執行map所指定的操作。

例如:Cabin列的每個元素均為字元串,可通過字元串的索引功能string[0],將首字母提取出來,就可以這樣強硬地使用map技能,對每個字元串截取首字母:

其中的lamda為匿名函數,後接參數,這裡參數指代原始字元串,要熟悉這種套路,打起怪來才能行雲流水。

截取之後的首字母,明顯只有幾個類別,為了便於建模分析,需要將其編碼為虛擬變數,也就是變為數值型特徵。

編碼虛擬變數的技能:pd.get_dummies

這個技能適合類別多於2類的數據,它會自動生成編碼後的特徵數據框。

所以,重編碼後新的特徵,需要新建一個數據框存儲下來:

每次形成新的特徵數據框之後,需要立刻將其與原數據集full_df按列合併,axis=1。同時刪除舊變數:

3.2.2 將Embarked列重編碼為虛擬變數

有了上面的一套連招,相信這一小節應該完全沒難度。

創建特徵數據框→pd.get_dummies→按列合併至原數據集→刪除舊變數→查看合併結果

3.2.3 將Name列重編碼為虛擬變數

先查看一下Name列的數據內容,還是挺雜亂,emmmm……貌似還有些規律,而且還能提供信息!

發現了嗎?每條數據都有格式:「姓, 頭銜. 名字」,可以把「頭銜」部分,通過字元串截取出來,再歸類出6種類別的社會階層啊!

這裡補充一下:map技能,後面可接函數名執行特定操作哦

先定義一個「頭銜」截取函數:先截取逗號右邊,再截取句點左邊,最後把空格去掉,OK!

釋放第一次map技能:截取頭銜字元串

創建映射字典,將上述N多種頭銜,歸為6類。再釋放一次map技能:

好,類別型變數有了,接下來釋放pd.get_dummies技能,完成虛擬變數重編碼。特徵數據框合併原數據集,刪除過渡無用變數:

3.2.4 將Parch列和SibSp列融合為新特徵(家庭大小特徵family_size)

接下來搞點特徵融合,Parch(非同代親屬數)和SibSp(同代親屬數)都為數值型,可以考慮融合為家庭大小的特徵。家庭大小familysize=Parch+SibSp+1(自己),結果為數值型,為了降維數據,可將family_size按數字範圍分組為:

  • 小號家庭family_single,family_size = 1
  • 中號家庭family_middle,2<=family_size<=4
  • 大號家庭family_large,family_size>=5

這裡為了一步完成,沒有採用先分類,再dummy的方式。而是通過map+lamda的組合技能,直接定義family_size特徵數據框每一列的定義:

3.2.5 將Pclass列重編碼為虛擬變數

Pclass列為數值型的1,2,3,其實際意義應為代表級別的類別型變數,且變數水平數>2,直接釋放pd.get_dummies技能搞定:

3.2.6 將Sex列編碼為類別變數

Sex列只有兩種值:female和male,變數水平數=2,直接map+映射字典,變為0或1的數值類型。

至此,最磨人意志的階段終於熬過去了,讓我們看看,原始數據集被收拾成了什麼樣?

只截取部分圖片

我們看到,現在已經具有30個變數了(含預測標籤Survived列)。

下面開始選擇特徵→→→

3.3 特徵工程--選擇特徵

選取原則:根據所有變數的相關係數矩陣,篩選出與預測標籤Survived最相關的特徵變數。

只截取部分圖片

單獨選擇Survived列,按列降序排列,就能看到哪些特徵最正相關,哪些特徵最負相關,將其篩選出來作為模型的特徵輸入。

正相關和負相關

選擇title_df, pclass_df, family_df, Fare, cabin_df, Sex作為特徵。

構建整體數據集的特徵數據框full_x(包含1309行整體數據集特徵),再使用loc屬性拆分出891行原始數據集特徵source_x和標籤source_y、481行測試數據集特徵test_x:


四、建立模型

終於見到BOSS了,驚不驚喜?嗨不嗨森?別嘚瑟,這裡要是搞不清楚各個數據集都代表什麼,那肯定被BOSS虐慘。

建模的時候,需要將原始數據集進行二八拆分:80%訓練集+20%測試集。

訓練集用於訓練模型;測試集用於評估模型效果。

加滿sklearn的BUFF,開干!

拆分數據集→建模→訓練模型


五、評估模型

使用model.score方法,通過測試集得到模型預測準確率。

準確率82%,還可以,拿來做預測吧!


六、提交Kaggle

我們看到預測結果pred_y是浮點數,而官網範例給的是整型int,故需先進行數據類型轉換,然後按照範例文件,創建具有兩個欄位的無index文件(Titanic.csv)

好啦,BOSS解決了,上傳到Kaggle看看戰績吧:


總結:

第一次在Kaggle上實踐機器學習,主要目的是掌握數據清洗中的特徵工程方法,其實最重要的部分也在這裡。涉及到的幾個新技能:

  • Series的map方法:高效、快速地批量處理列數據,也適用二水平分類數據的編碼
  • pd.get_dummies方法:適用多水平分類數據的虛擬編碼,premix增加變數名前綴
  • lamda匿名函數:配合以上技能效果更佳哦
  • pd.concat方法:axis=1按列合併
  • df.drop(column, axis=1,inplace=True)原地刪除無用變數
  • 數據集縱向合併df1.append(df2, ignore_index=True)

改日修得更NB的特徵工程方法和演算法,再來提高排名。


推薦閱讀:

那些錯過泰坦尼克號的「幸運兒」
泰坦尼克號上的6個中國人,106年沒等來一句抱歉
世界最令人困惑的未解之謎之「泰坦尼克」號沉沒之謎
沉沒100多年,沒想到真實的泰坦尼克長這樣....

TAG:機器學習 | Python | 「泰坦尼克號」沉沒事故 |