tropicbirdのブログ

備忘録です。

【kaggle】タイタニックのコンペ(6)

Kaggleで定番のタイタニック号の生存者の分析をPythonで行う記録。

↓コンペのサイトはここです。
Titanic: Machine Learning from Disaster | Kaggle

Pythonによる分析の一例をManav Sehgalさんのカーネルを参考に(と言いうかこれに沿って)行います。
↓Manav Sehgalさんの分析手順はここで確認ができます。
Titanic Data Science Solutions | Kaggle

17.4.数字の連続データを補完する。

・欠損値やNull値がある属性を推測する。まずは年齢のNull値を推測する。
・推測手法を3つ試みる。
・推測手法1:平均と標準偏差に従う乱数を発生させる。
・推測手法2:他の属性との相関から予測する。
・推測手法3:推測手法1と2の組み合わせ。等級と性別ごとの平均と標準偏差について、乱数を発生させる。
・推測手法1と3は乱数を使うため、値が安定しないので、今回は推測手法2を採用する。

#性別の2値(Sex:0,1)と等級の3値(Pclass:1,2,3)の組み合わせによる年齢を推測する。
guess_ages=np.zeros((2,3))

for dataset in combine:
    for i in range(0,2):
        for j in range(0,3):
            guess_df=dataset[(dataset['Sex']==i)&\
                             (dataset['Pclass']==j+1)]['Age'].dropna()
            age_guess=guess_df.median()
            guess_ages[i,j]=int(age_guess/0.5+0.5)*0.5
    
    for i in range(0,2):
        for j in range(0,3):
            dataset.loc[(dataset.Age.isnull())&\
                        (dataset.Sex==i)&\
                        (dataset.Pclass==j+1),'Age']=guess_ages[i,j]
    dataset['Age']=dataset['Age'].astype(int)
    
train_df[train_df.Age.isnull()]
'''出力
	Survived	Pclass	Sex	Age	SibSp	Parch	Fare	Embarked	Title
→AgeのNull値が無いことが確認できた。
'''

・Ageを5つのグループに分ける。

train_df['AgeBand']=pd.cut(train_df['Age'],5)
train_df[['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.337374
2	(32.0, 48.0]	0.412037
3	(48.0, 64.0]	0.434783
4	(64.0, 80.0]	0.090909
'''

・Ageの5つのグループに序数を与える。

for dataset in combine:
    dataset.loc[ dataset['Age'] <= 16, 'Age_category'] = 0
    dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age_category'] = 1
    dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age_category'] = 2
    dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age_category'] = 3
    dataset.loc[ dataset['Age'] > 64, 'Age_category']=4
17.5.既存の属性データから新しい属性データを作成する。

・SibSp(兄弟、配偶者の数)とParch(両親、子供の数)を基にFamilySize(家族の数)の属性を作成する。

for dataset in combine:
    dataset['FamilySize']=dataset['SibSp']+dataset['Parch']+1
train_df[['FamilySize','Survived']].\
groupby(['FamilySize'],as_index=False).\
mean().sort_values(by='Survived',ascending=False)
'''出力
FamilySize	Survived
3	4	0.724138
2	3	0.578431
1	2	0.552795
6	7	0.333333
0	1	0.303538
4	5	0.200000
5	6	0.136364
7	8	0.000000
8	11	0.000000
'''

・IsAlone(独り身)の属性も作成する。

for dataset in combine:
    dataset['IsAlone']=0
    dataset.loc[dataset['FamilySize']==1,'IsAlone']=1

train_df[['IsAlone','Survived']].groupby(['IsAlone'],as_index=False).mean()
'''出力
   IsAlone	Survived
0	0	0.505650
1	1	0.303538
'''

・年齢と等級を組み合わせた人工的な属性を作成する。

for dataset in combine:
    dataset['Age*Class']=dataset.Age_category*dataset.Pclass
train_df.loc[:,['Age*Class','Age_category','Pclass']].head(10)
'''出力
Age*Class	Age_category	Pclass
0	3.0	1.0	3
1	2.0	2.0	1
2	3.0	1.0	3
3	2.0	2.0	1
4	6.0	2.0	3
5	3.0	1.0	3
6	3.0	3.0	1
7	0.0	0.0	3
8	3.0	1.0	3
9	0.0	0.0	2
'''
17.6.カテゴリカルデータを補完する。

・トレーニングデータのうち、Embarked(乗船した港)の属性が抜けているデータが2つある。
・最も一般的な値(mode)で埋める。

freq_port=train_df.Embarked.dropna().mode()[0]
freq_port
#出力:S

for dataset in combine:
    dataset['Embarked']=dataset['Embarked'].fillna(freq_port)
train_df[['Embarked','Survived']].groupby(['Embarked'], as_index=False).\
mean().sort_values(by='Survived',ascending=False)
'''出力
    Embarked	Survived
0	C	0.553571
1	Q	0.389610
2	S	0.339009
'''
17.6.カテゴリカルデータを数値に変換する。

・Embarked(乗船した港)の属性の値を数値に変換する。

for dataset in combine:
    dataset['Embarked']=dataset['Embarked'].map({'S':0,'C':1,'Q':2}).astype(int)
17.7 残りの数値属性の補完と変換を行う。

・Fare属性の値が一つ抜けているのでそれを中央値で補完する。

test_df['Fare'].fillna(test_df['Fare'].dropna().median(),inplace=True)

・Fareの範囲をpd.qcutで4つに分ける。

train_df['FareBand']=pd.qcut(train_df['Fare'],4)
train_df[['FareBand','Survived']].groupby(['FareBand'],as_index=False).\
mean().sort_values(by='FareBand',ascending=True)
'''出力
	FareBand	Survived
0	(-0.001, 7.91]	0.197309
1	(7.91, 14.454]	0.303571
2	(14.454, 31.0]	0.454955
3	(31.0, 512.329]	0.581081
'''

・Fareを順序尺度に変換する。

for dataset in combine:
    dataset.loc[ dataset['Fare'] <= 7.91, 'Fare'] = 0
    dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
    dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare']   = 2
    dataset.loc[ dataset['Fare'] > 31, 'Fare'] = 3
    dataset['Fare'] = dataset['Fare'].astype(int)

train_df = train_df.drop(['FareBand'], axis=1)
combine = [train_df, test_df]