チュートリアル第2部「機械学習 with scikit-learn」
PyData Tokyoオーガナイザーの田中(@atelierhide)です。
第2部では、scikit-learnを使った機械学習のチュートリアルを行いました。このチュートリアルで次の2点を学びます。
- 機械学習を使った分類モデルの生成
- 分類結果の検証
チュートリアルの資料は、こちらから確認いただけます。なお、コードを実行する際、ライブラリのバージョンによってはエラーが出ることがありますので注意してください。
この記事では、Kaggleに実際にデータをアップロードするまでの手順を紹介します。これがきっかけでKaggleの参加者であるKagglerになる人が増えることを期待しています!
訓練データとテストデータ
第1部では、Kaggleからダウンロードした訓練データのみ(train.csv)を使いましたが、第2部ではテストデータ(test.csv)も使います。訓練データは、乗客の生存情報(正解データ)が付いているもので、機械学習のモデル作成に使います。一方、テストデータには生存情報が付いていません。訓練データを使って、テストデータに対する生存情報を予測することが、このコンペの目的です。
先ず、Pandasのデータフレームに2つのデータを読み込みます。
import pandas as pd df_train = pd.read_csv('data/train.csv') df_test = pd.read_csv('data/test.csv')
2つのデータを確認してみましょう。df_trainにのみ生存情報(Survived)があるのが分かります。
女性は全員生存したと仮定する「ジェンダーモデル」
第1部のデータ可視化で、男性に比べて、女性の生存率が高いことが分かりました。タイタニック沈没事故は、2224人の乗客と乗組員のうち1502人が亡くなる大事故でしたが、これほど多くの犠牲者を生んだ一つの理由は救助ボートが十分に用意されていなかったこととされています。男性が、女性を助けるために、救命ボートに優先的に誘導したということが推測できます。そこで、この仮説に基づいて1つ目のモデルを作成しましょう。
訓練データから性別データと乗客の生存情報を取り出します。特徴量はx、正解データはyと表すことが一般的です。ここでは、特徴量が性別、正解データは生存情報です。
x = df_train['Sex'] y = df_train['Survived']
次に、特徴量xを使って、生存情報を予測します。生存は1、死亡は0と定義されているので、Pandasのmapを使って、女性は1、男性は0になるように計算します。y_predのpredは予測を表すpredictionの略です。
y_pred = x.map({'female': 1, 'male': 0}).astype(int)
予測値の評価
機械学習では、作成したモデルを事前に評価することが重要です。ジェンダーモデルにより予測したy_predを正解データであるyと比較してみましょう。比較する際の評価指標はさまざまなものがあり、取り組む課題によって最適なものが選択されますが、このコンペでは正解率(Accuracy)という指標が使われています。正解率はscikit-learnのaccuracy_scoreで計算します。
from sklearn.metrics import accuracy_score print('Accuracy: {:.3f}'.format(accuracy_score(y, y_pred)))
この出力は「Accuracy: 0.787」です。単純なモデルで78.7%という高い正解率が得られました。これは、事前にデータをしっかりと把握し、仮説に基づいたモデルを立てることが重要であることを示すとても良い例です。
また、予測結果を理解するためにとても便利な混同行列(Confusion Matrix)もscikit-learnのconfusion_matrixで簡単に計算できます。
from sklearn.metrics import confusion_matrix cm = confusion_matrix(y, y_pred)
結果はmatplotlibで可視化すると、さらに分かりやすくなります。
![Confusion Matrix](http://cz-cdn.shoeisha.jp/static/images/article/8636/8636_11.gif)
Kaggleに投稿するファイルの作成
トレーニングデータと同様に、テストデータからも生存者を予測しましょう。
x_test = df_test['Sex'] y_test_pred = x_test.map({'female': 1, 'male': 0}).astype(int)
次に、予測した結果を、Kaggleに投稿するためのCSVファイルを作成します。CSVファイルに記載すべきデータは、コンペごとに決められており、サイトに説明があります。今回は、PassengerIdとSurvived(生存者の予測値)が必要なデータです。Pandasで投稿データ用のDataFrameを作成し、to_csvを使ってCSV形式で保存します。
df_kaggle = pd.DataFrame({'PassengerId': df_test['PassengerId'], 'Survived':np.array(y_test_pred)}) df_kaggle.to_csv('kaggle_gendermodel.csv', index=False)
作成したkaggle_gendermodel.csvをKaggleに投稿し、スコアと順位を確認してみましょう。これで皆さんもKagglerの仲間入りです!
3行のコードで終わる機械学習
次に、scikit-learnに実装されている機械学習のアルゴリズムの使い方について紹介します。チュートリアルでは、新たな仮説を立て、性別情報だけでなく年齢などの特徴量を使いましたが、ここでは特徴量選択の詳細は割愛し、訓練データの特徴量をX、正解データをy、テストデータをX_testと表します。
scikit-learnによる機械学習は誰にでも簡単に行えます。以下のように、必要なアルゴリズム(ここではロジスティック回帰)をインポートした後、テストデータに対する予測値を求めるまでに必要なコードはたった3行です。
from sklearn.linear_model import LogisticRegression clf = LogisticRegression() # モデルの定義 clf.fit(X, y) # 訓練データの特徴量と正解データによる学習 y_test_pred = clf.predict(X_test) # テストデータに対する生存情報の予測
タイタニックデータは、データ数も少ないため、学習も予測もあっという間に終わります。
たった3行のコードで良い結果が得られるか?
scikit-learnを使えば、たった3行のコードでテストデータに対する生存情報の予測を行えることを示しましたが、簡単に良い結果が得られるでしょうか? 答えは「ノー」です。アルゴリズムは「魔法」ではありません。データを見て、仮説を立て、その上で実際の結果を検証するというプロセスがいかに大切かはKaggleに参加すると良く分かります。
チュートリアルの資料では、より良い結果を得るために以下の手法を紹介していますので、Kaggleで上位を目指すための参考してください。
-
モデルの理解と比較
→ ロジスティック回帰、SVM、決定木 -
モデルの評価
→ 訓練データの分割、交差検証(クロスバリデーション) -
モデルパラメータの最適化
→ グリッドサーチ
学びの場としてのKaggle
私がこれまで参加した中で最も面白かったKaggleのコンペで、「Dogs vs. Cats」というものがあります。お題はとてもシンプルで、犬と猫の画像を分類するアルゴリズムを作るというものでした。このコンペは、いま最も熱い技術であるディープラーニング(深層学習)に関わる世界トップレベルの研究者が議論しながら、技術を競い合うという、ものすごいものでした。私のスコアでは上位は程遠いという結果でしたが、コンペを通してたくさんのことを学びました。Kaggleは最高の学びの場だと思っています。そして、同様の感想は他のKagglerからも挙がっています。
機械学習に興味があるけれども、始めるきっかけがないというお話を聞くことがあります。Kaggleをきっかけとして、機械学習を始めてみるのはいかがでしょうか?