このページの対象読者、目的
対象読者
・機械学習の概要がわかっている方
・もしくは一から始める機械学習(機械学習概要)を読んだ方が対象です
目的
・Kaggleについて理解する
・機械学習について実際の流れを理解する
・Kaggleのチュートリアルを用いて実践を行う
・scikit-learnを用いて実践を行う
アジェンダ
- Kaggleとは
- なぜKaggle?
- Kaggleチュートリアル(Titanic: Machine Learning from Disaster)
- データの中でどれを使う?
- データ前処理
- 使用データ
- 使用する学習手法
- 学習実行と交差検証
- 最適化
- 機械学習の流れ
- 企業のコンテストを一部紹介
このページはプレゼンテーションを再編集したものです。
オリジナルであるプレゼンテーションをみたい方はこちらをどうぞ
https://www.edocr.com/v/vlzyelxe/tflare/Kaggle_-Machine-learning-to-learn-at-Kaggle
1. Kaggleとは
誤解を恐れずにまとめれば
「Kaggleは企業や研究家が、データサイエンス、機械学習関連のお題をだしてそれを解くサイトです。賞金がつくものもあり(さらにそれを解くためのコードを公開しかつ説明する。その説明についてコメント等でコミュニケーションを行う機能もあり)
2. なぜKaggle?
・本などの説明では、説明のためのデータセットが使われていることが多く、実感が湧きにくい。
・本などの説明では端折られる箇所も、実施する必要があるため機械学習の実際の流れが理解できる。
・順位が出るためやる気が出る。(全世界のデータ分析家と勝負できますし、協力もできます)
・賞金がでます(150万ドルの賞金が出るものもあり)
3. Kaggleチュートリアル(Titanic: Machine Learning from Disaster)
・乗客がタイタニックの沈没を生き延びたかどうかを予測
・訓練用データ(891行 × 12列のcsv) データに一部欠損あり
・テストデータ(418行 × 11列のcsv) データに一部欠損あり
・訓練用データで学習し、テストデータに対して、生き延びたかどうかを予測する。
4. データの中でどれを使う?
・PassengerId:データにシーケンシャルでついている番号
・Survived:生存(0 = No, 1 = Yes) 訓練用データにのみ存在
・Pclass:チケットのクラス(1 = 1st, 2 = 2nd, 3 = 3rd)
・Name:名前
・Sex:性別
・Age:年齢
・SibSp:タイタニック号に乗っていた兄弟と配偶者の数
・Parch:タイタニック号に乗っていた両親と子どもの数
・Ticket:チケット番号
・Fare:旅客運賃
・Cabin:船室番号
・Embarked:乗船場(C = Cherbourg, Q = Queenstown, S = Southampton)
import numpy as np
import pandas as pd
train = pd.read_csv("train.csv", dtype={"Age": np.float64}, )
test = pd.read_csv("test.csv", dtype={"Age": np.float64}, )
train.head(10)
train_corr = train.corr()
train_corr
5. データ前処理
PassengerId以外は使えそうです。
現在解析に使えていないデータがあるので使えるデータ(数値)に変換します。
また欠損データがあるので補正します。
def correct_data(titanic_data):
titanic_data.Age = titanic_data.Age.fillna(titanic_data.Age.median())
titanic_data.Sex = titanic_data.Sex.replace(['male', 'female'], [0, 1])
titanic_data.Embarked = titanic_data.Embarked.fillna("S")
titanic_data.Embarked = titanic_data.Embarked.replace(['C', 'S', 'Q'], [0, 1, 2])
titanic_data.Fare = titanic_data.Fare.fillna(titanic_data.Fare.median())
return titanic_data
train_data = correct_data(train)
test_data = correct_data(test)
train_corr = train.corr()
train_corr
6. 使用データ
今回は以下項目を使用します。
・チケットのクラス
・性別
・年齢
・タイタニック号に乗っていた兄弟と配偶者の数
・タイタニック号に乗っていた両親と子どもの数
・旅客運賃
・乗船場
7. 使用する学習手法
・ロジスティック回帰
・サポートベクターマシン
・k-最近傍法
・決定木
・ランダムフォレスト
・ニューラルネットワーク
参考文献
学習手法の詳細は以下を参照ください。
Pythonではじめる機械学習 scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
https://www.oreilly.co.jp/books/9784873117980/
8. 学習実行と交差検証
データと学習手法を指定します。
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC, LinearSVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import cross_val_score
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
models = []
models.append(("LogisticRegression",LogisticRegression()))
models.append(("SVC",SVC()))
models.append(("LinearSVC",LinearSVC()))
models.append(("KNeighbors",KNeighborsClassifier()))
models.append(("DecisionTree",DecisionTreeClassifier()))
models.append(("RandomForest",RandomForestClassifier()))
models.append(("MLPClassifier",MLPClassifier(solver='lbfgs', random_state=0)))
交差検証を実施します。
交差検証ではデータセットを訓練データとテストデータに分割し(ここでは3分割)、
それぞれで評価することで精度を安定させる方法です
results = []
names = []
for name,model in models:
result = cross_val_score(model, train_data[predictors], train_data["Survived"], cv=3)
names.append(name)
results.append(result)
3分割されている結果を平均し、評価を出します。
ランダムフォレストが良い結果を出しました。
for i in range(len(names)):
print(names[i],results[i].mean())
LogisticRegression 0.785634118967
SVC 0.687991021324
LinearSVC 0.58810325477
KNeighbors 0.701459034792
DecisionTree 0.766554433221
RandomForest 0.796857463524
MLPClassifier 0.785634118967
ランダムフォレストで学習したものを元に、
テストデータで予想をし、その結果をcsvにして送ります。
alg = RandomForestClassifier()
alg.fit(train_data[predictors], train_data["Survived"])
predictions = alg.predict(test_data[predictors])
submission = pd.DataFrame({
"PassengerId": test_data["PassengerId"],
"Survived": predictions
})
submission.to_csv('submission.csv', index=False)
9. 最適化
正解率
正解率0.74163
7922人中7043位でした。ちょっと悔しいので最適化します。
最適化
grid searchを使用すればハイパーパラメータを自動的に最適化してくれます。
ただし実行時間がかかることに注意して下さい。
parameters = {
'n_estimators' : [5, 10, 20, 30, 50, 100, 300],
'max_depth' : [3, 5, 10, 15, 20, 25, 30, 40, 50, 100]
'random_state' : [0],
}
gsc = GridSearchCV(RandomForestClassifier(), parameters,cv=3)
gsc.fit(train_data[predictors], train_data["Survived"])
上記等で最適化した結果を適応してみます。
正解率0.77990
7922人中4129位まで行きました。
データ前処理変更による最適化
先程のコードをKaggleに公開するとコメントがつきました。
欠損値を訓練用データからではなくテストデータから求めるようにしたほうが良いとのことでした。やってみました。
修正後のコードを以下に記載します。
def correct_data(train_data, test_data):
# Make missing values for training data from test data as well
train_data.Age = train_data.Age.fillna(test_data.Age.median())
train_data.Fare = train_data.Fare.fillna(test_data.Fare.median())
test_data.Age = test_data.Age.fillna(test_data.Age.median())
test_data.Fare = test_data.Fare.fillna(test_data.Fare.median())
train_data = correct_data_common(train_data)
test_data = correct_data_common(test_data)
return train_data, test_data
def correct_data_common(titanic_data):
titanic_data.Sex = titanic_data.Sex.replace(['male', 'female'], [0, 1])
titanic_data.Embarked = titanic_data.Embarked.fillna("S")
titanic_data.Embarked = titanic_data.Embarked.replace(['C', 'S', 'Q'], [0, 1, 2])
return titanic_data
train_data, test_data = correct_data(train, test)
正解率0.79426
7922人中2189位まで行きました。
さらなる最適化の案
・名前の解析をする。(Mr. Mrs. Miss等があるためここから推測できないか等)
・別の学習手法を使用する(例えばXGBoost、LightGBM)を使用する
10. 機械学習の流れ
手法選択はアルゴリズム チートシート
ハイパーパラメータ選択
grid search
モデルの評価
交差検証
11. 企業のコンテストを一部紹介
Prudential Life Insurance Assessment
・Can you make buying life insurance easier?
・生命保険申請者の属性からリスクレベルを算出する
・賞金3万ドル
・既に終了済み(コードが参照できる)
・https://www.kaggle.com/c/prudential-life-insurance-assessment
Zillow Prize: Zillow’s Home Value Prediction (Zestimate)
・Can you improve the algorithm that changed the world of real estate?
・自宅のすべての機能を考慮して、Zestimateと実際の販売価格との間の誤差を予測する
・賞金120万ドル
・4ヶ月後に終了
・https://www.kaggle.com/c/zillow-prize-1