PyCaret 2.2 : チュートリアル : 回帰 (初級)

PyCaret 2.2 チュートリアル : 回帰 (初級) (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/18/2020 (2.2.2)

* 本ページは、PyCaret 2.2 ドキュメントの以下のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

 

チュートリアル : 回帰 (初級)

1.0 チュートリアルの目的

このチュートリアルは貴方が PyCaret の経験は初めてで pycaret.regression モジュールを使用して回帰から始めることに関心があることを仮定しています。

このチュートリアルで以下を学習します :

  • データを得る : PyCaret レポジトリからどのようにデータをインポートするか
  • 環境をセットアップする : PyCaret でどのように実験をセットアップして回帰モデルの構築を始めるか。
  • モデルを作成する : モデルをどのように作成するか、交差検証を遂行するか、そして回帰メトリクスを評価するか
  • モデルを調整する : 回帰モデルのハイパーパラメータをどのように調整するか
  • モデルをプロットする : 様々なプロットを使用してモデル性能をどのように分析するか
  • モデルを完成させる (= finalize) : 実験の最後に最善のモデルをどのように完成させるか
  • モデルを予測する : 新しい / 未見のデータ上でどのように予測を行なうか
  • モデルをセーブ / ロードする : 将来的な利用のためにモデルをどのようにセーブ / ロードするか

 

2.0 回帰とは何か?

回帰分析は従属変数 (しばしば「結果変数」や「ターゲット」と呼ばれます) と一つまたはそれ以上の独立変数 (しばしば「特徴」、「予測器 (= predictors)」や「共変量」と呼ばれます) 間の関係を推定するための統計的プロセスのセットです。機械学習における回帰の目的は売上高、量、気温等のような営業連続変数を予測することです。

回帰について更に学習する

 

3.0 PyCaret の回帰モジュールの概要

PyCaret の回帰モジュール (pycaret.regression) は教師あり機械学習モジュールで、これは様々なテクニックとアルゴリズムを使用して連続値 / 結果を予測するために利用されます。回帰はセールス、売上ユニット、気温や連続である任意の数を予測するために使用できます。

PyCaret の回帰モジュールは 25 以上のアルゴリズムとモデルのパフォーマンスを分析するために 10 プロットを持ちます。それがハイパーパラメータ調整、アンサンブル、あるいはスタッキングのような進んだテクニックであろうと、PyCaret の回帰モジュールはそれを総て持ちます。

 

4.0 チュートリアルのためのデータセット

このチュートリアルのために “Sarah Gets a Diamond” と呼ばれるケーススタディに基づいたデータセットを利用します。このケースは Darden School of Business (バージニア大学) の初年度の決定分析コースで提示されました。データのための基礎は未来の花嫁、Sarah のために 適切なダイアモンドを選択する hopeless romantic MBA 学生に関するケースです。データは訓練のために 6000 レコードを含みます。各カラムの短い説明は次のようなものです :

  • ID: 各観測を一意に識別する (ダイアモンド)
  • Carat Weight: メトリック・カラットでのダイアモンドの重み。1 カラットは 0.2 グラムで、大雑把にはペーパークリップと同じ重さです。
  • Cut: 次の望ましさの順序にあるダイアモンドのカットを示す 5 つの値の 1 つ (Signature-Ideal, Ideal, Very Good, Good, Fair)
  • Color: 次の望ましさの順序にあるダイアモンドのカラーを示す 6 つの値の 1 つ (D, E, F – Colorless, G, H, I – Near colorless)
  • Clarity: 次の望ましさの順序にあるダイアモンドのクラリティ (透明さ) を示す 7 つの値の 1 つ (F – Flawless, IF – Internally Flawless, VVS1 or VVS2 – Very, Very Slightly Included, or VS1 or VS2 – Very Slightly Included, SI1 – Slightly Included)
  • Polish: ダイアモンドのポリッシュ (研磨状態) を示す 4 つの値の 1 つ (ID – Ideal, EX – Excellent, VG – Very Good, G – Good)
  • Symmetry: ダイアモンドのシンメトリを示す 4 つの値の 1 つ (ID – Ideal, EX – Excellent, VG – Very Good, G – Good)
  • Report: どちらの格付けエージェンシーがダイアモンド品質の品質を報告したかを示す 2 つの値 “AGSL” or “GIA” の 1 つ
  • Price: 査定されたダイアモンドの USD での総額、ターゲットカラム

データセットの謝辞:
This case was prepared by Greg Mills (MBA ’07) under the supervision of Phillip E. Pfeifer, Alumni Research Professor of Business Administration. Copyright (c) 2007 by the University of Virginia Darden School Foundation, Charlottesville, VA. All rights reserved.

元のデータセットと説明は ここで見つけられます (訳注: リンク切れ)。

 

5.0 データを得る

データを ここで見つかる (訳注: リンク切れ) 元のソースからダウンロードして pandas を使用してそれをロードすることができますし、あるいは get_data() 関数を使用してデータをロードするために PyCaret のデータレポジトリを利用できます。

from pycaret.datasets import get_data
dataset = get_data('diamond')

#check the shape of data
dataset.shape
(6000, 8)

未見データ上で predict_model() 関数を実演するため、予測のために使用される元のデータセットから 600 レコードのサンプルが抑えられました。これは訓練/テスト分割と混同されるべきではありません、この特定の分割は現実生活のシナリオをシミュレートするために遂行されます。これについて考えるもう一つの方法はこれらの 600 レコードは機械学習実験が遂行される時点では利用可能ではないことです。

data = dataset.sample(frac=0.9, random_state=786)
data_unseen = dataset.drop(data.index)

data.reset_index(drop=True, inplace=True)
data_unseen.reset_index(drop=True, inplace=True)

print('Data for Modeling: ' + str(data.shape))
print('Unseen Data For Predictions: ' + str(data_unseen.shape))
Data for Modeling: (5400, 8)
Unseen Data For Predictions: (600, 8)

 

6.0 PyCaret で環境をセットアップする

setup() 関数は pycaret の環境を初期化してモデリングと配備のためにデータを準備する変換パイプラインを作成します。setup() は pycaret の任意の他の関数を実行する前に呼び出されなければなりません。それは 2 つの必須パラメータを取ります : pandas データフレームとターゲットカラム名です。総ての他のパラメータはオプションで前処理パイプラインをカスタマイズするために使用されます (後のチュートリアルでそれらを見ます)。

setup() が実行されるとき、PyCaret の推論アルゴリズムは特定のプロパティに基づいて総ての特徴のためにデータ型を自動的に推論します。データ型は正しく推論されるべきですが、これは常には当てはまりません。これを説明するため、setup() が実行された後 PyCaret は特徴とそれらの推論された型を含むテーブルを表示します。データ型の総てが正しく識別されれば続けるためにエンターを押すことができて、あるいは実験を終了するために quit がタイプできます。データ型が正しいことを確実にすることは PyCaret で基礎的な重要なことです、何故ならばそれは自動的に 2,3 の前処理タスクを遂行するからです、これは任意の機械学習実験に必須です。これらのタスクは各データ型のために様々に遂行されて、これはそれらが正しく configure されることが非常に重要であることを意味します。

後のチュートリアルで PyCaret の推論データ型を setup() の numeric_features と categorical_features パラメータを使用してどのように上書きするかを学習します。

from pycaret.regression import *
exp_reg101 = setup(data = data, target = 'Price', session_id=123)

ひとたびセットアップが成功的に実行されればそれは情報の幾つかの重要なピースを含む情報グリッドをプリントします。情報の殆どは setup() が実行されるときに構築される前処理パイプラインに関係します。これらの特徴の大部分はこのチュートリアルの目的の範囲外です。けれども、この段階で注意すべき幾つかの重要なことは以下を含みます :

  • session_id : 後の再現性のために総ての関数のシードとして分配される擬似乱数。session_id が渡されない場合、総ての関数に分配される乱数が自動的に生成されます。この実験では、後の再現性のために session_id は 123 として設定されます。
  • Original Data : データセットの元の shape を表示します。この実験では (5400, 8) は 5400 サンプルとターゲットカラムを含む 8 特徴を意味しています。
  • Missing Values : 元のデータに欠損値があるときこれは True として示されます。この実験についてはデータセットに欠損値はありません。
  • Numeric Features : numeric として推論される特徴の数。このデータセットでは 8 特徴から 1 が numeric として推論されます。
  • Categorical Features : categorical として推論される特徴の数。このデータセットでは 8 特徴から 6 が categorical として推論されます。
  • Transformed Train Set : 変換された訓練セットの shape を表示します。(5400, 8) の元の shape は変換された訓練セットのための (3779, 28) に変換されることに注意してください。特徴の数は categorical エンコーディングのために 8 から 28 に増えています。
  • Transformed Test Set : 変換されたテスト/hold-out セットの shape を表示します。テスト/hold-out セットに 1621 サンプルがあります。この分割は 70/30 のデフォルト値に基づいていて、これはセットアップの train_size パラメータを使用して変更可能です。

欠損値補完 (= imputation) (このケースでは訓練データに欠損値はありませんが、依然として未見のデータのために imputer が必要です)、categorical エンコーディング等のような、モデリングを遂行するために必須の 2, 3 のタスクがどのように自動的に処理されるかに気付いてください。setup() の殆どのパラメータはオプションで前処理パイプラインをカスタマイズするために使用されます。これらのパラメータはこのチュートリアルのためには範囲外ですが、中間あるいは専門家レベルに進むときそれらを遥かに詳細にカバーします。

 

7.0 総てのモデルを比較する

セットアップがひとたび完了すればパフォーマンスを評価するために総てのモデルを比較することはモデリングのために推奨される開始点です (どのような種類のモデルを貴方が必要とするかを正確に知らない限りは、それはしばしば当てはまらないでしょう)。この関数はモデルライブラリの総てのモデルを訓練してメトリック評価のための k-fold 交差検証を使用してそれらにスコアをつけます。出力は訓練時間とともに folds (デフォルトで 10) に渡る平均 MAE, MSE, RMSE, R2, RMSLE と MAPE を示すスコアグリッドをプリントします。

best = compare_models(exclude = ['ransac'])

コードの 2 つの単純な単語 (行でさえありません) は交差検証を使用して 20 モデルに渡り訓練して評価します。上でプリントされるスコアグリッドは比較目的だけのために最も高い性能のメトリックをハイライトします。デフォルトではグリッドは R2 (最高から最低へ) を使用してソートされます、これは sort パラメータを渡すことにより変更可能です。例えば compare_models(sort = ‘RMSLE’) は RMSLE によりグリッドをソートします (低いほうから高い方へ、より低いほうがより良いので)。fold パラメータを 10 のデフォルト値から異なる値に変更することを望む場合には fold パラメータを利用できます。例えば compare_models(fold = 5) は総てのモデルを 5 fold 交差検証上で比較します。fold の数を減じれば訓練時間を改良します。デフォルトでは、compare_models はデフォルトのソート順序に基づいて最善の性能のモデルを返しますが、n_select パラメータを使用して top N モデルのリストを返すために利用できます。

exclude パラメータが特定のモデルをブロックするためにどのように使用されるかに注意してください (この場合 RANSAC)。

 

8.0 モデルを作成する

create_model は PyCaret の最も極め細かい (= granular) 関数で殆どの PyCaret 機能の背後でしばしば基礎となります。名前が示すようにこの関数は fold パラメータで設定できる交差検証を使用してモデルを訓練して評価します。出力は fold による MAE, MSE, RMSE, R2, RMSLE と MAPE を示すスコアグリッドをプリントします。

このチュートリアルの残りのパートについては、候補モデルとして下のモデルで作業します。この選択は例示目的のためのみでそれらがこのタイプのデータに対してトップの性能であるとか理想的であることを必ずしも意味しません。

  • AdaBoost Regressor (‘ada’)
  • 軽量勾配ブースティングマシン (Light Gradient Boosting Machine) (‘lightgbm’)
  • 決定木 (‘dt’)

PyCaret のモデルライブラリには利用可能な 25 の regressor があります。総ての regressor のリストのためには docstring を確認するかライブラリを見るために models 関数を使用してください。

models()

 

8.1 AdaBoost Regressor

ada = create_model('ada')

print(ada)
AdaBoostRegressor(base_estimator=None, learning_rate=1.0, loss='linear',
                  n_estimators=50, random_state=123)

 

8.2 軽量勾配ブースティングマシン

lightgbm = create_model('lightgbm')

 

8.3 決定木

dt = create_model('dt')

総てのモデルの平均スコアは compare_models() でプリントされたスコアに一致することに注意してください。これは compare_models() スコアグリッドでプリントされたメトリクスは総ての CV fold に渡る平均スコアであるためです。compare_models() と同様に、fold パラメータを 10 のデフォルト値から異なる値に変更することを望む場合、fold パラメータを使用できます。例えば : create_model(‘dt’, fold = 5) は 5 fold 交差検証を使用して決定木分類器を作成できます。

 

9.0 モデルを調整する

モデルが create_model() 関数を使用して作成されるときそれはモデルを訓練するためにデフォルトのハイパーパラメータを使用します。ハイパーパラメータを調整するためには、tune_model() 関数が利用されます。この関数は事前定義された探索空間上でランダム・グリッドサーチを使用してモデルのハイパーパラメータを自動的に調整します。出力はスコアグリッドをプリントし、これは fold による MAE, MSE, RMSE, R2, RMSLE と MAPE を示します。カスタム・サーチグリッドを使用するために、tune_model 関数で custom_grid パラメータを渡すことができます (下の 9.2 LightGBM tuning 参照)。

 

9.1 AdaBoost Regressor

tuned_ada = tune_model(ada)

print(tuned_ada)
AdaBoostRegressor(base_estimator=None, learning_rate=0.175, loss='exponential',
                  n_estimators=60, random_state=123)

 

9.2 軽量勾配ブースティングマシン

import numpy as np
lgbm_params = {'num_leaves': np.arange(10,200,10),
                        'max_depth': [int(x) for x in np.linspace(10, 110, num = 11)],
                        'learning_rate': np.arange(0.1,1,0.1)
                        }
tuned_lightgbm = tune_model(lightgbm, custom_grid = lgbm_params)

print(tuned_lightgbm)
LGBMRegressor(boosting_type='gbdt', class_weight=None, colsample_bytree=1.0,
              importance_type='split', learning_rate=0.1, max_depth=60,
              min_child_samples=20, min_child_weight=0.001, min_split_gain=0.0,
              n_estimators=100, n_jobs=-1, num_leaves=120, objective=None,
              random_state=123, reg_alpha=0.0, reg_lambda=0.0, silent=True,
              subsample=1.0, subsample_for_bin=200000, subsample_freq=0)

 

9.3 決定木

tuned_dt = tune_model(dt)

デフォルトでは、tune_model は R2 を最適化しますがこれは optimize パラメータを使用して変更できます。例えば : tune_model(dt, optimize = ‘MAE’) は決定木 Regressor のハイパーパラメータを探索します、これは最高の R2 の代わりに最低の MAE という結果になります。このサンプルの目的のため、単純化の目的のためだけにデフォルトのメトリック R2 を使用しました。regressor を評価するために妥当なメトリックを選択する背後の方法論はこのチュートリアルの範囲を越えますが、それについて更に学習したい場合には、回帰エラーメトリクスの理解を深めるために ここをクリック できます。

プロダクションのための最善なモデルを finalize するときメトリクスだけが考慮すべき基準ではありません。考慮すべき他の因子は訓練時間、k-folds の標準偏差 etc. を含みます。チュートリアルのシリーズを通して進むにつれ、中間と専門家レベルでそれらの因子を詳細に議論します。当面は、このチュートリアルの残りのための最善なモデルとして、tuned_lightgbm 変数にストアされた調整された軽量勾配ブースティングマシンを考えて進みます。

 

10.0 モデルをプロットする

モデルを finalize する前に、残差プロット、予測エラー、特徴重要度 (= Feature Importance) 等のような異なる様相に渡りパフォーマンスを分析するために plot_model() 関数が利用できます。この関数は訓練されたモデルオブジェクトを取りテスト / hold-out セットに基づいてプロットを返します。

利用可能な 10 の異なるプロットがあります、利用可能なプロットのリストのためには plot_model() docstring を見てください。

 

10.1 残差 (Residual) プロット

plot_model(tuned_lightgbm)

 

10.2 予測エラープロット

plot_model(tuned_lightgbm, plot = 'error')

 

10.3 特徴重要度プロット

plot_model(tuned_lightgbm, plot='feature')

 
モデルのパフォーマンスを分析するもう一つの方法は evaluate_model() 関数を使用することです、これは与えられたモデルのために利用可能なプロットの総てのためのユーザインターフェイスを表示します。それは内部的には plot_model() 関数を使用しています。

evaluate_model(tuned_lightgbm)

 

11.0 テスト / hold-out サンプル上で予測する

モデルを finalize する前に、テスト/hold-out セットを予測して評価メトリクスをレビューすることにより一つの最終確認を遂行することが賢明です。上のセクション 6 の情報グリッドを見れば、データの 30% (1621 サンプル) がテスト/hold-out サンプルとして分割されたことを見るでしょう。上で見た評価メトリクスの総ては訓練セット (70%) だけに基づいて交差検証された結果です。今は、tuned_lightgbm 変数にストアされた最終的な訓練モデルを使用して hold-out サンプルに対して予測してそれらが CV 結果と実質的に異なるかを見るためにメトリクスを評価します。

predict_model(tuned_lightgbm);

テスト/hold-out セット上の R2 は tuned_lightgbm CV 結果 (上のセクション 9.2) 上で達成された 0.9652 に比較して 0.9708 です。これは本質的な差異ではありません。もしテスト/hold-out と CV 結果の間で大きな変動があれば、これは通常は over-fitting を示しますが幾つかの他の要因に依る可能性もあり更なる調査を必要とするでしょう。このケースでは、モデルを finalize して未見データ (最初に分離された 10% で PyCaret に決して公開していません) を予測することに進みます。

(TIP : create_model() を使用するとき CV 結果の標準偏差を見ることは常に良いです。)

 

配備のためにモデルを finalize する

モデル finalization は実験の最後のステップです。PyCaret の通常の機械学習ワークフローは setup() で始まり、続いて compare_models() を使用して総てのモデルを比較してそしてハイパーパラメータ調整、アンサンブリング、スタッキング等のような幾つかのモデリングテクニックを遂行するために 2, 3 の候補モデルをショートリストします (関心のあるメトリックに基づいて)。このワークフローは新しい未見のデータ上で予測する点で使用するに最善のモデルに最終的に導きます。finalize_model() 関数はモデルをテスト/hold-out サンプル (この場合 30%) を含む完全なデータセットに fit します。この関数の目的はそれがプロダクションで配備される前に完全なデータセット上でモデルを訓練することです。

final_lightgbm = finalize_model(tuned_lightgbm)
print(final_lightgbm)
LGBMRegressor(boosting_type='gbdt', class_weight=None, colsample_bytree=1.0,
              importance_type='split', learning_rate=0.1, max_depth=60,
              min_child_samples=20, min_child_weight=0.001, min_split_gain=0.0,
              n_estimators=100, n_jobs=-1, num_leaves=120, objective=None,
              random_state=123, reg_alpha=0.0, reg_lambda=0.0, silent=True,
              subsample=1.0, subsample_for_bin=200000, subsample_freq=0)

Caution: One final word of caution. モデルが finalize_model() を使用してひとたび finalize されれば、テスト/hold-out セットを含むデータセット全体が訓練のために使用されます。そのようなものとして、もし finalize_model が使用された後にモデルが hold-out セット上で予測のために使用されれば、プリントされる情報グリッドは誤解されやすいです、何故ならばモデリングのために使用された同じデータ上で予測しようとしているからです。この点だけを実演するため、情報グリッドを上のセクション 11 のものと比較するため predict_model() のもとに final_lightgbm を使用します。

predict_model(final_lightgbm);

final_lightgbm の R2 が 0.9652 から 0.9891 に増加したことに気付いてください、モデルは同じですが。これは final_lightgbm 変数がテスト/hold-out セットを含む完全なデータセット上で訓練されたからです。

 

13.0 未見のデータ上で予測する

predict_model() 関数はまた未見のデータセット上で予測するために使用されます。上のセクション 11 との唯一の違いは今回は data_unseen パラメータを渡すことです。data_unseen はチュートリアルの最初で作成される変数で元のデータセットの 10% (600 サンプル) を含みます、これは PyCaret に決して公開されていません。(説明のためにはセクション 5 参照)

unseen_predictions = predict_model(final_lightgbm, data=data_unseen)
unseen_predictions.head()

Label カラムが data_unseen セットに追加されます。Label は final_lightgbm モデルを使用して予測された値です。予測が丸められることを望むのであれば、predict_model() 内で round パラメータを使用できます。この上でメトリクスを確認することもできます、何故ならば利用可能な実際のターゲットカラム Price を持つからです。それを行なうために pycaret.utils モジュールを使用します。下のサンプルを見てください :

from pycaret.utils import check_metric
check_metric(unseen_predictions.Price, unseen_predictions.Label, 'R2')
0.9779

 

14.0 モデルをセーブする

今では final_lightgbm 変数にストアされた tuned_lightgbm モデルを finalize することにより実験を終了しました。data_unseen を予測するために final_lightgbm にストアされたモデルも使用しました。これは私達に実験の終わりをもたらしますが、依然として一つの質問が問われるべきです : 予測するためのより多くの新しいデータを持つとき何が起きるでしょう?実験全体を再度通り抜けなければなりませんか?答えはノーです、PyCaret の組込み関数 save_model() は後で使用するために変換パイプライン全体と一緒にモデルをセーブすることを可能にします。

save_model(final_lightgbm,'Final LightGBM Model 25Nov2020')
Transformation Pipeline and Model Succesfully Saved
(Pipeline(memory=None,
          steps=[('dtypes',
                  DataTypes_Auto_infer(categorical_features=[],
                                       display_types=True, features_todrop=[],
                                       id_columns=[], ml_usecase='regression',
                                       numerical_features=[], target='Price',
                                       time_features=[])),
                 ('imputer',
                  Simple_Imputer(categorical_strategy='not_available',
                                 fill_value_categorical=None,
                                 fill_value_numerical=None,
                                 numeric_strategy='...
                  LGBMRegressor(boosting_type='gbdt', class_weight=None,
                                colsample_bytree=1.0, importance_type='split',
                                learning_rate=0.1, max_depth=60,
                                min_child_samples=20, min_child_weight=0.001,
                                min_split_gain=0.0, n_estimators=100, n_jobs=-1,
                                num_leaves=120, objective=None, random_state=123,
                                reg_alpha=0.0, reg_lambda=0.0, silent=True,
                                subsample=1.0, subsample_for_bin=200000,
                                subsample_freq=0)]],
          verbose=False), 'Final LightGBM Model 25Nov2020.pkl')

(TIP : It’s always good to use date in the filename when saving models, it’s good for version control.)

 

15.0 セーブされたモデルをロードします

同じまたは代替の環境で将来的にセーブされたモデルをロードするためには、PyCaret の load_model() 関数を使用してから予測のために新しい未見のデータ上でセーブされたモデルを容易に適用します。

saved_final_lightgbm = load_model('Final LightGBM Model 25Nov2020')
Transformation Pipeline and Model Successfully Loaded

ひとたびモデルが環境にロードされれば、同じ predict_model() 関数を使用して任意の新しいデータ上で予測するためにそれを利用できます。上のセクション 13 で使用した同じ data_unseen を予測するために下でロードされたモデルを適用しました。

new_prediction = predict_model(saved_final_lightgbm, data=data_unseen)
new_prediction.head()

unseen_predictions と new_prediction の結果が同一であることに注意してください。

from pycaret.utils import check_metric
check_metric(new_prediction.Price, new_prediction.Label, 'R2')
0.9779
 

以上