泰坦尼克号分析是否获救
1.從kaggle獲取數據
kaggle網站
Competions泰坦尼克號鏈接
點擊date,然后點擊Download ALL即可獲得數據,解壓后可以得到3個csv文件,分別是:
- gender_submission.csv?分析女性全部獲救概率
- test.csv 測試文本,沒有Survived,根據訓練生成的模型預測其他人的存活狀況。
- train.csv 訓練文本,有一些乘客的個人信息以及存活狀況,要嘗試根據它生成合適的模型。
得到了數據后可以開始根據train.csv分析出一個baseline的model出來,再進行后續的分析步驟
2.分析步驟
- 認識數據
- 分析和處理數據中的特殊點/離群點
- 特征工程(feature engineering)
- 模型融合(model ensemble)
2.1在kaggle中瀏覽數據字典(Data Dictionary)情況
數據字典翻譯
| survival | 生存 | 0=否,1=是 |
| pclass | 客位等級 | 1=1,2=2,3=3 |
| sex | 性別 | |
| age | 歲數 | |
| Sibsp | 泰坦尼克號上的兄弟姐妹/配偶 | |
| parch | 泰坦尼克號上的父母/孩子 | |
| ticket | 船票信息 | |
| fare | 船費 | |
| cabin | 船艙號 | |
| embarked | 從那個港口上船 | C=瑟堡,q=昆斯敦,S=南安普敦 |
2.2添加相關的包import
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt# machine learning from sklearn.ensemble import RandomForestRegressor from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC, LinearSVC2.3數據分析
導入數據
train_df = pd.read_csv(r'E:\2345下載\kaggle\泰坦尼克號\train.csv') #r為絕對路徑,相對路徑直接輸入 test_df = pd.read_csv(r'E:\2345下載\kaggle\泰坦尼克號\test.csv') combine = [train_df, test_df]數據導入后可以查看一下,print(combine),由于數據過多,可以看一下它的info
train_df.info() test_df.info()結果如下:
train_df? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?test_df
? ? ? ? ? ? ?
我們可以發現train樣本中有891條數據,其中Age,Cabin,Embarked有缺失,在test樣本中,Age和Cabin有缺失
查看測試樣本的特征分布(describe方法)
train_df.describe()結果如下:
我們可以發現:
- 訓練樣本有891
- 獲救率為38.84%
- 大部分人的Pclass為3
- 平均年齡為29.7歲
- 大部分人的票價低于平均值32
綜上所述,我們可以總結一下,做出一下分析假設:
- 是否獲救可能和性別,年齡有關。畢竟逃生的話,小孩老人女士優先嘛。
- 是否獲救可能和Parch,SibSp有關,逃生可能和家庭有關系
- 可以探究一下船票等級(Pclass),有錢人可能優先
- 探究一下Embarked,登船港口可能和地位有關
- 雖然cabin缺失太多,但是可能與獲救有關
- fare船票費用可能貴的先逃生
3.繪制圖表,可視化分析?
3.1Age和Sex與Survived的關系
m = sns.FacetGrid(train_df, col='Survived',row='Sex') #col為列,row為行 m.map(plt.hist, 'Age', bins=25)?結果如下:
?很明顯可以看出女士和小孩的獲救概率要高
3.2探究Parch,SibSp與Survived的關系
m = sns.FacetGrid(train_df, col='Survived') m.map(plt.hist, 'Parch') m = sns.FacetGrid(train_df, col='Survived') m.map(plt.hist, 'SibSp')結果如下:
結果有些復雜,基本看不出來Parch,SibSp與Survived有聯系,暫時放在這里,可能將Parch+SibSp組成一個新特征Family后與Survived有關系。
3.3Pclass與Survived的關系
grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', aspect=1.5) grid.map(plt.hist, 'Age', alpha=.5, bins=25)?結果如下:
?由圖可得,Pclass等于1和2時的獲救率明顯大于Pclass等于3時。有錢人果然優先逃生。
3.4在不同的Embarked中Fare與Survived的關系
grid = sns.FacetGrid(train_df, col='Embarked',hue='Survived') grid.map(plt.hist,'Fare',bins=10) grid.add_legend()結果如下:
我們可以明顯看出S港的獲救率沒有C港和Q港高,而且C港的Fare比較高,結合整個圖可以分析出Fare高的獲救率高,C港和Q港的人比較有錢,S港的船票費用低且獲救率低。
小小分析一下,有cabin 的獲救率高,但是cabin缺失太多,不能得出什么結果,我希望放棄cabin。
4.數據預處理
目前為止,Survived可能與Sex,Age,Fare,Embarked,Pclass,Family(Parch+SibSp)有關
我們目前放棄了?Ticket(太亂了,沒有規律)和cabin。
我們希望能夠為Age和Embarked補齊數據,我們可以考慮種倆方法來填補數值連續特征:
- 手動設置方法補充(1.在均值和標準偏差之間生成隨機數2.使用其他相關特征,猜測相關值)
- 用scikit-learn中的RandomForest來擬合一下缺失的數據
由于本人比較懶,我希望使用scikit-learn中的RandomForest來擬合一下缺失的數據。
# 填補缺少值或空值 def set_missing_ages(df):# 把已有的數值型特征取出來丟進Random Forest Regressor中age_df = df[['Age', 'Fare', 'Parch', 'SibSp', 'Pclass']]# 乘客分成已知年齡和未知年齡兩部分known_age = age_df[age_df.Age.notnull()].valuesunknown_age = age_df[age_df.Age.isnull()].values# 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'] = predictedAgesreturn df, rfr# 補充train的age,依據train的age補充test train_df, rfr = set_missing_ages(train_df) tmp_df = test_df[['Age','Fare', 'Parch', 'SibSp', 'Pclass']] null_age = tmp_df[test_df.Age.isnull()].values # 根據特征屬性X預測年齡并補上 X = null_age[:, 1:] predictedAges = rfr.predict(X) test_df.loc[ (test_df.Age.isnull()), 'Age' ] = predictedAges combine=[train_df,test_df]Age補充完畢,由于小孩優先逃生,所以Age基于16的將Age的數值分割。
for dataset in combine:dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3dataset.loc[ dataset['Age'] > 64, 'Age']然后補充Embarked,由于Embarked缺陷非常少,所以用均值填充。
freq_port = train_df.Embarked.dropna().mode()[0] for dataset in combine:dataset['Embarked'] = dataset['Embarked'].fillna(freq_port)順便將Embarked數字化
# 將embarked轉化為數字 for dataset in combine:dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)特征工程
特征工程
特征工程
接下來是最重要的特征工程
首先分析Name,將Name按26個英文字母排序
for dataset in combine:dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False) # 參數expand=false 標志返回一個df pd.crosstab(train_df['Title'], train_df['Sex'])結果如下:
我們可以將Name合并為Mr,Miss,Mrs,Master,Other(其他),再將其數字化
for dataset in combine:dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col',\'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Other')dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Other": 5} for dataset in combine:dataset['Title'] = dataset['Title'].map(title_mapping)dataset['Title'] = dataset['Title'].fillna(0)最后在將原特征刪除,這里不僅刪除Name,還有多余的無關特征Ticket, Cabin,順便將Sex數字化
#刪除無關特征 train_df = train_df.drop(['Ticket', 'Cabin'], axis=1) test_df = test_df.drop(['Ticket', 'Cabin'], axis=1) combine = [train_df, test_df]# 刪除名字 train_df = train_df.drop(['Name', 'PassengerId'], axis=1) test_df = test_df.drop(['Name'], axis=1) combine = [train_df, test_df]# sex轉換數字 for dataset in combine:dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int)我們可以為 Family創建一個新特征,它結合了 Parch 和 SibS,再創建一個輔助特征叫做 isAlone。最后可以刪除原特征。
# 設置新特征家庭 for dataset in combine:dataset['Family'] = dataset['SibSp'] + dataset['Parch'] + 1 # 設置輔助特征 for dataset in combine:dataset['IsAlone'] = 0dataset.loc[dataset['Family'] == 1, 'IsAlone'] = 1 # 刪除原特征 train_df = train_df.drop(['Parch', 'SibSp', 'Family'], axis=1) test_df = test_df.drop(['Parch', 'SibSp', 'Family'], axis=1) combine = [train_df, test_df]最后,我們給Fare分類
先查看一下Fare的分布
train_df['Fare'].describe()
結果如下:
count ? ?891.000000
mean ? ? ?32.204208
std ? ? ? 49.693429
min ? ? ? ?0.000000
25% ? ? ? ?7.910400
50% ? ? ? 14.454200
75% ? ? ? 31.000000
max ? ? ?512.329200
我們取7.91(25%),14.45(50%),31(75%)
#Fare分類 test_df['Fare'].fillna(test_df['Fare'].dropna().median(), inplace=True) train_df['Fare'].fillna(train_df['Fare'].dropna().median(), inplace=True) for dataset in combine:dataset.loc[ dataset['Fare'] <= 7.91, 'Fare'] = 0dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.45), 'Fare'] = 1dataset.loc[(dataset['Fare'] > 14.45) & (dataset['Fare'] <= 31), 'Fare'] = 2dataset.loc[ dataset['Fare'] > 31, 'Fare'] = 3dataset['Fare'] = dataset['Fare'].astype(int) combine = [train_df, test_df]5.模型,預測和解決
我們準備訓練模型并預測所需的解決方案。 有60多種預測建模算法可供選擇。 我們必須了解問題的類型和解決方案要求,以縮小到我們可以評估的少數幾個模型。
這里我選擇Logistic回歸和SVM訓練算法
# ------------------------------------------ # # 模型 X_train = train_df.drop("Survived", axis=1) Y_train = train_df["Survived"] X_test = test_df.drop("PassengerId", axis=1).copy()# Logistic Regression 邏輯回歸 logreg = LogisticRegression() logreg.fit(X_train, Y_train) Y_test = logreg.predict(X_test)# 保存 save= pd.DataFrame({"PassengerId": test_df["PassengerId"],"Survived": Y_test}) save.to_csv(r'E:\2345下載\kaggle\test_result.csv', index=False)# svm訓練算法 svc = SVC() svc.fit(X_train, Y_train) Y_pred = svc.predict(X_test)save= pd.DataFrame({"PassengerId": test_df["PassengerId"],"Survived": Y_pred}) save.to_csv(r'E:\2345下載\kaggle\test_result2.csv', index=False)最后得到的csv文件就可以在Kaggle的Make a submission頁面
總結
以上是生活随笔為你收集整理的泰坦尼克号分析是否获救的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: autoit3 ie.au3 函数之——
- 下一篇: jquery禁止鼠标右键 原生js禁止鼠