LoginSignup
308
381

More than 3 years have passed since last update.

一から始める機械学習(Kaggleで学ぶ機械学習)

Last updated at Posted at 2017-09-03

このページの対象読者、目的

対象読者

・機械学習の概要がわかっている方 
・もしくは一から始める機械学習(機械学習概要)を読んだ方が対象です

目的

 ・Kaggleについて理解する
 ・機械学習について実際の流れを理解する
 ・Kaggleのチュートリアルを用いて実践を行う
 ・scikit-learnを用いて実践を行う

アジェンダ

  1. Kaggleとは
  2. なぜKaggle?
  3. Kaggleチュートリアル(Titanic: Machine Learning from Disaster)
  4. データの中でどれを使う?
  5. データ前処理
  6. 使用データ
  7. 使用する学習手法
  8. 学習実行と交差検証
  9. 最適化
  10. 機械学習の流れ
  11. 企業のコンテストを一部紹介

このページはプレゼンテーションを再編集したものです。
オリジナルであるプレゼンテーションをみたい方はこちらをどうぞ
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)

kaggle_titanic1.png

実行コード
train_corr = train.corr()
train_corr

kaggle_titanic3.png

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

kaggle_titanic.png

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分割)、
それぞれで評価することで精度を安定させる方法です

一から始める機械学習(Kaggleで学ぶ機械学習)__Machine_learning_to_learn_at_Kaggle_key.png

実行コード
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位まで行きました。

Titanic__Machine_Learning_from_Disaster___Kaggle.png

データ前処理変更による最適化

先程のコードを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位まで行きました。

Titanic__Machine_Learning_from_Disaster___Kaggle2.png

さらなる最適化の案

・名前の解析をする。(Mr. Mrs. Miss等があるためここから推測できないか等)

kaggle_titanic1.png

・別の学習手法を使用する(例えばXGBoost、LightGBM)を使用する

10. 機械学習の流れ

一から始める機械学習(Kaggleで学ぶ機械学習)__Machine_learning_to_learn_at_Kaggle_key2.png

手法選択はアルゴリズム チートシート

Choosing_the_right_estimator_—_scikit-learn_0_19_0_documentation.png

ハイパーパラメータ選択

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

308
381
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
308
381