Kaggle泰坦尼克號案例
來自專欄猴子聊數據分析
1、數據來源及說明
(1)數據來源
來自kaggle的數據集Titanic:Titanic: Machine Learning from Disaster
(2)數據說明
下載的數據包含test.csv和train.csv兩個文件。train文檔數據是用來分析和建模,包含有生存情況信息;test數據是用來最終預測其生存情況並生成結果文件。
2、分析目的和思路
本文主要根據train數據的分析並建立模型,預測test數據中乘客在沉船事件中的生存情況。思路主要分為以下幾個過程:
(1)不同變數跟生存情況的關係分析;(2)查看缺失值並對缺失值進行處理;(3)建立模型並預測;(4)提交預測結果,查看網站排名。
3、數據分析和建模
import pandas as pd import numpy as np data_train = pd.read_csv("C:/Users/Administrator/Desktop/Kaggle_Titanic/train.csv")
-載入包並載入文件
data_train.columns
-查看相關特徵
-理解數據變數含義
PassengerId => 乘客ID
Pclass => 乘客等級(1/2/3等艙位)
Name => 乘客姓名
Sex => 性別
Age => 年齡
SibSp => 堂兄弟/妹個數
Parch => 父母與小孩個數
Ticket => 船票信息
Fare => 票價
Cabin => 客艙
Embarked => 登船港口
-查看相關性矩陣
corrDf = data_train.corr() print(corrDf)
-相關性排序
print(corrDf[Survived].sort_values(ascending =False))
-處理缺失值
data_train.info()
我們可以看到所有的缺失信息
-通過可視化觀察屬性與生還的關係
import matplotlib.pyplot as pltplt.rcParams[font.sans-serif]=[SimHei]#用來顯示正常中文標籤% matplotlib inlinefig = plt.figure(figsize=(15,9))fig.set(alpha=0.2) # 設定圖表顏色alpha參數plt.subplot2grid((2,3),(0,0)) # 在一張大圖裡分列幾個小圖data_train.Survived.value_counts().plot(kind=bar)# plots a bar graph of those who surived vs those who did not. plt.title(u"獲救情況 (1為獲救)") # puts a title on our graphplt.ylabel(u"人數") plt.subplot2grid((2,3),(0,1))data_train.Pclass.value_counts().plot(kind="bar")plt.ylabel(u"人數")plt.title(u"乘客等級分布")plt.subplot2grid((2,3),(0,2))plt.scatter(data_train.Survived, data_train.Age)plt.ylabel(u"年齡") # sets the y axis lableplt.grid(b=True, which=major, axis=y) # formats the grid line style of our graphsplt.title(u"按年齡看獲救分布 (1為獲救)")plt.subplot2grid((2,3),(1,0), colspan=2)data_train.Age[data_train.Pclass == 1].plot(kind=kde) # plots a kernel desnsity estimate of the subset of the 1st class passangess agedata_train.Age[data_train.Pclass == 2].plot(kind=kde)data_train.Age[data_train.Pclass == 3].plot(kind=kde)plt.xlabel(u"年齡")# plots an axis lableplt.ylabel(u"密度") plt.title(u"各等級的乘客年齡分布")plt.legend((u頭等艙, u2等艙,u3等艙),loc=best) # sets our legend for our graph.plt.subplot2grid((2,3),(1,2))data_train.Embarked.value_counts().plot(kind=bar)plt.title(u"各登船口岸上船人數")plt.ylabel(u"人數") plt.show()
#觀察統計分布#看看各乘客等級的獲救情況fig = plt.figure()fig.set(alpha=0.2) # 設定圖表顏色alpha參數Survived_0 = data_train.Pclass[data_train.Survived == 0].value_counts()Survived_1 = data_train.Pclass[data_train.Survived == 1].value_counts()df=pd.DataFrame({u獲救:Survived_1, u未獲救:Survived_0})df.plot(kind=bar, stacked=True)plt.title(u"各乘客等級的獲救情況")plt.xlabel(u"乘客等級") plt.ylabel(u"人數")
明顯等級為1的乘客,獲救的概率高很多。這個一定是影響最後獲救結果的一個特徵。#看看各登錄港口的獲救情況fig = plt.figure()fig.set(alpha=0.2) # 設定圖表顏色alpha參數Survived_0 = data_train.Embarked[data_train.Survived == 0].value_counts()Survived_1 = data_train.Embarked[data_train.Survived == 1].value_counts()df=pd.DataFrame({u獲救:Survived_1, u未獲救:Survived_0})df.plot(kind=bar, stacked=True)plt.title(u"各登錄港口乘客的獲救情況")plt.xlabel(u"登錄港口") plt.ylabel(u"人數")
結果不明顯#看看各性別的獲救情況fig = plt.figure()fig.set(alpha=0.2) # 設定圖表顏色alpha參數Survived_m = data_train.Survived[data_train.Sex == male].value_counts()Survived_f = data_train.Survived[data_train.Sex == female].value_counts()df=pd.DataFrame({u男性:Survived_m, u女性:Survived_f})df.plot(kind=bar, stacked=True)plt.title(u"按性別看獲救情況")plt.xlabel(u"性別") plt.ylabel(u"人數")plt.show()
從協方差矩陣中我們可以看出船票號『PassengerId』,堂兄妹SibSp,家族Parch與生還的相關性接近0,所以不考慮了
#cabin只有204個乘客有值,由於缺失值過大,先看看這個值的有無,對於survival的分布狀況的影響fig = plt.figure()fig.set(alpha=0.2) # 設定圖表顏色alpha參數Survived_cabin = data_train.Survived[pd.notnull(data_train.Cabin)].value_counts()Survived_nocabin = data_train.Survived[pd.isnull(data_train.Cabin)].value_counts()df=pd.DataFrame({u有:Survived_cabin, u無:Survived_nocabin}).transpose()df.plot(kind=bar, stacked=True)plt.title(u"按Cabin有無看獲救情況")plt.xlabel(u"Cabin有無") plt.ylabel(u"人數")plt.show()
似乎有cabin記錄的乘客survival比例稍高,那先把這個值分為兩類,有cabin值/無cabin值,再加到類別特徵好了
-補充缺失值
#用scikit-learn中的RandomForest來擬合一下缺失的年齡數據from sklearn.ensemble import RandomForestRegressor ### 使用 RandomForestClassifier 填補缺失的年齡屬性def set_missing_ages(df): # 把已有的數值型特徵取出來丟進Random Forest Regressor中 age_df = df[[Age,Fare, Parch, SibSp, Pclass]] # 乘客分成已知年齡和未知年齡兩部分 known_age = age_df[age_df.Age.notnull()].as_matrix() unknown_age = age_df[age_df.Age.isnull()].as_matrix() # y即目標年齡 y = known_age[:, 0] # X即特徵屬性值 X = known_age[:, 1:] # fit到RandomForestRegressor之中 rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1) rfr.fit(X, y) # 用得到的模型進行未知年齡結果預測 predictedAges = rfr.predict(unknown_age[:, 1::]) # 用得到的預測結果填補原缺失數據 df.loc[ (df.Age.isnull()), Age ] = predictedAges return df, rfrdef set_Cabin_type(df): df.loc[ (df.Cabin.notnull()), Cabin ] = "Yes" df.loc[ (df.Cabin.isnull()), Cabin ] = "No" return dfdata_train, rfr = set_missing_ages(data_train)data_train = set_Cabin_type(data_train)data_train
https://www.douban.com/note/566045251/?type=rec
可以參考這個鏈接用隨機森林來填充缺失值
-特徵工程
#one-hot編碼# 因為邏輯回歸建模時,需要輸入的特徵都是數值型特徵,而男女不是數值型特徵# 以Cabin為例,原本一個屬性維度,因為其取值可以是[yes,no],而將其平展開為Cabin_yes,Cabin_no兩個屬性# 原本Cabin取值為yes的,在此處的Cabin_yes下取值為1,在Cabin_no下取值為0# 原本Cabin取值為no的,在此處的Cabin_yes下取值為0,在Cabin_no下取值為1# 我們使用pandas的get_dummies來完成這個工作,並拼接在原來的data_train之上,如下所示dummies_Cabin = pd.get_dummies(data_train[Cabin], prefix= Cabin)dummies_Embarked = pd.get_dummies(data_train[Embarked], prefix= Embarked)dummies_Sex = pd.get_dummies(data_train[Sex], prefix= Sex)dummies_Pclass = pd.get_dummies(data_train[Pclass], prefix= Pclass)df = pd.concat([data_train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)df.drop([Pclass, Name, Sex, Ticket, Cabin, Embarked], axis=1, inplace=True)df
然後就是建模了
# 我們把需要的feature欄位取出來,轉成numpy格式,使用scikit-learn中的LogisticRegression建模from sklearn import linear_model# y即Survival結果y = df[Survived]# X即特徵屬性值X = df.loc[:, Age:]# fit到RandomForestRegressor之中clf = linear_model.LogisticRegression(tol=1e-6)clf.fit(X, y) clf
-對測試集進行同樣的數據預處理
data_test = pd.read_csv("C:/Users/Administrator/Desktop/Kaggle_Titanic/test.csv")data_test.loc[ (data_test.Fare.isnull()), Fare ] = 0# 接著我們對test_data做和train_data中一致的特徵變換# 首先用同樣的RandomForestRegressor模型填上丟失的年齡tmp_df = data_test[[Age,Fare, Parch, SibSp, Pclass]]null_age = tmp_df[data_test.Age.isnull()].as_matrix()# 根據特徵屬性X預測年齡並補上X = null_age[:, 1:]predictedAges = rfr.predict(X)data_test.loc[ (data_test.Age.isnull()), Age ] = predictedAgesdata_test = set_Cabin_type(data_test)dummies_Cabin = pd.get_dummies(data_test[Cabin], prefix= Cabin)dummies_Embarked = pd.get_dummies(data_test[Embarked], prefix= Embarked)dummies_Sex = pd.get_dummies(data_test[Sex], prefix= Sex)dummies_Pclass = pd.get_dummies(data_test[Pclass], prefix= Pclass)df_test = pd.concat([data_test, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)df_test.drop([Pclass, Name, Sex, Ticket, Cabin, Embarked], axis=1, inplace=True)df_test
用模型進行結果預測
predictions = clf.predict(test)生成的預測值是浮點數(0.0,1,0)但是Kaggle要求提交的結果是整型(0,1)所以要對數據類型進行轉換result = pd.DataFrame({PassengerId:data_test[PassengerId].as_matrix(), Survived:predictions.astype(np.int32)})result.to_csv("C:/Users/Administrator/Desktop/logistic_regression_predictions.csv", index=False)
保存結果為CSV格式,提交到kaggle中
pd.read_csv("logistic_regression_predictions.csv")
這樣就得到了分數與排名,等我再不斷學習調整,讓排名上升吧
推薦閱讀:
※Kaggle—So Easy!百行代碼實現排名Top 5%的圖像分類比賽
※這是一份為數據科學初學者準備的Kaggle競賽指南
※Kaggle實戰項目:泰坦尼克號預測
※Kaggle求生:亞馬遜熱帶雨林篇
※kaggle小黃車競賽 得分:0.41038
TAG:Kaggle |