kaggleやってみた
背景
データ分析を学んでみようということで社内エンジニアチームでkaggleをやってみようという話になったので軽く触ってみたことを書きます。
準備
始めるに当たってまず準備したのはkaggleのサイトへのユーザー登録と、Pythonとその周りの機械学習ライブラリのセットアップです。
$ brew install python3 pip3 $ pip3 install pandas numpy sklearn
ユーザー登録は以下のサイトからそれっぽいところをクリックしていけばできます。英語のサイトですがFacebook連携もできるので意外と楽。
Kaggle: Your Home for Data Science
とりあえずやってみる
あまり書くことがないのでやったことを一通り書いてみたいと思います。やったのはタイタニックと呼ばれる一番有名っぽいデータセット。
Titanic: Machine Learning from Disaster | Kaggle
Dataと書いてあるタブから、トレーニングデータとテストデータをダウンロードします。
決定木を使う
まずは決定木を使ってやってみます。
データはcsv形式で降ってきているはずなのでpandasでよしなに処理して作成した決定木モデルに流し込みます。
import pandas as pd import numpy as np from sklearn import tree train = pd.read_csv("train.csv") test = pd.read_csv("test.csv") # 欠損しているデータを埋める train["Age"] = train["Age"].fillna(train["Age"].median()) train["Embarked"] = train["Embarked"].fillna("S") train["Sex"][train["Sex"] == "male"] = 0 train["Sex"][train["Sex"] == "female"] = 1 train["Embarked"][train["Embarked"] == "S" ] = 0 train["Embarked"][train["Embarked"] == "C" ] = 1 train["Embarked"][train["Embarked"] == "Q"] = 2 test["Age"] = test["Age"].fillna(test["Age"].median()) test["Sex"][test["Sex"] == "male"] = 0 test["Sex"][test["Sex"] == "female"] = 1 test["Embarked"][test["Embarked"] == "S"] = 0 test["Embarked"][test["Embarked"] == "C"] = 1 test["Embarked"][test["Embarked"] == "Q"] = 2 test.Fare[152] = test.Fare.median() target = train["Survived"].values # 追加となった項目も含めて予測モデルで使う値を取り出す features_two = train[["Pclass","Age","Sex","Fare", "SibSp", "Parch", "Embarked"]].values # 決定木の作成とアーギュメントの設定 max_depth = 10 min_samples_split = 5 my_tree_two = tree.DecisionTreeClassifier(max_depth = max_depth, min_samples_split = min_samples_split, random_state = 1) my_tree_two = my_tree_two.fit(features_two, target) # tsetから使う項目の値を取り出す test_features_2 = test[["Pclass","Age", "Sex", "Fare", "SibSp", "Parch", "Embarked"]].values # 決定木を使って予測をしてCSVへ書き出す my_prediction_tree_two = my_tree_two.predict(test_features_2) PassengerId = np.array(test["PassengerId"]).astype(int) my_solution_tree_two = pd.DataFrame(my_prediction_tree_two, PassengerId, columns = ["Survived"]) my_solution_tree_two.to_csv("my_tree.csv", index_label = ["PassengerId"])
Submit Predictionを押して解答のCSVをサブミットしてみたところ、正答率は75%程度でした。
トレーニングデータの中身を見てみたところ、年齢欄の欠損が多かったので、年齢を説明変数から削除して再度予測してみた結果、正答率が76%と微増しました。
ランダムフォレストを使う
ソースコードを軽くいじって、予測モデルにランダムフォレストを使ってみます。
import pandas as pd import numpy as np from sklearn.ensemble import RandomForestClassifier train = pd.read_csv("train.csv") test = pd.read_csv("test.csv") train["Age"] = train["Age"].fillna(train["Age"].median()) train["Embarked"] = train["Embarked"].fillna("S") train["Sex"][train["Sex"] == "male"] = 0 train["Sex"][train["Sex"] == "female"] = 1 train["Embarked"][train["Embarked"] == "S" ] = 0 train["Embarked"][train["Embarked"] == "C" ] = 1 train["Embarked"][train["Embarked"] == "Q"] = 2 test["Age"] = test["Age"].fillna(test["Age"].median()) test["Sex"][test["Sex"] == "male"] = 0 test["Sex"][test["Sex"] == "female"] = 1 test["Embarked"][test["Embarked"] == "S"] = 0 test["Embarked"][test["Embarked"] == "C"] = 1 test["Embarked"][test["Embarked"] == "Q"] = 2 test.Fare[152] = test.Fare.median() target = train["Survived"].values features = train[["Pclass","Sex","Fare", "SibSp", "Parch", "Embarked"]].values clf = RandomForestClassifier() clf.fit(features, target) test_features = test[["Pclass", "Sex", "Fare", "SibSp", "Parch", "Embarked"]].values test_pred = clf.predict(test_features) PassengerId = np.array(test["PassengerId"]).astype(int) my_solution = pd.DataFrame(test_pred, PassengerId, columns = ["Survived"]) my_solution.to_csv("rf.csv", index_label = ["PassengerId"])
解答を提出しましたが、正答率は75%程度でした。
SVMを使う
今度は予測モデルにサポートベクターマシンを利用してみます。
import pandas as pd import numpy as np from sklearn import svm train = pd.read_csv("train.csv") test = pd.read_csv("test.csv") train["Age"] = train["Age"].fillna(train["Age"].median()) train["Embarked"] = train["Embarked"].fillna("S") train["Sex"][train["Sex"] == "male"] = 0 train["Sex"][train["Sex"] == "female"] = 1 train["Embarked"][train["Embarked"] == "S" ] = 0 train["Embarked"][train["Embarked"] == "C" ] = 1 train["Embarked"][train["Embarked"] == "Q"] = 2 test["Age"] = test["Age"].fillna(test["Age"].median()) test["Sex"][test["Sex"] == "male"] = 0 test["Sex"][test["Sex"] == "female"] = 1 test["Embarked"][test["Embarked"] == "S"] = 0 test["Embarked"][test["Embarked"] == "C"] = 1 test["Embarked"][test["Embarked"] == "Q"] = 2 test.Fare[152] = test.Fare.median() target = train["Survived"].values features = train[["Pclass","Age","Sex","Fare", "SibSp", "Parch", "Embarked"]].values clf = svm.SVC() clf.fit(features, target) test_features = test[["Pclass","Age", "Sex", "Fare", "SibSp", "Parch", "Embarked"]].values test_pred = clf.predict(test_features) PassengerId = np.array(test["PassengerId"]).astype(int) my_solution = pd.DataFrame(test_pred, PassengerId, columns = ["Survived"]) my_solution.to_csv("svm.csv", index_label = ["PassengerId"])
こちらの正答率はなんと60%台でした。。。
まとめ
kaggleのタイタニックデータセットを軽くいじってみましたが、なかなか正答率が上がらず大変です。このデータセットに限って言えば、モデルよりはデータの前処理が大変に感じました。少し触れましたが、年齢欄や乗船地の欠損が多かったですし、それらをどのように扱えば高い正答率が得られるかというのは、経験に基づくところがあるのではないかと思います。