從泰坦尼克項目中,學習數據處理

個人博客

前言

學習機器學習也有一段時間了,在這段時間內,有很多感想,其中之一就是數據處理的重要。
在機器學習中,一般使用pandas進行數據的處理,使用matplotlib或者seaborn進行圖形化數據,兩者結合起來處理和分析數據,能讓之後的步驟事半功倍。
用來學習的項目是kaggle上的項目,有很多人分享了對這個項目的處理方法,我認爲這個項目很重要的一點就是,數據的分析和處理,比模型更加重要。

分析

拿到數據,首先可以一窺數據大概,將數據展示出來看看大概構成:

train = pd.read_csv('../input/train.csv')
test = pd.read_csv('../input/test.csv')
combine = [train, test]
train.head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th… female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S

其中數據欄目分別爲:id,是否獲救,座位等級,姓名,性別,年齡,船上兄弟姐妹個數,船上父母子女個數,票號,票價,客艙號,登陸港口

接下來就要開始分析這些數據了。

基於個人理解,船上人員如果紳士,那麼最有可能和存活相關的應該是性別,年齡。

然後考慮的應該是當時的社會等級,有可能相關的是座位等級,票價。

還有可能和當時團隊力量相關,那麼是否有親人在船上也是一個可以考慮的因素。

現在就要驗證之前的想法:

train[['Sex', 'Survived']].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)
Sex Survived
0 female 0.742038
1 male 0.188908
train[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)
Pclass Survived
0 1 0.629630
1 2 0.472826
2 3 0.242363
train[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)
SibSp Survived
1 1 0.535885
2 2 0.464286
0 0 0.345395
3 3 0.250000
4 4 0.166667
5 5 0.000000
6 8 0.000000
train[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)
Parch Survived
3 3 0.600000
1 1 0.550847
2 2 0.500000
0 0 0.343658
5 5 0.200000
4 4 0.000000
6 6 0.000000

直接能夠分析的幾個數據已經看出來了,其中性別和座位等級確實對獲救影響很大,親人數量影響不是很絕對。

還有幾個其他的數據,都可以像這樣來分析,分析出來數據之後,可以判斷出這個條件是否是決定存活與否的關鍵因素。

數據補充

還有幾個維度的數據有缺失,需要進行數據處理,所以先進行一下數據的處理,爲缺失的年齡數據補齊,補充數據的思路很多,可以隨機年齡,可以平均年齡:

for dataset in combine:
    age_guess = dataset['Age'].dropna().median()
    dataset.loc[dataset.Age.isnull(), 'Age'] = age_guess
    dataset['Age'] = dataset['Age'].astype(int)

train.head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th… female 38 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35 0 0 373450 8.0500 NaN S

年齡補充完整之後,分析年齡。
因爲像年齡這種帶跨度的數據,可以使用跨度來進行分析,用pandas的cut方法生成跨度字段,再通過跨度字段進行統計:

train['AgeBand'] = pd.cut(train['Age'], 5)
train[['AgeBand', 'Survived']].groupby(['AgeBand'], as_index=False).mean().sort_values(by='AgeBand', ascending=True)
AgeBand Survived
0 (-0.08, 16.0] 0.550000
1 (16.0, 32.0] 0.344762
2 (32.0, 48.0] 0.403226
3 (48.0, 64.0] 0.434783
4 (64.0, 80.0] 0.090909

可以看到年齡段對生存的影響不是很絕對,但是也有將近一半的概率。

其他的數據中,也有一部分數據是缺失的,可以用上面提到的辦法,或者更巧妙的辦法進行補充,補充之後進行統計,更加準確。

for dataset in combine:
    dataset['Embarked'] = dataset['Embarked'].fillna('S')

標準化

目前數據都已經分析好,或者說準備好,但是這些數據還不能直接用來做模型的輸入。

因爲模型不能處理如:male, female。這樣的文字。而且Fare這一欄中,數字要遠遠大過其他欄的數字,這樣Fare的影響可能會讓模型不夠準確。所以在進行模型訓練之前,先要對數據進行標準化。

以年齡標準化爲例:

for dataset in combine:
    dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0
    dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
    dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
    dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
    dataset.loc[ dataset['Age'] > 64, 'Age'] = 4
train.head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked AgeBand
0 1 0 3 Braund, Mr. Owen Harris male 1 1 0 A/5 21171 7.2500 NaN S (16.0, 32.0]
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th… female 2 1 0 PC 17599 71.2833 C85 C (32.0, 48.0]
2 3 1 3 Heikkinen, Miss. Laina female 1 0 0 STON/O2. 3101282 7.9250 NaN S (16.0, 32.0]
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 2 1 0 113803 53.1000 C123 S (32.0, 48.0]
4 5 0 3 Allen, Mr. William Henry male 2 0 0 373450 8.0500 NaN S (32.0, 48.0]

將性別和登陸地也進行標準化,使用map函數來做比較簡單:

for dataset in combine:
    dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int)
    dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)

train.head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked AgeBand
0 1 0 3 Braund, Mr. Owen Harris 0 1 1 0 A/5 21171 7.2500 NaN 0 (16.0, 32.0]
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th… 1 2 1 0 PC 17599 71.2833 C85 1 (32.0, 48.0]
2 3 1 3 Heikkinen, Miss. Laina 1 1 0 0 STON/O2. 3101282 7.9250 NaN 0 (16.0, 32.0]
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) 1 2 1 0 113803 53.1000 C123 0 (32.0, 48.0]
4 5 0 3 Allen, Mr. William Henry 0 2 0 0 373450 8.0500 NaN 0 (32.0, 48.0]

去掉我們所不需要的數據(當然,只是我懶,不想分析其他的因素了):

train = train.drop(['Name', 'PassengerId', 'Ticket', 'Fare', 'Cabin', 'AgeBand'], axis=1)
test = test.drop(['Name', 'PassengerId', 'Ticket', 'Fare', 'Cabin'], axis=1)

train.head()
Survived Pclass Sex Age SibSp Parch Embarked
0 0 3 0 1 1 0 0
1 1 1 1 2 1 0 1
2 1 3 1 1 0 0 0
3 1 1 1 2 1 0 0
4 0 3 0 2 0 0 0

總結

到這一步,就可以開始訓練模型了。具體的訓練模型還是不寫在這裏了,本文章是看了這篇文章理解之後寫的,簡化和更改了(因爲懶),英文好的同學,可以看原版。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章