機械学習を使用したいです。
このような要望にお応えします。
今回は、データに対して決定木ブースティング手法を用いて、ワインの種類を分類するモデルを構築し学習、評価を行いたいと思います。
決定木ブースティング手法としては、LightGBMと呼ばれる決定木アルゴリズムに基づいたブースティング手法の機械学習フレームワークを利用します。
LightGBMを使用して分類問題を解きますが、回帰問題に対応することもできます。また、GPUを使用してさらに高速化することもできます。この特性からKaggle等のデータ分析コンペで頻繁に使用されています。
決定木ブースティングとは
決定木ブースティングについて整理します。
決定木
決定木は木構造モデルで表現され、分類や回帰問題を扱うことができる機械学習手法の一つです。分類時には分類木、回帰問題では回帰木と呼ばれたりもします。
また決定木は、データ分析の過程を比較的容易に解釈することができます。該当の木構造内の葉が分類結果を表現し、枝がその分類にに至るまでの情報を保持するため、何をもって分類されたのかを確認することができる。
分類木であれば、どの要素により分類されたのか、回帰木であればどの要素が予測値に影響を与えるのかといったことが可視化できる。また、数値だけではなくカテゴリデータを扱うことができます。
ただし、決定木は学習を実施することで学習データに過剰適合したモデルになりやすい傾向にあります。そこで、アンサンブル学習を利用したランダムフォレストやブースティング法などが使用されています。
ランダムフォレストについて、気になる方は以下の記事を参照ください。
アンサンブル学習
アンサンブル学習は、複数の学習モデルを融合させて一つの学習モデルを生成する手法です。そして、アンサンブル学習のひとつとしてブースティング手法があります。ブースティングでは前のモデルの学習結果を次のモデル学習に反映させるという特徴があります。
先程挙げたランダムフォレストはバギングと呼ばれるアンサンブル学習を利用した手法です。並列的にモデルを学習させ、各々のモデルの結果を参考にして多数決決定するようなイメージになります。
このように、決定木およびブースティング手法を組み合わせた手法をLightGBMで利用することができます。
それでは、LightGBMを使用してみます。
Google Colaboratoryの準備
・Googleのアカウントを作成します。
・Googleドライブにアクセスし、「新規」→「その他」から「Google Colaboratory」の順でクリックします。そうすると、Colaboratoryが起動します。
・Colaboratoryが起動したら、以下のコマンドをCoalboratoryのセルに入力し実行します。
そうすることで、Googleドライブをマウントします。
1 2 |
from google.colab import drive drive.mount('/content/drive') |
・実行後、認証コードの入力が促されます。このとき、「Go to this URL in a browser」が指しているURLにアクセスしgoogleアカウントを選択すると、認証コードが表示されますので、それをコピーしenterを押します。これでGoogleドライブのマウントが完了します。
LightGBMの準備
Google Colaboratoryを実行環境として利用する場合は、すでに導入されていますので特別な準備は必要ありません。それでは進めます。
モデル学習用データと検証用データの準備
ワインデータを読み込み、学習用データと検証用のデータに分割します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import numpy as np import pandas as pd import matplotlib.pyplot as plt import lightgbm as lgb from sklearn.metrics import confusion_matrix from sklearn.metrics import accuracy_score from sklearn.datasets import load_wine from sklearn.model_selection import train_test_split data = load_wine() x_data = data['data'] label_data = data['target'] x_train, x_test, y_train, y_test = train_test_split(x_data, label_data, test_size=0.2) train_set = lgb.Dataset(x_train, y_train) test_set = lgb.Dataset(x_test, y_test, reference=train_set) |
これでデータの準備は完了です。
モデル定義、学習、評価
モデルパラメータを以下のように設定し、学習とモデル評価を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
lgb_params = { 'boosting_type' : 'gbdt', 'objective' : 'multiclass', 'metric' : 'multi_logloss', 'num_class' : 3, 'num_leaves' : 40, 'learning_rate' : 0.05, 'feature_fraction' : 0.9, 'bagging_fraction' : 0.8, 'bagging_freq' : 0 } lgb_model = lgb.train(lgb_params, train_set, num_boost_round=100, valid_sets=test_set, verbose_eval=10) result = lgb_model.predict(x_test, num_iteration=lgb_model.best_iteration) y_pred = [] for x in result: y_pred.append(np.argmax(x)) |
これでモデルの定義は完了です。実際の学習ログとしては、以下になります。
1 2 3 4 5 6 7 8 9 10 |
[10] valid_0's multi_logloss: 0.735528 [20] valid_0's multi_logloss: 0.540822 [30] valid_0's multi_logloss: 0.430339 [40] valid_0's multi_logloss: 0.34375 [50] valid_0's multi_logloss: 0.274193 [60] valid_0's multi_logloss: 0.225241 [70] valid_0's multi_logloss: 0.187616 [80] valid_0's multi_logloss: 0.162716 [90] valid_0's multi_logloss: 0.146367 [100] valid_0's multi_logloss: 0.133638 |
学習モデルを混同行列と正解率で確認します。混同行列を使用することで、ある正解ラベルに対してモデルの予測結果が一致したデータ件数と、ある正解ラベルに対してモデルの予測結果が一致していないデータ件数を確認することができます。
1 2 |
confusion_matrix(y_test, y_pred) accuracy_score(y_test, y_pred) |
混同行列を確認すると、正解はクラス2に属するワインをクラス3に属するワインと誤って分類したデータが2件あるようです。正解率は94.44%のようです。
PythonでLightGBMを用いてデータ分析を行いました。今回はサンプルデータを利用しましたが、Kaggle等のデータ分析コンペのデータでも利用できますので是非活用してみてはいかがでしょうか。
ソースコード全体を載せます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import numpy as np import pandas as pd import matplotlib.pyplot as plt import lightgbm as lgb from sklearn.metrics import confusion_matrix from sklearn.metrics import accuracy_score from sklearn.datasets import load_wine from sklearn.model_selection import train_test_split data = load_wine() x_data = data['data'] label_data = data['target'] x_train, x_test, y_train, y_test = train_test_split(x_data, label_data, test_size=0.2) train_set = lgb.Dataset(x_train, y_train) test_set = lgb.Dataset(x_test, y_test, reference=train_set) lgb_params = { 'boosting_type' : 'gbdt', 'objective' : 'multiclass', 'metric' : 'multi_logloss', 'num_class' : 3, 'num_leaves' : 40, 'learning_rate' : 0.05, 'feature_fraction' : 0.9, 'bagging_fraction' : 0.8, 'bagging_freq' : 0 } lgb_model = lgb.train(lgb_params, train_set, num_boost_round=100, valid_sets=test_set, verbose_eval=10) result = lgb_model.predict(x_test, num_iteration=lgb_model.best_iteration) y_pred = [] for x in result: y_pred.append(np.argmax(x)) confusion_matrix(y_test, y_pred) accuracy_score(y_test, y_pred) |