1、數據來源
(1)數據來源
來自kaggle的數據集Titanic:Titanic: Machine Learning from Disaster
train文檔數據是用來分析和建模,包含有生存情況信息;test數據是用來最終預測其生存情況並生成結果文件。
2、分析流程
(1)不同變量跟生存情況的關系分析;
(2)查看缺失值並對缺失值進行處理;
(3)建立模型並預測;
(4)提交預測結果,查看網站排名。
3、數據分析
載入文件:
import pandas #中文的話這樣打開,不會出現Initializing from file failed這種錯誤 f=open("C:/Users/中文的話/Desktop/Kaggle_Titanic/train.csv") titanic=pandas.read_csv(f) titanic.describe()
data_train.info()
#從datafrom中得到一些信息
可以看到所有的缺失值信息
用可視化分析觀察各部分與生還的關系:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']#用來顯示正常中文標簽 fig = plt.figure() fig.set(alpha=0.2) # 設定圖表顏色alpha參數 plt.subplot2grid((2,3),(0,0)) # 在一張大圖里分列幾個小圖 data_train.Survived.value_counts().plot(kind='bar')# 柱狀圖 plt.title(u"獲救情況 (1為獲救)") # 標題 plt.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"年齡") # 設定縱坐標名稱 plt.grid(b=True, which='major', axis='y') plt.title(u"按年齡看獲救分布 (1為獲救)") plt.subplot2grid((2,3),(1,0), colspan=2) data_train.Age[data_train.Pclass == 1].plot(kind='kde') data_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 lable plt.ylabel(u"密度") plt.title(u"各等級的乘客年齡分布") plt.legend((u'頭等艙', u'2等艙',u'3等艙'),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_m = data_train.Pclass[data_train.Survived == 0].value_counts() Survived_f = 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"人數")
可以看出,等級高的獲救的可能性大。。。
#看看各性別的獲救情況 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()
性別對獲救的影響還是很大的。。
#看看各登錄港口的獲救情況 fig = plt.figure() fig.set(alpha=0.2) # 設定圖表顏色alpha參數 Survived_m = data_train.Embarked[data_train.Survived == 0].value_counts() Survived_f = 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"人數")
可以看出關系不太大。。。
#查看相關性矩陣 corrDf = data_train.corr() print(corrDf)
#相關性排序 print(corrDf['Survived'].sort_values(ascending =False))
從協方差矩陣中我們可以看出船票號‘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記錄的似乎獲救概率稍高一些。。。
數據預處理
用隨機森林填補缺失值
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, rfr def set_Cabin_type(df): df.loc[ (df.Cabin.notnull()), 'Cabin' ] = "Yes" df.loc[ (df.Cabin.isnull()), 'Cabin' ] = "No" return df data_train, rfr = set_missing_ages(data_train) data_train = set_Cabin_type(data_train)
特征工程:
#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
對測試集進行同樣的數據預處理:
n=open("C:/Users/文字/Desktop/Kaggle_Titanic/test.csv")
data_test = pd.read_csv(n) 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' ] = predictedAges data_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/。。。。/Desktop/logistic_regression_predictions.csv", index=False)
保存結果為CSV格式,提交到kaggle中
pd.read_csv("logistic_regression_predictions.csv")