さてここからが問題です。 ここまでは比較的に簡単な処理を行ってきました。今処理できていないのはName、TicketとCabinでしょう。それぞれNameは全くみんなバラバラでどう処理の仕方がわからない。Ticketも同様。Cabinは欠損値が多すぎる。これらの骨が折れる奴らを処理しなければなりません。私には全く思いつきません。では、どうするのか?Kaggleにはカーネルがありますので参考にしながら進めて行きましょう。ここまでも参考にしてきましたが… はじめにNameを処理して行きます。Nameを眺めてなんとなく共通しているものに気がつくでしょうか?Mr、Mrs、Missなどの敬称があると思います。これで分類してみましょう。Salutationは挨拶という意味らしいです。そして今は女性に対して使うMissとMrsがMsに統合されているそうです。
combine1 = [train] for train in combine1: train['Salutation'] = train.Name.str.extract(' ([A-Za-z]+).', expand=False) for train in combine1: train['Salutation'] = train['Salutation'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare') train['Salutation'] = train['Salutation'].replace('Mlle', 'Miss') train['Salutation'] = train['Salutation'].replace('Ms', 'Miss') train['Salutation'] = train['Salutation'].replace('Mme', 'Mrs') del train['Name'] Salutation_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5} for train in combine1: train['Salutation'] = train['Salutation'].map(Salutation_mapping) train['Salutation'] = train['Salutation'].fillna(0)
次に、Ticketの処理です。今度はTicketの先頭の文字で分けていきます。また、文字列の長さでも分けていきます。そして、その後にそれらの文字を数字に直します。
for train in combine1: train['Ticket_Lett'] = train['Ticket'].apply(lambda x: str(x)[0]) train['Ticket_Lett'] = train['Ticket_Lett'].apply(lambda x: str(x)) train['Ticket_Lett'] = np.where((train['Ticket_Lett']).isin(['1', '2', '3', 'S', 'P', 'C', 'A']), train['Ticket_Lett'], np.where((train['Ticket_Lett']).isin(['W', '4', '7', '6', 'L', '5', '8']), '0','0')) train['Ticket_Len'] = train['Ticket'].apply(lambda x: len(x)) del train['Ticket'] train['Ticket_Lett']=train['Ticket_Lett'].replace("1",1).replace("2",2).replace("3",3).replace("0",0).replace("S",3).replace("P",0).replace("C",3).replace("A",3)
同様にCabinも先頭の文字で分けていきます。
for train in combine1: train['Cabin_Lett'] = train['Cabin'].apply(lambda x: str(x)[0]) train['Cabin_Lett'] = train['Cabin_Lett'].apply(lambda x: str(x)) train['Cabin_Lett'] = np.where((train['Cabin_Lett']).isin([ 'F', 'E', 'D', 'C', 'B', 'A']),train['Cabin_Lett'], np.where((train['Cabin_Lett']).isin(['W', '4', '7', '6', 'L', '5', '8']), '0','0')) del train['Cabin'] train['Cabin_Lett']=train['Cabin_Lett'].replace("A",1).replace("B",2).replace("C",1).replace("0",0).replace("D",2).replace("E",2).replace("F",1)
ここで一度trainを見てみましょう。 一応全て数字になりました。ここからは、さらに生存予測の精度を高めるために新たな変数を追加していきます。 FamilySizeとIsAloneです。なぜなら一緒に乗船している人数によって生存に大きく差が出るからです。ここまででまだ使われていないものはPclass、SibspとParchです。Pclassは何等級のところに乗っていたかを表すものなのでこのままでいいです。Sibspは乗っていた夫婦と兄弟の人数を表したものです。Parchは乗っていた親と子供の人数を表したものです。よってSibsp+Parch+1がFamilySizeとなります。また、FamilySizeが1だとIsAlone一人で乗っているかどうかが1となります。
train.head(10)
train["FamilySize"] = train["SibSp"] + train["Parch"] + 1 for train in combine1: train['IsAlone'] = 0 train.loc[train['FamilySize'] == 1, 'IsAlone'] = 1
ここまででtrainの処理は終わりました。次に、trainのデータを機械学習にかけるために加工します。はじめにtrainの値だけを取り出し、次にそれを正解データと学習用のデータに分けます。
train_data = train.values xs = train_data[:, 2:] # Pclass以降の変数 y = train_data[:, 1] # 正解データ
次に、testの処理をしていきたいと思います。ほぼtrainと一緒のことをします。ですが気をつけなければいけないことがあります。testのデータをみてみましょう。
test.info()
<class ‘pandas.core.frame.DataFrame’>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId 418 non-null int64
Pclass 418 non-null int64
Name 418 non-null object
Sex 418 non-null int64
Age 332 non-null float64
SibSp 418 non-null int64
Parch 418 non-null int64
Ticket 418 non-null object
Fare 417 non-null float64
Cabin 91 non-null object
Embarked 418 non-null int64
dtypes: float64(2), int64(6), object(3)
memory usage: 36.0+ KB