TensorFlow でのレコメンデーション: AI Platform でトレーニングと調整を行う

この記事は、TensorFlowAI Platform を使用して機械学習(ML)レコメンデーション システムを実装する方法を説明する、マルチパート チュートリアル シリーズのパート 2 です。このパートでは、Google Cloud Platform(GCP)の AI Platform を使用してレコメンデーション システムをトレーニングし、ハイパーパラメータを調整する方法を学びます。

シリーズは次のパートで構成されています。

このチュートリアルは、ユーザーがこのシリーズの前のチュートリアルを完了していることを前提としています。

目標

  • AI Platform でトレーニング ジョブを実行して MovieLens データセット レコメンデーションを実行する方法を学習する。
  • AI Platform のハイパーパラメータを調整し、MovieLens データセットの TensorFlow WALS レコメンデーション モデルを最適化する。

費用

このチュートリアルでは、有料サービスである Cloud StorageAI Platform を使用します。料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを作成できます。このチュートリアルの予測費用は $0.20 です。GCP を初めて使用する方は、無料トライアルをご利用いただけます。

始める前に

パート 1 の指示に従って GCP プロジェクトを設定してください。

モデルのトレーニング

このセットの最初のチュートリアルでは、TensorFlow での WALS アルゴリズムの実装について説明しました。このチュートリアルでは、AI Platform を使用してモデルをトレーニングする方法について説明します。ここでの「モデルのトレーニング」とは、評価 R の疎行列をユーザー因子行列 X とアイテム因子行列 Y に因子分解することを意味します。結果のユーザー因子は、レコメンデーション システムのベースモデルとして機能します。

パート 4 でレコメンデーション システムを GCP にデプロイします。

AI Platform でジョブをトレーニングする

AI Platform でモデルをトレーニングするには、Cloud Storage バケット フォルダであるジョブ ディレクトリを指定する必要があります。トレーニング ジョブを実行する手順は次のとおりです。

  1. プロジェクトで新しい Cloud Storage バケットを作成するか、既存のバケットを使用します。

    新しいバケットを作成するには、GCP Console で [Cloud Storage] > [ブラウザ] を選択し、[バケットの作成] をクリックします。

    このバケットに付けた名前を覚えておいてください。バケットを Compute Engine インスタンスと同じリージョンに配置することをおすすめします。

  2. シェルで、使用しているバケットの Cloud Storage バケット URL に環境変数 BUCKET を設定します。

    BUCKET=gs://[YOUR_BUCKET_NAME]
  3. gsutil ツールを使用して、MovieLens データセットをバケットにコピーします。

    gsutil cp -r data/u.data $BUCKET/data/u.data
    gsutil cp -r data/ratings.dat $BUCKET/data/ratings.dat
    gsutil cp -r data/ratings.csv $BUCKET/data/ratings.csv
  4. wals_ml_engine ディレクトリでトレーニング スクリプトを実行します。train オプションを設定し、Cloud Storage バケット URL とバケット内のデータファイルへのパスを指定してジョブを実行します。

    使用するデータセットは、パート 1 で選択したものです。区切り文字やヘッダーなど、データファイルに適合する追加オプションを設定します。

    cd wals_ml_engine
    • MovieLens 100k データセットの場合は、100k データファイルへのパスを指定します。

      ./mltrain.sh train ${BUCKET} data/u.data
    • 1m データセットの場合は、--delimiter オプションを指定し、1m データファイルへのパスを指定します。

      ./mltrain.sh train ${BUCKET} data/ratings.dat --delimiter ::
    • 20m データセットの場合は、--delimiter オプションと --headers オプションを使用します。

      ./mltrain.sh train ${BUCKET} data/ratings.csv --delimiter , --headers

    GCP Console の [AI Platform] セクションの [ジョブ] ページで、ジョブのステータスと出力をモニタリングできます。ジョブ出力を表示するには、[ログ] をクリックします。結果は、テストセットに対する二乗平均平方根誤差(RMSE)として記録されます。RMSE は、評価のテストセット全体について、予測されたユーザー評価のモデルの平均誤差を表します。

モデルを保存する

因子分解後、因子行列が numpy 形式で 5 つの個別ファイルに保存されるため、それらを使用してレコメンデーションを実行できます。 チュートリアルのパート 3 では、モデルファイルについて説明し、それらのモデルファイルを使用してレコメンデーションを生成する方法を紹介しています。 パート 4 では、レコメンデーションを実行する本番環境システムをデプロイする方法を紹介しています。モデルがローカルでトレーニングされると、コード パッケージ内の jobs フォルダにファイルが保存されます。AI Platform でモデルがトレーニングされると、Cloud Storage バケットにファイルが保存されます。このバケットは、前のセクションで説明した AI Platform ジョブの job-dir 引数によって指定されます。

MovieLens データセットの結果

行列因子分解の概算の結果は、テストセットの予測評価に基づきます。このテストセットは、前処理中に評価マトリックスから抽出されたものです。予測された評価と実際にユーザーが提供したテストセットの評価の差を計算するには、パート 1 で説明した損失公式を使用します。

$$ L = \sum_{u,i}(r_{ui} - x^{T}_{u} \cdot y_{i})^{2} $$

ここで、\(r_{ui}\) はテストセットの評価であり、\(x_{u}\) と \(y_{i}\) は、WALS 因子分解をトレーニング セットに適用することによって計算される行因子と列因子です。

行列因子分解のパフォーマンスは、いくつかのハイパーパラメータに大きく依存します。詳細については、このドキュメントの次のセクションで説明します。1m MovieLens データセットと表 1 に記載されているハイパーパラメータのデフォルト セットを使用して、テストセットで 1.06 の RMSE が達成されました。RMSE は、テストセットと比較した場合の予測評価の平均誤差に対応します。平均して、アルゴリズムによって生成された各評価は、1m データセットのテストセットにおける実際のユーザー評価の ±1.06 以内です。ユーザー定義の評価 3 により、2 と 4 の間の予測評価が生成される可能性がありますが、1 または 5 が生成される可能性は低いです。これは悪い結果ではありませんが、このデータセットの公開された結果では、1.0 未満の RMSE が達成されています。

結果を改善するには、表 1 にリストされているハイパーパラメータを調整する必要があります。

ハイパーパラメータの名前と説明 デフォルト値 スケール
latent_factors
潜在因子 K の数
5 UNIT_REVERSE_LOG_SCALE
regularization
L2 正規化定数
0.07 UNIT_REVERSE_LOG_SCALE
unobs_weight
モニタリングされない評価行列項目の重み
0.01 UNIT_REVERSE_LOG_SCALE
feature_wt_factor
モニタリングされている項目の重み
130 UNIT_LINEAR_SCALE
feature_wt_exp
機能加重指数
1 UNIT_LOG_SCALE
num_iters
交互最小二乗法の反復数
20 UNIT_LINEAR_SCALE

表 1. モデルで使用されるハイパーパラメータ名とデフォルト値

ハイパーパラメータの調整

ハイパーパラメータの最適なセットを見つけることは、機械学習モデルのパフォーマンスのために重要です。残念ながら、理論ではほんの僅かなガイダンスしか示されません。データ サイエンティストは、合理的な範囲でさまざまな値を試し、結果として生じるモデルのパフォーマンスをテストし、パフォーマンスが最高のパラメータの組み合わせを選択することによって最適化せざるを得ません。これは人的時間と計算リソースの面で時間とコストのかかるプロセスとなります。ハイパーパラメータの可能な組み合わせは、モデルの各種パラメータの数に基づき指数関数的に増加します。すべての可能性を試すことは現実的ではありません。このため、経験則、以前の経験、各パラメータの数学的特性の知識に基づいて、どの因子がモデルに影響するかについて推測する必要があります。

AI Platform には、ハイパーパラメータの最適なセットを自動的に検索するハイパーパラメータ調整機能が備わっています。この調整機能を使用するには、調整するハイパーパラメータのリストと、それらのパラメータの予想範囲または値を指定します。AI Platform は、ハイパーパラメータの空間上で検索を実行し、任意のさまざまなトライアルを実行して、すべてのトライアルで検出されたパフォーマンスが最高のハイパーパラメータのランキング リストを返します。検索プロセスでは、パラメータの推定スケール、ログ、リニアを指定することもできます。

ハイパーパラメータ調整について詳しくは、AI Platform のドキュメントをご覧ください。ハイパーパラメータの調整に使用される基本アルゴリズムの詳細については、ブログ投稿のベイズ最適化を使用した Cloud Machine Learning Engine のハイパーパラメータ調整をご覧ください。

ハイパーパラメータの構成ファイル

AI Platform のハイパーパラメータ リストは、JSON または YAML の構成ファイルで指定できます。このチュートリアルのサンプルコードでは、ハイパーパラメータの調整構成は config/config_tune.json で定義されています。このチュートリアルで調整した各ハイパーパラメータは、最小範囲、最大範囲、スケールとともにこのファイルにリストされています。パラメータの有効なスケール値については、ハイパーパラメータの調整の概要をご覧ください。

scaleTier パラメータで standard_gpu マシンタイプが指定されているため、調整は GPU が備わったマシンで行われます。構成ファイルを以下に示します。

{
  "trainingInput":{
    "scaleTier":"CUSTOM",
    "masterType":"standard_gpu",
    "hyperparameters":{
      "goal":"MINIMIZE",
      "params":[
        {
          "parameterName":"regularization",
          "type":"DOUBLE",
          "minValue":"0.001",
          "maxValue":"10.0",
          "scaleType":"UNIT_REVERSE_LOG_SCALE"
        },
        {
          "parameterName":"latent_factors",
          "type":"INTEGER",
          "minValue":"5",
          "maxValue":"50",
          "scaleType":"UNIT_REVERSE_LOG_SCALE"
        },
        {
          "parameterName":"unobs_weight",
          "type":"DOUBLE",
          "minValue":"0.001",
          "maxValue":"5.0",
          "scaleType":"UNIT_REVERSE_LOG_SCALE"
        },
        {
          "parameterName":"feature_wt_factor",
          "type":"DOUBLE",
          "minValue":"1",
          "maxValue":"200",
          "scaleType":"UNIT_LOG_SCALE"
        }
      ],
      "maxTrials":500
    }
  }
}

ハイパーパラメータの調整コード

モデルコードには、ハイパーパラメータを調整できる次の機能が含まれています。

  • 各ハイパーパラメータは、AI Platform でハイパーパラメータ調整ジョブに引数として渡されます。この例では、ジョブへのエントリ ポイントとして機能する task.py ファイルによって、ハイパーパラメータ引数が処理されます。引数の名前が、ハイパーパラメータ構成ファイルにリストされているハイパーパラメータ名と一致していることを確認する必要があります。
  • モデルにより、特殊タグ training/hptuning/metric を使用して TensorFlow サマリーが書き込まれます。このタグは、モデルの品質を評価する指標に設定されます。この例では、RMSE がテストセットの指標です。このサマリー指標を使用すると、AI Platform のハイパーパラメータ調整サービスの検索プロセスで、トライアルにランクを付けることができます。util.py のユーティリティ関数で summary 指標値が書き込まれます。

    summary = Summary(value=[Summary.Value(tag='training/hptuning/metric',
                                           simple_value=metric)])
    
    eval_path = os.path.join(args['output_dir'], 'eval')
    summary_writer = tf.summary.FileWriter(eval_path)
    
    # Note: adding the summary to the writer is enough for hyperparam tuning.
    # The ml engine system is looking for any summary added with the
    # hyperparam metric tag.
    summary_writer.add_summary(summary)
  • トライアルごとに個別の出力ディレクトリを用意することが重要です。出力ディレクトリは、TensorFlow サマリーと保存されたモデルを書き込むために使用されます。トライアルごとに異なる出力ディレクトリを作成しないと、各トライアルの結果によって以前のトライアルの結果が上書きされます。トライアルごとの固有ディレクトリの作成は、task.pyparse_arguments メソッドの次のコードによって処理されます。

    if args.hypertune:
      # if tuning, join the trial number to the output path
      trial = json.loads(os.environ.get('TF_CONFIG', '{}')).get('task', {}).get('trial', '')
      output_dir = os.path.join(job_dir, trial)
    else:
      output_dir = os.path.join(job_dir, args.job_name)

    ここでは、parse_arguments 関数によって調整と標準出力が区別され、それに応じて output_dir が変更されます。

ハイパーパラメータ調整ジョブの実行

次のコマンドは、100k データセットに対して調整ジョブを実行します。

./mltrain.sh tune $BUCKET data/u.data

BUCKET 変数が前に作成したバケットに設定されていることを確認してください。100k データセットはサイズが小さいため、多数のトライアルを実行できます(この例では 500 個)。

調整の結果

ハイパーパラメータの調整結果は、AI Platform のジョブデータに保存されます。このデータには、GCP Console の [AI プラットフォーム] の [ジョブ] ページでアクセスできます。図 1 に示されているように、ジョブの結果には、サマリー指標のすべてのトライアルに関する RMSE スコアの最高値が含まれます。100k MovieLens データセットに対する 500 個のトライアルのハイパーパラメータ調整の結果を確認できます。最高値はトライアル 384 で発生しました。

ハイパーパラメータ調整ジョブの結果(ジョブ 384 の結果を強調表示)
図 1. ハイパーパラメータ調整ジョブの結果

ハイパーパラメータを調整することで、最終結果が大きく異なる場合があります。この例では、100k テストセットに対するハイパーパラメータ調整により RMSE 0.98 を達成しました。これらのパラメータを 1m20m の各データセットに適用したところ、RMSE 値はそれぞれ 0.90 と 0.88 という結果になりました。最適なパラメータは表 2 に、調整前後の RMSE 値は表 3 にまとめられています。

ハイパーパラメータ名 説明 調整の値
latent_factors 潜在因子 K 34
regularization L2 正規化定数 9.83
unobs_weight モニタリングされていない重み 0.001
feature_wt_factor モニタリングされている重み 189.8
feature_wt_exp 機能加重指数 なし
num_iters 反復回数 なし

表 2. AI Platform のハイパーパラメータ調整で検出された値

MovieLens データセットにはリニアにモニタリングされる重みが使用されるため、機能加重指数は調整パラメータに含まれません。num_iters(反復回数パラメータ)にはデフォルト値が使用されています。

データセット デフォルトのハイパーパラメータでの RMSE ハイパーパラメータ調整後の RMSE
100k 1.06 0.98
1m 1.11 0.90
20m 1.30 0.88

表 3. 各 MovieLens データセットのテストセットでの RMSE 値の概要(ハイパーパラメータ調整前後)

次のステップ

ソリューションの TensorFlow でのレコメンデーション: Google アナリティクスのデータに適用する(パート 3)では、Google アナリティクスのライブデータにレコメンデーション モデルを適用する方法について説明します。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...