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は数値じゃないので、捨てるか数値に変換したい。
ヒストグラムにしてもう少し覗いてみる前に、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()
欠損値の補完は適当に中央値にしておく。
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ということで大目に見てもらいたい。