Kaggle

Kaggle|訓練データ・テストデータの結合と切り離しの仕方を解説

・Kaggleのtitanicをちょうどやり始めたけど、train.csvとtest.csvの結合の仕方が分からない
・最後にtest.csvの部分だけをKaggleに提出しないといけないけど、どうやったらtest.csv部分だけ切り離せるのかな

このような疑問を持つ方も多いのではないでしょうか。

実際、私は昨年Kaggleを始めた際にここにかなりの時間を割きました。

本記事をお読みいただくと、以下が分かります。

ポイント

・Kaggleでのtrain.csv(訓練用のデータ)とtest.csv(提出用のためのデータ)の結合の仕方が分かる

・最後にtest.csvだけを結合したデータから切り離して、Kaggleにsubmitするやり方が分かる

 

本記事の目次は以下の通りです。

①Kaggleコンペのsubmitまでのフロー

②train.csvとtest.csvの結合から、test.csvだけをKaggleにsubmitする一連の流れ

 

そもそもtrain.csvとtest.csvの違いがわからない・・という方は以下も併せてお読みください。

機械学習の訓練データとテストデータをわかりやすく解説

  機械学習に興味を持ち、いざkaggleに挑戦!と思ったのに、下記で困ることはないでしょうか。 機械学習でよく言われる「訓練データ」と「テストデータ」の違いがよくわからない・・ kaggl ...

続きを見る

①Kaggleコンペのsubmitまでのフロー

もちろんやり方はいくつもあるので絶対このやり方でないといけないということはないのですが、以下のSTEP1~4のやり方がわかりやすいと思います。

今回はKaggleのtitanicを例に全体像をお見せした後、各STEPについて解説していきます。

STEP1:train.csvとtest.csvの結合

下の図を見ながら、説明をお読みください。

・まずtrain.csvとtest.csvを結合し、dfという変数に格納します(下の図の赤枠

・結合のタイミングで、どの行がtrain.csv/test.csvだったかを後から判断するために、「TrainFlag」という列をつけておきます。
dfの一番右の列
※train.csvの行にTrue,test.csvの行にFalseを入れておく

※下記の図にあるtarget列がいわゆる目的変数で、titanicでいうと「Survived」列にあたります。

※「aaa」「bbb」「ccc」がいわゆる説明変数で、titanicでいうと「Age」「Pclass」などにあたります。

STEP2:dfに対して前処理等、必要な処理を実施

STEP3:訓練データ(train.csv)でモデル構築

STEP2,3はまとめて図示します。必要な前処理を行ったうえで(STEP2)、訓練データ(train.csv)だけ切り離し、モデル構築を行います(STEP3)。

STEP1でtrain.csvとtest.csvを結合しておかないと、同じ前処理をtrain.csvとtest.csv双方に行わないといけないため手間ですし、対応漏れが発生しやすいです。

STEP4:test.csvをモデルに読み込ませ、予測結果を出力

STEP3までで構築したモデルにdfから切り離したtest.csvを読み込ませ、予測結果を出力させます。

その後KaggleへSubmitして、終了です。

train.csvとtest.csvの結合から、test.csvだけをKaggleにsubmitする一連の流れ

本題に入る前に、必要なものをインポートし、データを読み込みましょう。

(1)必要なもののインポート

 command
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import math

(2)データの読み込み

 command
df_train = pd.read_csv("train.csv")
df_test = pd.read_csv("test.csv")

STEP1:train.csvとtest.csvの結合

こちらの部分です。

(1)train.csvとtest.csvにTrainFlagを付ける

図で示したように「TrainFlag」列を追加し、df_trainのデータはTrue,df_testのデータはFalseを入れておきます。

 command
df_train["TrainFlag"] = True
df_test["TrainFlag"] = False

(2)train.csvとtest.csvの結合

 command
df = df_train.append(df_test)

このようにtrain.csvとtest.csvを結合し、dfというデータフレームを設定します。

(3)提出の際に必要となる列(titanicでいうとPassengerID)をindexにして、通常の列からは削除

大抵、何らかのIDに予測結果を付与してSubmitすることが多いです。
このID,例えばtitanicでいうところのPassengerIDモデル予測には使いませんが最後の提出では絶対必要になるので、PassengerIDの情報をdfに持っておく必要があります

そのために、提出の際に必要なカラムは「indexにしておく」ことをお勧めします

 command
#データフレームのindexをPassengerIDにしておく
df.index = df["PassengerId"]
#その上で、PassengerID列を削除
df.drop("PassengerId", axis = 1, inplace = True)

 

dfを見てみましょう。

PassengerIDがindexに入っていますね。
図には載せていないですが、df全体からはPassengerID列は消えています。
こうすることでモデルの訓練にPassengerIDを使わなくてすみ、かつPassengerIDの情報をdfに保持させたまま進めていくことができます

STEP2:dfに対して前処理等、必要な処理を実施

下の図のSTEP2部分(”必要な前処理をdf全体に実施”)です。

今回は精度は気にせず進めていきますので、他にもやりようはありますが、一旦必要な最低限の処理をしていきます。

本記事ではSTEP2自体は主旨から外れるので、STEP2の内容がわからなくても気にせず読み進めてください。

(1)欠損値処理

説明変数として使用するAgeとEmbarkedは欠損値補完をしておきます。
※厳密にはAgeはtest.csvのデータも含まれた「df」の平均で補完しない方がいい考えもあるのですが、今回は本論から外れるのと、不要にテキストを増やさない意図でまとめて処理をしています。

 command
df["Age"] = df["Age"].fillna(df["Age"].median())
df["Embarked"] = df["Embarked"].fillna("S")

(2)カテゴリ変数処理

 command
df = pd.get_dummies(df, columns = ["Sex", "Embarked"])

(3)不要列の削除

今回のモデルでは使わない変数を削除します。

 command
df = df.drop(['Cabin','Name','Ticket', 'Fare'], axis = 1)

STEP3:訓練データ(train.csv)でモデル構築

下の図のSTEP3です。

(1)dfから訓練データを切り離す

冒頭で紹介した図の赤枠のdfに対して必要な前処理がtrain.csvとtest.csvに対して終わりました。

ここから、実際にモデルを作るために、train.csv部分だけを切り離します。

そう、ここでTrainFlagが役に立ちます。

 command
#TrainFlag列がTrueの行をdf_trainとして再定義
df_train = df[df["TrainFlag"] == True]
#その上でTrainFlag列を削除(もう使わないため)
df_train= df_train.drop(["TrainFlag"], axis = 1)

(2)dfからテストデータを切り離す

(1)同様、テストデータもdfから切り離しておきます。

 command
df_test = df[df["TrainFlag"] == False]
df_test = df_test.drop(["TrainFlag"], axis = 1)
#df_testには目的変数のSurvied列は不要(元からなかった)なので、削除
df_test = df_test.drop(["Survived"], axis = 1)

(3)訓練データでモデル構築(今回はランダムフォレストを使います)

(1)で切り離したtrain.csvのデータをさらに訓練データとテストデータに分割し、モデル構築を行います。
※今回はテストデータでの精度検証は行っていません。

 command
y = df_train["Survived"].values
X = df_train.drop("Survived", axis=1).values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1234)
clf = RandomForestClassifier(random_state=1234)
clf.fit(X_train,y_train)

STEP4:test.csvをモデルに読み込ませ、予測結果を出力

最後に、STEP4です。

(1)df_testで予測を行う

 command
prediction_RF = clf.predict(df_test)

(2)提出できる形式にする

ここで、最初にPassengerIDをindexにしていたことが生きてきます。

PassengerIDのデータを持っていないと、ここで行き詰ります。
(私は人生初Kaggleの際、ここで詰みました。PassengerIDを冒頭で消していました・・)

 command
#df_test.indexで、PassengerIDを呼び出している
submission = pd.DataFrame({"PassengerId": df_test.index, "Survived": prediction_RF})
#予測結果がfloat(小数点)になり、submitしても精度が0になってしまうため、ここでintにしておく。
#(submissionをDataFrameにしているのでこの問題が起こるようです)
submission["Survived"] = submission["Survived"].astype(int)

(3)提出ファイルの出力

 command
submission.to_csv("submission.csv", index = False)

以上で終了です、お疲れさまでした!

私は初めてKaggleに挑戦した際、今回の記事の内容をわかっておらず、Google検索等して1つずつ解消していきました。

ただ、かなり遠回りをしてしまったので、本記事をお読み頂いた方は是非本題の「データ分析」「モデル構築」にしっかり時間を充てていただけると嬉しいです。

最後までお読み頂き、ありがとうございました。

最後に・・・

Kaggleについて以下の記事も書いておりますので、よろしければ参考にしてみてください。

初心者向け|おすすめのKaggle本と使い方を解説

  ・何となくKaggleを始めてみたけど、機械学習の全体像が分からない ・とりあえず欠損値処理と簡単なコードを書いてsubmitしてみたけど、この後どう勉強を進めていけばいいんだろう こん ...

続きを見る

 

Kaggle titanicの次に取り組むコンペの探し方

機械学習を少し勉強して、「Kaggleのtitanicコンペ」には一旦submitしてみた。 さて、次は何をすればいいんだろうか・・・まだ全然機械学習のことわからないな・・・。 こう思っている方は多い ...

続きを見る

-Kaggle

© 2021 データサイエンス はじめの一歩 Powered by AFFINGER5