行列分解モデルを使用して暗黙的なフィードバックに基づくレコメンデーションを作成する

このチュートリアルでは、行列分解モデルを作成し、一般公開されている GA360_test.ga_sessions_sample テーブルの Google アナリティクス 360 ユーザー セッション データでトレーニングする方法について説明します。次に、行列分解モデルを使用して、サイトユーザー向けのコンテンツ レコメンデーションを生成します。

ユーザーのセッション継続時間などの間接的なユーザー設定情報を使用してモデルをトレーニングすることを、暗黙的なフィードバックによるトレーニングと呼びます。トレーニング データとして暗黙的なフィードバックを使用する場合、行列分解モデルは加重交互最小二乗アルゴリズムを使用してトレーニングされます。

データセットを作成する

ML モデルを保存する BigQuery データセットを作成します。

コンソール

  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    [BigQuery] ページに移動

  2. [エクスプローラ] ペインで、プロジェクト名をクリックします。

  3. [アクションを表示] > [データセットを作成] をクリックします。

  4. [データセットを作成する] ページで、次の操作を行います。

    • [データセット ID] に「bqml_tutorial」と入力します。

    • [ロケーション タイプ] で [マルチリージョン] を選択してから、[US(米国の複数のリージョン)] を選択します。

    • 残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。

bq

新しいデータセットを作成するには、--location フラグを指定した bq mk コマンドを使用します。使用可能なパラメータの一覧については、bq mk --dataset コマンドのリファレンスをご覧ください。

  1. データの場所が US に設定され、BigQuery ML tutorial dataset という説明の付いた、bqml_tutorial という名前のデータセットを作成します。

    bq --location=US mk -d \
     --description "BigQuery ML tutorial dataset." \
     bqml_tutorial

    このコマンドでは、--dataset フラグの代わりに -d ショートカットを使用しています。-d--dataset を省略した場合、このコマンドはデフォルトでデータセットを作成します。

  2. データセットが作成されたことを確認します。

    bq ls

API

定義済みのデータセット リソースを使用して datasets.insert メソッドを呼び出します。

{
  "datasetReference": {
     "datasetId": "bqml_tutorial"
  }
}

BigQuery DataFrames

このサンプルを試す前に、BigQuery DataFrames を使用した BigQuery クイックスタートの手順に沿って BigQuery DataFrames を設定してください。詳細については、BigQuery DataFrames のリファレンス ドキュメントをご覧ください。

BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の ADC の設定をご覧ください。

import google.cloud.bigquery

bqclient = google.cloud.bigquery.Client()
bqclient.create_dataset("bqml_tutorial", exists_ok=True)

サンプルデータを準備する

GA360_test.ga_sessions_sample テーブルのデータをモデル トレーニングに適した構造に変換し、このデータを BigQuery テーブルに書き込みます。次のクエリは、コンテンツごとに各ユーザーのセッション継続時間を計算します。この値を暗黙的なフィードバックとして使用することで、そのコンテンツに対するユーザーの好みを推測できます。

トレーニング データテーブルを作成するには、次の操作を行います。

  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    [BigQuery] に移動

  2. トレーニング データテーブルを作成します。クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    CREATE OR REPLACE TABLE `bqml_tutorial.analytics_session_data`
    AS
    WITH
      visitor_page_content AS (
        SELECT
          fullVisitorID,
          (
            SELECT
              MAX(
                IF(
                  index = 10,
                  value,
                  NULL))
            FROM
              UNNEST(hits.customDimensions)
          ) AS latestContentId,
          (LEAD(hits.time, 1) OVER (PARTITION BY fullVisitorId ORDER BY hits.time ASC) - hits.time)
            AS session_duration
        FROM
          `cloud-training-demos.GA360_test.ga_sessions_sample`,
          UNNEST(hits) AS hits
        WHERE
          # only include hits on pages
          hits.type = 'PAGE'
        GROUP BY
          fullVisitorId,
          latestContentId,
          hits.time
      )
    # aggregate web stats
    SELECT
      fullVisitorID AS visitorId,
      latestContentId AS contentId,
      SUM(session_duration) AS session_duration
    FROM
      visitor_page_content
    WHERE
      latestContentId IS NOT NULL
    GROUP BY
      fullVisitorID,
      latestContentId
    HAVING
      session_duration > 0
    ORDER BY
      latestContentId;
  3. トレーニング データのサブセットを表示します。クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    SELECT * FROM `bqml_tutorial.analytics_session_data` LIMIT 5;

    結果は次のようになります。

    +---------------------+-----------+------------------+
    | visitorId           | contentId | session_duration |
    +---------------------+-----------+------------------+
    | 7337153711992174438 | 100074831 | 44652            |
    +---------------------+-----------+------------------+
    | 5190801220865459604 | 100170790 | 121420           |
    +---------------------+-----------+------------------+
    | 2293633612703952721 | 100510126 | 47744            |
    +---------------------+-----------+------------------+
    | 5874973374932455844 | 100510126 | 32109            |
    +---------------------+-----------+------------------+
    | 1173698801255170595 | 100676857 | 10512            |
    +---------------------+-----------+------------------+
    

モデルを作成する

行列分解モデルを作成し、analytics_session_data テーブルのデータをトレーニングします。モデルは、すべての visitorIdcontentId ペアの信頼度評価を予測するようにトレーニングされます。信頼度の評価は、セッション継続時間の中央値を基準にセンタリングとスケーリングを行い作成されます。セッション継続時間が中央値の 3.33 倍を超えるレコードは、外れ値として除外されます。

次の CREATE MODEL ステートメントは、これらの列を使用してレコメンデーションを生成します。

  • visitorId: 訪問者 ID。
  • contentId: コンテンツ ID。
  • rating: 訪問者とコンテンツの各ペアについて計算された、0~1 の暗黙的な評価(センタリングおよびスケーリング済み)。
  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    CREATE OR REPLACE MODEL `bqml_tutorial.mf_implicit`
      OPTIONS (
        MODEL_TYPE = 'matrix_factorization',
        FEEDBACK_TYPE = 'implicit',
        USER_COL = 'visitorId',
        ITEM_COL = 'contentId',
        RATING_COL = 'rating',
        L2_REG = 30,
        NUM_FACTORS = 15)
    AS
    SELECT
      visitorId,
      contentId,
      0.3 * (1 + (session_duration - 57937) / 57937) AS rating
    FROM `bqml_tutorial.analytics_session_data`
    WHERE 0.3 * (1 + (session_duration - 57937) / 57937) < 1;

    クエリが完了するまでに約 10 分かかります。完了後、mf_implicit モデルが [エクスプローラ] ペインに表示されます。クエリは CREATE MODEL ステートメントを使用してモデルを作成するため、クエリの結果は表示されません。

トレーニングの統計情報を取得する

必要に応じて、Google Cloud コンソールでモデルのトレーニング統計情報を表示できます。

ML アルゴリズムがモデルを構築するには、さまざまなパラメータを使用してモデルのイテレーションを多数作成し、損失を最小限に抑えるモデルのバージョンを選択します。このプロセスを経験損失最小化と呼びます。モデルのトレーニング統計情報で、モデルの各反復処理に関連付けられた損失を確認できます。

モデルのトレーニング統計情報を表示する手順は次のとおりです。

  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    BigQuery に移動

  2. 左側のペインで、 [エクスプローラ] をクリックします。

    エクスプローラ ペインのボタンがハイライト表示されている。

    左側のペインが表示されていない場合は、 左側のペインを開くをクリックしてペインを開きます。

  3. [エクスプローラ] ペインで、プロジェクトを開き、[データセット] をクリックします。

  4. bqml_tutorial データセットをクリックします。検索機能やフィルタを使用してデータセットを見つけることもできます。

  5. [モデル] タブをクリックします。

  6. mf_implicit モデルをクリックし、[トレーニング] タブをクリックします。

  7. [表示形式] セクションで、[テーブル] をクリックします。結果は次のようになります。

    +-----------+--------------------+--------------------+
    | Iteration | Training Data Loss | Duration (seconds) |
    +-----------+--------------------+--------------------+
    |  5        | 0.0027             | 47.27              |
    +-----------+--------------------+--------------------+
    |  4        | 0.0028             | 39.60              |
    +-----------+--------------------+--------------------+
    |  3        | 0.0032             | 55.57              |
    +-----------+--------------------+--------------------+
    |  ...      | ...                | ...                |
    +-----------+--------------------+--------------------+
    

    [トレーニング データの損失] 列は、モデルのトレーニング後に計算された損失指標を表します。これは行列分解モデルであるため、この列には平均二乗誤差が表示されます。

モデルを評価する

ML.EVALUATE 関数を使用してモデルのパフォーマンスを評価します。 ML.EVALUATE 関数は、モデルから返された予測コンテンツ評価を、トレーニング中に計算された評価指標と照らし合わせて評価します。

次の手順でモデルを評価します。

  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    SELECT
      *
    FROM
      ML.EVALUATE(MODEL `bqml_tutorial.mf_implicit`);

    結果は次のようになります。

    +------------------------+-----------------------+---------------------------------------+---------------------+
    | mean_average_precision |  mean_squared_error   | normalized_discounted_cumulative_gain |    average_rank     |
    +------------------------+-----------------------+---------------------------------------+---------------------+
    |     0.4434341257478137 | 0.0013381759837648962 |                    0.9433280547112802 | 0.24031636088594222 |
    +------------------------+-----------------------+---------------------------------------+---------------------+
    

    ML.EVALUATE 関数の出力の詳細については、出力をご覧ください。

訪問者とコンテンツのペアのサブセットに対する予測評価を取得する

ML.RECOMMEND を使用して、5 人のサイト訪問者による各コンテンツの予測評価を取得します。

予測評価は次の手順で取得できます。

  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    SELECT
      *
    FROM
      ML.RECOMMEND(
        MODEL `bqml_tutorial.mf_implicit`,
        (
          SELECT
            visitorId
          FROM
            `bqml_tutorial.analytics_session_data`
          LIMIT 5
        ));

    結果は次のようになります。

    +-------------------------------+---------------------+-----------+
    | predicted_rating_confidence   | visitorId           | contentId |
    +-------------------------------+---------------------+-----------+
    | 0.0033608418060270262         | 7337153711992174438 | 277237933 |
    +-------------------------------+---------------------+-----------+
    | 0.003602395397293956          | 7337153711992174438 | 158246147 |
    +-------------------------------+---------------------+--  -------+
    | 0.0053197670652785356         | 7337153711992174438 | 299389988 |
    +-------------------------------+---------------------+-----------+
    | ...                           | ...                 | ...       |
    +-------------------------------+---------------------+-----------+
    

レコメンデーションの生成

予測された評価を使用して、訪問者 ID ごとに上位 5 つのおすすめコンテンツ ID を生成します。

レコメンデーションを生成する手順は次のとおりです。

  1. Google Cloud コンソールで、[BigQuery] ページに移動します。

    [BigQuery] に移動

  2. 予測評価をテーブルに書き込みます。クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    CREATE OR REPLACE TABLE `bqml_tutorial.recommend_content`
    AS
    SELECT
      *
    FROM
      ML.RECOMMEND(MODEL `bqml_tutorial.mf_implicit`);
  3. 訪問者ごとに上位 5 件の結果を選択します。クエリエディタに次のクエリを貼り付け、[実行] をクリックします。

    SELECT
      visitorId,
      ARRAY_AGG(
        STRUCT(contentId, predicted_rating_confidence)
        ORDER BY predicted_rating_confidence DESC
        LIMIT 5) AS rec
    FROM
      `bqml_tutorial.recommend_content`
    GROUP BY
      visitorId;

    結果は次のようになります。

    +---------------------+-----------------+---------------------------------+
    | visitorId           | rec:contentId   | rec:predicted_rating_confidence |
    +---------------------+-----------------+-------------------------  ------+
    | 867526255058981688  | 299804319       | 0.88170525357178664             |
    |                     | 299935287       | 0.54699439944935124             |
    |                     | 299410466       | 0.53424780863188659             |
    |                     | 299826767       | 0.46949603950374219             |
    |                     | 299809748       | 0.3379991197434149              |
    +---------------------+-----------------+---------------------------------+
    | 2434264018925667659 | 299824032       | 1.3903516407308065              |
    |                     | 299410466       | 0.9921995618196483              |
    |                     | 299903877       | 0.92333625294129218             |
    |                     | 299816215       | 0.91856701667757279             |
    |                     | 299852437       | 0.86973661454890561             |
    +---------------------+-----------------+---------------------------------+
    | ...                 | ...             | ...                             |
    +---------------------+-----------------+---------------------------------+