fantom_zona’s diary

合成生物学(と最近では神経変性疾患)

KaggleのTitanicにトライしてみた話

右も左も分からない人間が、kaggleに挑戦してみた話です。

とりあえず登録してこのページに行ってtrain.csv, test.csvをダウンロード。
train.csvで予測モデルを構築して、test.csvを予想して提出という形。
とりあえず色々データを覗いてみる。

import pandas as pd 
import matplotlib.pyplot as plt
%matplotlib inline

train=pd.read_csv("./Titanic/train.csv")
train.head(20)

こんな感じに先頭の20個を表示してみると、Cabinに欠損値が多いことが分かる。Name、Sex、Ticket、Cabin、Embarkedは数値じゃないので、捨てるか数値に変換したい。
f:id:fantom_zona:20180321042244p:plain

ヒストグラムにしてもう少し覗いてみる前に、SexとEmbarkedを数値に変換して、Name、Ticket、Cabinのデータは捨てることにする。ヒストグラムにする際には、欠損値はdropna()で落としておく。

train.replace({"male": 0, "female": 1}, inplace=True);
train.replace({"Q": 0, "S": 1, "C": 2}, inplace=True);
train.drop(["Name", "Ticket", "Cabin"], axis=1, inplace=True);

dead_data=train[train.Survived==0]
survived_data=train[train.Survived==1]

plt.hist([dead_data.Age.dropna(), survived_data.Age.dropna()], label=["dead"," survived"])
plt.legend()
plt.titile("age")
plt.show()

plt.hist([dead_data.Fare.dropna(), survived_data.Fare.dropna()], label=["dead"," survived"])
plt.legend()
plt.titile("fare")
plt.show()


plt.hist([dead_data.Embarked.dropna(), survived_data.Embarked.dropna()], label=["dead","survived"])
plt.legend()
plt.titile("embarked")
plt.show()

f:id:fantom_zona:20180321043953p:plainf:id:fantom_zona:20180321044002p:plainf:id:fantom_zona:20180321044011p:plain

欠損値の補完は適当に中央値にしておく。

train.Age.fillna(test.Age.median(), inplace=True);
train.Fare.fillna(test.Fare.median(), inplace=True);
train.Embarked.fillna(1, inplace=True);

今回行う学習は2値分類なので、有名どころのSVMとRandomforestの比較をしてみる。
データをtrain/testに分けたいときは、sklearnのtran_test_splitが便利。
分けたあとは、ラベルと入力を分けて学習させて評価すれば終わり。

import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import svm
from sklearn.metrics import classification_report, accuracy_score

train1, test1=train_test_split(train, test_size=0.2, random_state=None)
train_feature=train1.drop("Survived", axis=1)
train_label=train1.Survived
test_feature=test1.drop("Survived", axis=1)
test_label=test1.Survived

clf = svm.SVC()
clf.fit(train_feature, train_label)
svm_pred=clf.predict(test_feature)
print(classification_report(test_label, svm_pred))
print(accuracy_score(test_label, svm_pred))

rf=RandomForestClassifier()
rf.fit(train_feature, train_label)
rf_pred=rf.predict(test_feature)
print(classification_report(test_label, rf_pred))
print(accuracy_score(test_label, rf_pred))

こちらの手元では、SVMが0.6、RFが0.8弱だったので、RFを採用して提出することにした。

#testデータの前処理
test.replace({"male": 0, "female": 1}, inplace=True);
test.replace({"Q": 0, "S": 1, "C": 2}, inplace=True);
test.drop(["Name", "Ticket", "Cabin"], axis=1, inplace=True);
test.Age.fillna(test.Age.median(), inplace=True);
test.Fare.fillna(test.Fare.median(), inplace=True);
test.Embarked.fillna(1, inplace=True);

rf=RandomForestClassifier()
rf.fit(train.drop("Survived", axis=1), train.Survived)
rf_pred_all=rf.predict(test)

submission = pd.DataFrame()
submission['PassengerId'] = test.PassengerId
submission['Survived'] = rf_pred_all
submission.to_csv('submission.csv', index=False)

が、、、ここまで来てKaggleのページからどうやってsubmitすればいいのか分からなくなった。。。
調べたところ、最近になってKaggleはAPIで提出する形になったようなので仕方なくpip install kaggle。kaggleのページに行って、"My account">"create new api token"に進むと、kaggle.jsonのダウンロードが開始される。homeディレクトリに.kaggleを作成してkaggle.jsonをそこに入れたのち、

!kaggle competitions submit -c titanic -f submission.csv -m "RF all data"

で提出完了!データを落としてくるところもAPIでいけるらしい。ほー。

感想とか。
Embarkを0,1,2にしちゃダメそうな気がしたけど、まあとりあえずやっちゃった感ある。
SVMの精度がめちゃめちゃ悪かったのがなんでなのかよく分からない。ここでは結構精度が出てるので、どこかが変なのかもしれない。
前処理はもっと工夫するべきなんだろうけど、初めてのKaggleということで大目に見てもらいたい。