数年前に、アカウントだけ作成したまま放置していたKaggleに再挑戦することにした。
まずは、下記の書籍を参考に、Titanicの問題にチャレンジしてみる。
Kaggleには、無料の分析環境があると聞いていたが、改めて使ってみると無茶苦茶便利。
とりあえず、Titanicのinputデータを取り込んで、下記のコードで読み取る。
df_train = pd.read_csv('../input/titanic/train.csv')
この本によれば、まずは粗削りでも最後まで実行できる「ベースライン」を作成することが重要で、最初から丁寧に前処理を実行することは推奨していない。
これは、時間に限りのある状況で作業することを考えると非常に納得感のあるものなので、「ベースライン」を作成することを優先。分析で、結果が出ないほど怖いことはないので、精度が低くても最後まで結果を出し、試行錯誤しながら改善することとする。
この辺りの進め方は、人によって流儀があるようだが、本に記載のとおり、データの前処理をすることなく最後まで実行できる「Fare」と「Pclass」を利用して分析を実施。
「ホールドアウト検証」と、「クロスバリデーション」があるようだが、データを無駄にしない「クロスバリデーション」を選択。なんか、カッコよさげだし。
あれ、これって、5個モデル作成しているけど、結局どのモデルを使うんだっけ?
まあ、細かいことは後で確認するとして、とりあえずコミット。
Evaluation Exception: Submission must have 418 rows
ん?エラーが出た。レコード数が違う?確かに、「test.csv」のデータとレコード数が異なる。コードを確認すると、間違えてtrainデータを読み込んだままになっていた。コピペの後に、修正する箇所が足りなかったみたい。
修正して、再度コミット。スコアは0.622。
とりあえず、Ageを追加してみる。
適当に平均値で欠損値を埋めて追加。
df_train["Age"] = df_train["Age"].fillna(df_train["Age"].mean())
スコアが0.68くらいに上昇。
次に、「Embarked」の欠損値を最頻値で埋める。
df_train["Embarked"] = df_train["Embarked"].fillna(df_train["Embarked"].mode())
「Embarked」と「Sex」が文字列なので、ワンホットエンコーディングで数値化してやる。
df_train = pd.get_dummies(df_train, columns=["Sex","Embarked"],dummy_na=True, drop_first=False)
Kaggleの分析環境からだと、ノートブックのコードも一緒にアップロードできるみたい。このスコアがどのコードを利用したかわからなくなることが多いので、非常に便利。
0.765くらいまで、スコアが向上。
「SibSp」は、同乗している兄弟または配偶者の数で、「Parch」は、同乗している親または子どもの数らしい。親が子どもを優先させたり、夫が妻を優先させることがあるかもしれないので、こちらも追加してみたが、若干スコアが下がった。
明日は、標準化と、カラムの追加をしようかな?ハイパーパラメーターの調整も考えた方が良いかも。クロスバリデーションのスコアと比べると、コミット後のスコアが低くなっているので、過学習しているのかも。
あと、クロスバリデーションでランダムでデータを分割したけど、この分割方法は上級者になっても悩むところらしい。正解が少ない場合などに、偏ったデータで学習すると精度に影響がでるとか…
トップの方はスコアが1だけど、これは機械学習の結果ではなく答えを試行錯誤で求めたのではないかとのこと。純粋に機械学習で予測すると、0.8を超えたくらいが限界らしいのでそのあたりを目指すことにしよう。
あと、テーブルデータは推論では、単体のモデルでは、ニューラルネットワークより、決定木などの方が精度が良くなるらしい。ふむふむ。
今日はこれくらいにしておこう。
コメント