AutoML と Python (SDK v1) を使用して回帰モデルをトレーニングする
適用対象: Python SDK azureml v1
この記事では、Azure Machine Learning の AutoML を使用して Azure Machine Learning Python SDK で回帰モデルをトレーニングする方法について説明します。 回帰モデルは、ニューヨーク市 (NYC) で運行するタクシーの乗客料金を予測します。 ここでは、準備されたデータを使用してワークスペースを構成し、カスタム パラメーターを使用してモデルをローカルでトレーニングし、結果を確認するコードを Python SDK を使用して記述します。
このプロセスは、トレーニング データと構成設定を受け入れます。 これは、さまざまな特徴量の正規化/標準化の方法、モデル、ハイパーパラメーター設定の組み合わせを自動的に反復処理し、最適なモデルに到達します。 次の図は、回帰モデル トレーニングのプロセス フローを示しています。
前提条件
Azure サブスクリプション。 Azure Machine Learning の無料アカウントまたは有料アカウントを作成できます。
Azure Machine Learning ワークスペースまたはコンピューティング インスタンス。 これらのリソースを準備するには、「クイックスタート: Azure Machine Learning の利用を開始する」を参照してください。
ワークスペースにノートブックを読み込んで、チュートリアル演習用に準備されたサンプル データを取得します。
Azure Machine Learning スタジオでワークスペースに移動し、[ノートブック] を選択してから [サンプル] タブを選択します。
ノートブックの一覧で、[Samples]>[SDK v1]>[tutorials]>[regression-automl-nyc-taxi-data] ノードを展開します。
regression-automated-ml.ipynb ノートブックを選択します。
各ノートブック セルをこのチュートリアルの一環として実行するには、[このノートブックを複製する] を選択します。
別の方法: 必要に応じて、ローカル環境でチュートリアルの演習を実行できます。 このチュートリアルは、GitHub の Azure Machine Learning Notebooks リポジトリで入手できます。 この方法を使用する場合は、次の手順に従って必要なパッケージを取得します。
ローカル コンピューターで
pip install azureml-opendatasets azureml-widgets
コマンドを実行して、必要なパッケージを取得します。
データのダウンロードと準備
Open Datasets パッケージには各データ ソースを表すクラス (NycTlcGreen
など) が含まれており、ダウンロードする前に簡単に日付パラメーターをフィルター処理できます。
次のコードは、必要なパッケージをインポートします。
from azureml.opendatasets import NycTlcGreen
import pandas as pd
from datetime import datetime
from dateutil.relativedelta import relativedelta
最初の手順では、タクシー データのデータフレームを作成します。 Spark 以外の環境で作業する場合、Open Datasets では、特定のクラスの 1 か月分のデータしか一度にダウンロードできません。 この方法は、大規模なデータセットで発生しがちな MemoryError
の問題を回避するのに役立ちます。
タクシーのデータをダウンロードするには、一度に 1 か月ずつ繰り返しフェッチします。 次のデータ セットを green_taxi_df
データフレームに追加する前に、毎月 2,000 件のレコードをランダムにサンプリングしてから、データのプレビューを実行します。 この方法は、データフレームの肥大化を回避するのに役立ちます。
次のコードは、データフレームを作成し、データをフェッチして、それをデータフレームに読み込みます。
green_taxi_df = pd.DataFrame([])
start = datetime.strptime("1/1/2015","%m/%d/%Y")
end = datetime.strptime("1/31/2015","%m/%d/%Y")
for sample_month in range(12):
temp_df_green = NycTlcGreen(start + relativedelta(months=sample_month), end + relativedelta(months=sample_month)) \
.to_pandas_dataframe()
green_taxi_df = green_taxi_df.append(temp_df_green.sample(2000))
green_taxi_df.head(10)
次の表は、サンプル タクシー データの値を含む多数の列を示しています。
vendorID | lpepPickupDatetime | lpepDropoffDatetime | passengerCount | tripDistance | puLocationId | doLocationId | pickupLongitude | pickupLatitude | dropoffLongitude | ... | paymentType | fareAmount | extra | mtaTax | improvementSurcharge | tipAmount | tollsAmount | ehailFee | totalAmount | tripType |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 2015-01-30 18:38:09 | 2015-01-30 19:01:49 | 1 | 1.88 | なし | なし | -73.996155 | 40.690903 | -73.964287 | ... | 1 | 15.0 | 1.0 | 0.5 | 0.3 | 4.00 | 0.0 | なし | 20.80 | 1.0 |
1 | 2015-01-17 23:21:39 | 2015-01-17 23:35:16 | 1 | 2.70 | なし | なし | -73.978508 | 40.687984 | -73.955116 | ... | 1 | 11.5 | 0.5 | 0.5 | 0.3 | 2.55 | 0.0 | なし | 15.35 | 1.0 |
2 | 2015-01-16 01:38:40 | 2015-01-16 01:52:55 | 1 | 3.54 | なし | なし | -73.957787 | 40.721779 | -73.963005 | ... | 1 | 13.5 | 0.5 | 0.5 | 0.3 | 2.80 | 0.0 | なし | 17.60 | 1.0 |
2 | 2015-01-04 17:09:26 | 2015-01-04 17:16:12 | 1 | 1.00 | なし | なし | -73.919914 | 40.826023 | -73.904839 | ... | 2 | 6.5 | 0.0 | 0.5 | 0.3 | 0.00 | 0.0 | なし | 7.30 | 1.0 |
1 | 2015-01-14 10:10:57 | 2015-01-14 10:33:30 | 1 | 5.10 | なし | なし | -73.943710 | 40.825439 | -73.982964 | ... | 1 | 18.5 | 0.0 | 0.5 | 0.3 | 3.85 | 0.0 | なし | 23.15 | 1.0 |
2 | 2015-01-19 18:10:41 | 2015-01-19 18:32:20 | 1 | 7.41 | なし | なし | -73.940918 | 40.839714 | -73.994339 | ... | 1 | 24.0 | 0.0 | 0.5 | 0.3 | 4.80 | 0.0 | なし | 29.60 | 1.0 |
2 | 2015-01-01 15:44:21 | 2015-01-01 15:50:16 | 1 | 1.03 | なし | なし | -73.985718 | 40.685646 | -73.996773 | ... | 1 | 6.5 | 0.0 | 0.5 | 0.3 | 1.30 | 0.0 | なし | 8.60 | 1.0 |
2 | 2015-01-12 08:01:21 | 2015-01-12 08:14:52 | 5 | 2.94 | なし | なし | -73.939865 | 40.789822 | -73.952957 | ... | 2 | 12.5 | 0.0 | 0.5 | 0.3 | 0.00 | 0.0 | なし | 13.30 | 1.0 |
1 | 2015-01-16 21:54:26 | 2015-01-16 22:12:39 | 1 | 3.00 | なし | なし | -73.957939 | 40.721928 | -73.926247 | ... | 1 | 14.0 | 0.5 | 0.5 | 0.3 | 2.00 | 0.0 | なし | 17.30 | 1.0 |
2 | 2015-01-06 06:34:53 | 2015-01-06 06:44:23 | 1 | 2.31 | なし | なし | -73.943825 | 40.810257 | -73.943062 | ... | 1 | 10.0 | 0.0 | 0.5 | 0.3 | 2.00 | 0.0 | なし | 12.80 | 1.0 |
これは、トレーニングまたはその他の特徴量の構築には必要ない列を削除するのに役立ちます。 たとえば、時間ベースの特徴量は AutoML が自動的に処理するため、lpepPickupDatetime 列は削除できます。
次のコードは、サンプル データから 14 列を削除します。
columns_to_remove = ["lpepDropoffDatetime", "puLocationId", "doLocationId", "extra", "mtaTax",
"improvementSurcharge", "tollsAmount", "ehailFee", "tripType", "rateCodeID",
"storeAndFwdFlag", "paymentType", "fareAmount", "tipAmount"
]
for col in columns_to_remove:
green_taxi_df.pop(col)
green_taxi_df.head(5)
データをクレンジングする
次の手順では、データをクレンジングします。
次のコードは、新しいデータフレームで describe()
関数を実行して、各フィールドの要約統計を生成します。
green_taxi_df.describe()
次の表に、サンプル データの残りのフィールドの要約統計を示します。
vendorID | passengerCount | tripDistance | pickupLongitude | pickupLatitude | dropoffLongitude | dropoffLatitude | totalAmount | |
---|---|---|---|---|---|---|---|---|
count | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 | 24000.00 |
mean | 1.777625 | 1.373625 | 2.893981 | -73.827403 | 40.689730 | -73.819670 | 40.684436 | 14.892744 |
std | 0.415850 | 1.046180 | 3.072343 | 2.821767 | 1.556082 | 2.901199 | 1.599776 | 12.339749 |
min | 1.00 | 0.00 | 0.00 | -74.357101 | 0.00 | -74.342766 | 0.00 | -120.80 |
25% | 2.00 | 1.00 | 1.05 | -73.959175 | 40.699127 | -73.966476 | 40.699459 | 8.00 |
50% | 2.00 | 1.00 | 1.93 | -73.945049 | 40.746754 | -73.944221 | 40.747536 | 11.30 |
75% | 2.00 | 1.00 | 3.70 | -73.917089 | 40.803060 | -73.909061 | 40.791526 | 17.80 |
max | 2.00 | 8.00 | 154.28 | 0.00 | 41.109089 | 0.00 | 40.982826 | 425.00 |
要約統計には、外れ値 (モデルの精度を低下させる値) であるいくつかのフィールドが表示されます。 この問題に対処するには、緯度/経度 (lat/long) フィールドをフィルター処理して、値がマンハッタン区域の境界に収まるようにします。 この方法により、その距離範囲を超えるタクシー乗車や、他の特徴量との関係の点で外れ値となっているタクシー乗車が除外されます。
次に、tripDistance
フィールドが 0 より大きく 31 マイル (2 つの緯度/経度ペア間の半正矢距離) 未満の値となるようにフィルター処理します。 この手法により、移動距離が長く、矛盾した運賃となっている外れ値の乗車が除外されます。
最後に、totalAmount
フィールドには、このモデルのコンテキストでは的外れな、タクシー料金に関する負の値があります。 passengerCount
フィールドにも、最小値 0 という不適切なデータが含まれています。
次のコードは、クエリ関数を使用してこれらの異常値を除外します。 次に、トレーニングに必要のない最後のいくつかの列を削除します。
final_df = green_taxi_df.query("pickupLatitude>=40.53 and pickupLatitude<=40.88")
final_df = final_df.query("pickupLongitude>=-74.09 and pickupLongitude<=-73.72")
final_df = final_df.query("tripDistance>=0.25 and tripDistance<31")
final_df = final_df.query("passengerCount>0 and totalAmount>0")
columns_to_remove_for_training = ["pickupLongitude", "pickupLatitude", "dropoffLongitude", "dropoffLatitude"]
for col in columns_to_remove_for_training:
final_df.pop(col)
このシーケンスの最後の手順では、データに対して describe()
関数をもう一度呼び出して、クレンジングが期待どおりに動作することを確認します。 これで、機械学習モデルのトレーニングに使用するためのタクシー、休日、気象のデータセットの準備とクレンジングが終了しました。
final_df.describe()
ワークスペースの構成
既存のワークスペースからワークスペース オブジェクトを作成します。 ワークスペースは、お客様の Azure サブスクリプションとリソースの情報を受け取るクラスです。 また、これにより、お客様のモデル実行を監視して追跡するためのクラウド リソースが作成されます。
次のコードは、Workspace.from_config()
関数を呼び出して config.json ファイルを読み取り、認証の詳細を ws
という名前のオブジェクトに読み込みます。
from azureml.core.workspace import Workspace
ws = Workspace.from_config()
ws
オブジェクトは、このチュートリアルの残りのコード全体で使用されます。
データをトレーニング セットとテスト セットに分割する
scikit-learn ライブラリの train_test_split
関数を使用して、トレーニング セットとテスト セットにデータを分割します。 この関数は、モデル トレーニング用の x (特徴) データ セットとテスト用の y (予測する値) データ セットに、データを分割します。
test_size
パラメーターでは、テストに割り当てるデータの割合を決定します。 random_state
パラメーターでは、お客様のトレーニングとテストの分割が決定論的になるように、乱数ジェネレーターにシードを設定します。
次のコードは、x と y のデータセットを読み込む train_test_split
関数を呼び出します。
from sklearn.model_selection import train_test_split
x_train, x_test = train_test_split(final_df, test_size=0.2, random_state=223)
この手順の目的は、モデルのトレーニングに使用されない完成したモデルをテストするためにデータ ポイントを準備することです。 これらのポイントは、真の精度を測定するために使用されます。 適切にトレーニングされたモデルは、見えないデータから正確な予測を行うことができるモデルです。 機械学習モデルの自動トレーニングに使用するデータの準備が整いました。
自動的にモデルをトレーニングする
モデルを自動的にトレーニングするには、次の手順を実行します。
実験の実行用の設定を定義する。 トレーニング データを構成にアタッチし、トレーニング プロセスを制御する設定を変更します。
モデル調整用の実験を送信する。 実験を送信した後、プロセスは定義された制約に従って、他の機械学習アルゴリズムとハイパー パラメーター設定を反復処理します。 精度メトリックを最適化することによって、最適なモデルが選択されます。
トレーニングの設定を定義する
トレーニング用の実験パラメーターとモデルの設定を定義します。 設定の完全な一覧を表示します。 これらの既定の設定で実験を送信するには、約 5 分から 20 分かかります。 実行時間を短縮するには、experiment_timeout_hours
パラメーターを低くしてください。
プロパティ | このチュートリアルの値 | 説明 |
---|---|---|
iteration_timeout_minutes |
10 | 各イテレーションの分単位での時間制限。 各イテレーションにより多くの時間を必要とする大規模なデータセットの場合は、この値を大きくします。 |
experiment_timeout_hours |
0.3 | すべてのイテレーションを組み合わせて、実験が終了するまでにかかる最大時間 (時間単位)。 |
enable_early_stopping |
True | 短期間でスコアが向上していない場合に、早期終了を有効にするフラグ。 |
primary_metric |
spearman_correlation | 最適化したいメトリック。 このメトリックに基づいて、最適なモデルが選択されます。 |
featurization |
auto | auto 値を使用すると、実験で入力データを前処理できます (欠損データの処理、テキストから数値への変換など)。 |
verbosity |
logging.INFO | ログ記録のレベルを制御します。 |
n_cross_validations |
5 | 検証データが指定されていない場合に実行される、クロス検証の分割の数。 |
次のコードは実験を送信します。
import logging
automl_settings = {
"iteration_timeout_minutes": 10,
"experiment_timeout_hours": 0.3,
"enable_early_stopping": True,
"primary_metric": 'spearman_correlation',
"featurization": 'auto',
"verbosity": logging.INFO,
"n_cross_validations": 5
}
次のコードを使用すると、定義済みのトレーニング設定を、AutoMLConfig
オブジェクトへの **kwargs
パラメーターとして使用できます。 さらに、トレーニング データとモデルの種類を指定します。モデルの種類は、ここでは regression
です。
from azureml.train.automl import AutoMLConfig
automl_config = AutoMLConfig(task='regression',
debug_log='automated_ml_errors.log',
training_data=x_train,
label_column_name="totalAmount",
**automl_settings)
Note
AutoML の前処理手順 (特徴量の正規化、欠損データの処理、テキストから数値への変換など) は、基になるモデルの一部になります。 モデルを予測に使用する場合、トレーニング中に適用されたのと同じ前処理手順が入力データに自動的に適用されます。
自動回帰モデルをトレーニングする
自分のワークスペース内に実験オブジェクトを作成します。 実験は、個々のジョブのコンテナーとして機能します。 定義済みの automl_config
オブジェクトを実験に渡し、出力を True に設定してジョブ中の進行状況を表示します。
実験を開始すると、その進行に伴い、表示される出力が随時更新されます。 イテレーションごとに、モデルの種類、実行継続時間、トレーニングの精度が表示されます。 BEST
フィールドでは、メトリックの種類に基づいて、最高の実行トレーニング スコアが追跡されます。
from azureml.core.experiment import Experiment
experiment = Experiment(ws, "Tutorial-NYCTaxi")
local_run = experiment.submit(automl_config, show_output=True)
出力は次のようになります。
Running on local machine
Parent Run ID: AutoML_1766cdf7-56cf-4b28-a340-c4aeee15b12b
Current status: DatasetFeaturization. Beginning to featurize the dataset.
Current status: DatasetEvaluation. Gathering dataset statistics.
Current status: FeaturesGeneration. Generating features for the dataset.
Current status: DatasetFeaturizationCompleted. Completed featurizing the dataset.
Current status: DatasetCrossValidationSplit. Generating individually featurized CV splits.
Current status: ModelSelection. Beginning model selection.
****************************************************************************************************
ITERATION: The iteration being evaluated.
PIPELINE: A summary description of the pipeline being evaluated.
DURATION: Time taken for the current iteration.
METRIC: The result of computing score on the fitted pipeline.
BEST: The best observed score thus far.
****************************************************************************************************
ITERATION PIPELINE DURATION METRIC BEST
0 StandardScalerWrapper RandomForest 0:00:16 0.8746 0.8746
1 MinMaxScaler RandomForest 0:00:15 0.9468 0.9468
2 StandardScalerWrapper ExtremeRandomTrees 0:00:09 0.9303 0.9468
3 StandardScalerWrapper LightGBM 0:00:10 0.9424 0.9468
4 RobustScaler DecisionTree 0:00:09 0.9449 0.9468
5 StandardScalerWrapper LassoLars 0:00:09 0.9440 0.9468
6 StandardScalerWrapper LightGBM 0:00:10 0.9282 0.9468
7 StandardScalerWrapper RandomForest 0:00:12 0.8946 0.9468
8 StandardScalerWrapper LassoLars 0:00:16 0.9439 0.9468
9 MinMaxScaler ExtremeRandomTrees 0:00:35 0.9199 0.9468
10 RobustScaler ExtremeRandomTrees 0:00:19 0.9411 0.9468
11 StandardScalerWrapper ExtremeRandomTrees 0:00:13 0.9077 0.9468
12 StandardScalerWrapper LassoLars 0:00:15 0.9433 0.9468
13 MinMaxScaler ExtremeRandomTrees 0:00:14 0.9186 0.9468
14 RobustScaler RandomForest 0:00:10 0.8810 0.9468
15 StandardScalerWrapper LassoLars 0:00:55 0.9433 0.9468
16 StandardScalerWrapper ExtremeRandomTrees 0:00:13 0.9026 0.9468
17 StandardScalerWrapper RandomForest 0:00:13 0.9140 0.9468
18 VotingEnsemble 0:00:23 0.9471 0.9471
19 StackEnsemble 0:00:27 0.9463 0.9471
結果を探索する
Jupyter ウィジェットを使用して、自動トレーニングの結果を探索します。 このウィジェットを使用すると、トレーニング精度のメトリックとメタデータと共に、各ジョブのすべてのイテレーションのグラフと表を確認できます。 さらに、ドロップダウン セレクターを使用して、主なメトリック以外にも、さまざまな精度メトリックを条件としてフィルター処理することができます。
次のコードは、結果を調べるためのグラフを生成します。
from azureml.widgets import RunDetails
RunDetails(local_run).show()
Jupyter ウィジェットの実行の詳細:
Jupyter ウィジェットのプロット グラフ:
最適なモデルを取得する
次のコードを使用すると、イテレーションから最適なモデルを選択できます。 get_output
関数は、最適な実行と、最後の fit の呼び出しで適合したモデルを返します。 get_output
関数のオーバーロードを使用して、ログ記録された任意のメトリックや特定のイテレーションに対する最適な実行と適合モデルを取得できます。
best_run, fitted_model = local_run.get_output()
print(best_run)
print(fitted_model)
最適なモデルの精度をテストする
最高のモデルを使用して、テスト データ セット上で予測を実行し、タクシー料金を予測します。 predict
関数は最適のモデルを使用して、x_test
データ セットから y (交通費) の値を予測します。
次のコードは、y_predict
データ セットから最初の 10 個の予測コスト値を出力します。
y_test = x_test.pop("totalAmount")
y_predict = fitted_model.predict(x_test)
print(y_predict[:10])
結果の root mean squared error
を計算します。 y_test
データフレームをリストに変換し、予測値と比較します。 mean_squared_error
関数によって 2 つの配列の値が受け取られ、それらの間の平均二乗誤差が計算されます。 結果の平方根を取ると、y 変数 (コスト) と同じ単位で誤差が得られます。 これは、タクシー料金の予測が実際の料金からどの程度離れているかを大まかに示します。
from sklearn.metrics import mean_squared_error
from math import sqrt
y_actual = y_test.values.flatten().tolist()
rmse = sqrt(mean_squared_error(y_actual, y_predict))
rmse
次のコードを実行し、完全な y_actual
と y_predict
データ セットを使用して平均絶対誤差率 (MAPE) を計算します。 このメトリックでは、予測される各値と実際の値の間の絶対誤差が計算され、すべての差分が合計されます。 そしてその合計が、実際の値の合計に対する割合として表されます。
sum_actuals = sum_errors = 0
for actual_val, predict_val in zip(y_actual, y_predict):
abs_error = actual_val - predict_val
if abs_error < 0:
abs_error = abs_error * -1
sum_errors = sum_errors + abs_error
sum_actuals = sum_actuals + actual_val
mean_abs_percent_error = sum_errors / sum_actuals
print("Model MAPE:")
print(mean_abs_percent_error)
print()
print("Model Accuracy:")
print(1 - mean_abs_percent_error)
出力は次のようになります。
Model MAPE:
0.14353867606052823
Model Accuracy:
0.8564613239394718
最終的な予測精度メトリックから、モデルでのデータ セットの特徴によるタクシー料金の予測はかなり良好で、誤差は ± 4 ドル (約 15%) 以内であることがわかります。
従来型の機械学習モデルの開発プロセスは、リソースを大量に消費します。 多数のモデルの結果を実行して比較するため、ドメインに関する膨大な知識と時間の投資が求められます。 自動化された機械学習の使用は、シナリオに合わせてさまざまなモデルを迅速にテストするための優れた方法です。
リソースをクリーンアップする
他の Azure Machine Learning チュートリアルを実行する予定がない場合は、次の手順を実行して、不要なリソースを削除します。
コンピューティングを停止する
コンピューティングを使用した場合は、使用していないときに仮想マシンを停止するとコストを削減できます。
Azure Machine Learning スタジオ内のワークスペースに移動し、[コンピューティング] を選択します。
一覧で、停止するコンピューティングを選択し、[停止] を選択します。
コンピューティングを再度使用する準備ができたら、仮想マシンを再起動できます。
他のリソースを削除する
このチュートリアルで作成したリソースを使用する予定がない場合は、それらを削除して、追加の料金が発生しないようにすることができます。
リソース グループとすべてのリソースを削除するには、次の手順に従います。
Azure portal で、[リソース グループ] に移動します。
一覧で、このチュートリアルで作成したリソース グループを選択し、[リソース グループの削除] を選択します。
確認のプロンプトが表示されたら、リソース グループ名を入力し、[削除] を選択します。
リソース グループは保持したまま 1 つのワークスペースのみを削除する場合は、次の手順に従います。
Azure portal で、削除するワークスペースが含まれているリソース グループに移動します。
ワークスペースを選択し、[プロパティ] を選択してから [削除] を選択します。