# Next Best Product (NBP) レコメンデーション

すべての顧客に、その人が次に最も求めそうなものを提示できます。

## 概要とユースケース

Treasure AIの機械学習プラットフォーム (AI Signal) のNBPワークフローは、顧客ごとに最も響きやすい商品・サービス・コンテンツのランク付きリストを生成します。誰が何をいつ購入したかを学習し、各顧客が次に求める可能性が最も高いものを予測します。

NBPは1つのワークフローの中で、相互に補完する3つのアルゴリズムを提供します。それぞれが顧客基盤の異なる部分をカバーするため、多くのチームは複数を併用します。

**協調フィルタリング (`als`)** は、顧客基盤全体にわたる行列分解を通じて潜在的な嗜好を学習します。アイテムのメタデータを明示的に与えなくても、「Xを買った人はYも買う傾向がある」といったパターンを発見します。3つの中で最も高品質なパーソナライゼーションであり、トランザクション履歴が豊富な既知の顧客に最も適しています。

**アイテム類似度 (`similar_to_latest`)** は、各顧客の直近の購入に最も似たアイテムを推奨します。トランザクションが1件以上ある顧客であれば機能し、新しいアイテムが頻繁に追加される状況でも高速かつ安定して動作します。

**トレンドアイテム (`popular`)** は、顧客基盤全体で最も購入されている、または最も閲覧されているアイテムを返します。履歴がまったくないコールドスタートの顧客にも対応でき、信頼できる全体向けのフォールバックとして機能します。

組み合わせ方については[カバレッジのためのアルゴリズムの組み合わせ](#%E3%82%AB%E3%83%90%E3%83%AC%E3%83%83%E3%82%B8%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B)を参照してください。

**主なユースケース**

- サイトやアプリの商品カルーセルをパーソナライズする
- メールやプッシュ通知のキャンペーンに商品レコメンデーションを組み込む
- 顧客が既に所有しているものを起点に、クロスセルや買い替えのジャーニーを構築する
- 購入と購入の間に、記事・動画・ポッドキャストなどのコンテンツを推奨する
- アルゴリズムを重ねてコールドスタートの穴を埋め、すべての顧客に何かを届ける


**特に効果が高いユーザー:** 専任のMLプラットフォームやデータサイエンスチームを持たずに、数百万件規模のプロファイルに対して顧客ごとのレコメンデーションを必要とするライフサイクルマーケター、パーソナライゼーション担当チーム、CRMマネージャー。

### 他のAI Signalsとの使い分け

| **知りたいこと**  | **使用するソリューション**  |
|  --- | --- |
| 過去の購買から見て、重要なのは誰か? | [RFM AI Signals](/ja/products/customer-data-platform/machine-learning/ai-signals/rfm-ai-signals): モデリング不要の記述的セグメント |
| この顧客がXを実行する可能性はどのくらいか? | [Propensity Scoring AI Signals](/ja/products/customer-data-platform/machine-learning/ai-signals/propensity-ai-signals): 定義したイベントごとの確率 |
| この顧客は将来どれだけの価値をもたらすか? | [CLTV AI Signals](/ja/products/customer-data-platform/machine-learning/ai-signals/cltv-ai-signals): 金額の予測とパーセンタイルランク |
| **次にどの商品を推奨すべきか?** | **NBP AI Signals (このページ)**: 商品・サービス・コンテンツのランク付きリスト |
| この顧客にどのアクションを取るべきか? | [NBA AI Signals](/ja/products/customer-data-platform/machine-learning/ai-signals/nba-ai-signals): 候補アクションから学習したユーザーごとのポリシー |


***NBPとNBAのどちら?** 読者が混同しやすいのはこの組み合わせだけです。NBPはカタログのアイテムを親和性でランク付けします。つまり、この人が最も求める可能性が高いものは何かを扱います。NBAは、実際に効果があった結果に基づいて、自社が制御する少数のマーケティング上の意思決定 (どのチャネル、どの配信時刻、どのオファー) に対する方針を学習します。NBPは購買と行動の履歴から動作します。NBAはアクションと成果のログのペアを必要とします。この2つは相性がよく、NBPで商品を選び、NBAでその訴求方法とタイミングを選ぶという組み合わせが可能です。*

*これらのシグナルは競合するものではなく、互いに補完します。そもそも誰にレコメンデーションを送るかを判断する際には、RFMやCLTVのスコアが有用な入力になります。*

## クイックスタート

NBPは、Treasure AI ML Batch API上の2つの関数として実行されます。

- **`nbp_train`** は選択したアルゴリズムをトランザクション履歴で学習し、ランキング指標を書き出して、`model_name` でモデルを登録します。
- **`nbp_predict`** は登録済みのモデルを読み込み、顧客ごとにアイテムのランク付きリストを書き出します。


入力はインタラクションごとに1行、3つの列で構成されます。ユーザー識別子、アイテム識別子、タイムスタンプです。3つとも列名を設定できるため、既存のテーブルで使用している列名をそのままパラメータに指定できます。NBPは生のトランザクション行から動作し、集計済みのサマリーは入力として受け付けません。完全なスキーマとデータ要件については[データ準備](#%E3%83%87%E3%83%BC%E3%82%BF%E6%BA%96%E5%82%99)を参照してください。

**設定が必要なパラメータはわずかです。** `input_table`、`output_table`、`model_name` が必須です。列名が `userid`、`itemid`、`tstamp` でない場合は `user_column`、`item_column`、`tstamp_column` を追加してください。それ以外には、デフォルトが `als` である `algorithm` を含め、すべて実用的なデフォルト値が設定されています。

セキュリティ
Treasure AI APIキーは、ワークフロー定義にリテラル値として記述せず、`td.apikey` という名前のWorkflowシークレットとして保存してください。シークレットとして参照することでキーがバージョン管理に含まれなくなり、チームは機密情報を安全に管理できます。詳細は [Treasure コンソール からのワークフローシークレットの設定](/products/customer-data-platform/data-workbench/workflows/setting-workflow-secrets-from-td-console) を参照してください。

### トレーニング

```yaml
# nbp_train.dig
# ステップ1: トレーニング。選択したアルゴリズムを学習し、`model_name` で登録します。

+train:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/
  method: POST
  headers:
    - authorization: "TD1 ${secret:td.apikey}"
    - X-TD-ML-SESSION-ID: ${session_id}
    - X-TD-ML-ATTEMPT-ID: ${attempt_id}
  store_content: true
  content:
    input_table: your_database.transactions
    output_table: your_database.nbp_train_metrics
    solution_name: nbp_train
    solution_arguments:
      model_name: "nbp_retail_als_v1"
      algorithm: "als"
      user_column: "user_id"
      item_column: "item_id"
      tstamp_column: "timestamp"

+print_response:
  echo>: "Training job submitted. Response: ${http.last_content}"

# トレーニングが完了するまでポーリングします。ジョブの実行中、APIはHTTP 408を返します。
# Treasure WorkflowはHTTP 200を受け取るまでリトライします。
+train_poll_status:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/${JSON.parse(http.last_content)['id']}/status
  method: GET
  headers:
    - authorization: "TD1 ${secret:td.apikey}"
```

**想定される出力:** トレーニング実行ごとに1行が記録され、`map_10` や `ndcg_10` といったランキングスコアを含む指標テーブルです。学習済みモデルは `model_name` でマネージドストレージに保存されます。指標の読み方については[トレーニング指標の読み方](#%E3%83%88%E3%83%AC%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E6%8C%87%E6%A8%99%E3%81%AE%E8%AA%AD%E3%81%BF%E6%96%B9)を参照してください。

### 予測

```yaml
# nbp_predict.dig
# ステップ2: 予測。登録済みモデルを読み込み、ランク付きレコメンデーションを書き出します。

+pred:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/
  method: POST
  headers:
    - authorization: "TD1 ${secret:td.apikey}"
    - X-TD-ML-SESSION-ID: ${session_id}
    - X-TD-ML-ATTEMPT-ID: ${attempt_id}
  store_content: true
  content:
    input_table: your_database.transactions
    output_table: your_database.nbp_recommendations
    solution_name: nbp_predict
    solution_arguments:
      model_name: "nbp_retail_als_v1"     # トレーニング実行と一致させる必要があります
      algorithm: "als"
      user_column: "user_id"
      item_column: "item_id"
      tstamp_column: "timestamp"
      topk: 10

+print_response:
  echo>: "Prediction job submitted. Response: ${http.last_content}"

# 予測が完了するまでポーリングします。ジョブの実行中、APIはHTTP 408を返します。
# Treasure WorkflowはHTTP 200を受け取るまでリトライします。
+pred_poll_status:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/${JSON.parse(http.last_content)['id']}/status
  method: GET
  headers:
    - authorization: "TD1 ${secret:td.apikey}"
```

**想定される出力:** 顧客ごとに1行、アイテム識別子のランク付き配列が出力されます。

```
user_id          rec_items
A1146YGPNU9EUL   [B007FHX9OK, B008DJIIG8]
44039871         [79255, 82886, 93487, 48930, 30495]
```

これらのワークフローの作成とスケジュール設定については、[Treasure Workflowを使ってみる](/products/customer-data-platform/data-workbench/workflows/getting-started-with-treasure-workflow)を参照してください。

## モデル設定

NBP AI Signalsの各関数は2種類の入力を受け取ります。指定するトランザクションテーブルと、渡すパラメータです。どちらも以下のデータ準備とワークフローパラメータで説明します。

各アルゴリズムの完全な `nbp_train` パラメータセットは[モデルタイプ](#%E3%83%A2%E3%83%87%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%97)に記載しているため、1つのテーブルからアルゴリズムを設定できます。

### `nbp_train`

`nbp_train` は1つのアルゴリズムをトランザクション履歴で学習し、再利用できる形で保存します。

#### データ準備

インタラクションごとに1行の**トランザクションレベルのテーブル**です。3つとも列名を設定できます。

| **フィールド**  | **型**  | **必須**  | **説明**  |
|  --- | --- | --- | --- |
| `userid` | VARCHAR | はい | 顧客識別子。`user_column` で列名を変更できます。 |
| `itemid` | VARCHAR | はい | アイテム識別子。商品、サービス、記事、動画など、あらゆるアセットを指定できます。`item_column` で列名を変更できます。 |
| `tstamp` | LONG | はい | インタラクションが発生した時刻。`tstamp_column` で列名を変更できます。 |


行の例:

```
userid           itemid       tstamp
A1146YGPNU9EUL   B007FHX9OK   1704067200
A1146YGPNU9EUL   B008DJIIG8   1706745600
44039871         79255        1707350400
```

**データ要件**

- **トランザクションレベルの行のみを使用してください。** NBPは内部で集計を行うため、集計済みのサマリーは入力として使用できません。
- **顧客ごとではなく、インタラクションごとに1行です。** 12回購入した顧客は12行を占めます。
- **`als` はトレーニングデータに存在するユーザーにしか推奨できません。** トレーニング時点で存在しなかった顧客に対しては、そのモデルからは何も返りません。[カバレッジのためのアルゴリズムの組み合わせ](#%E3%82%AB%E3%83%90%E3%83%AC%E3%83%83%E3%82%B8%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B)を参照してください。
- **`similar_to_latest` はコールドアイテムを推奨できません。** トレーニングデータに一度も出現しないアイテムは、このアルゴリズムでは推奨されません。


#### ワークフローパラメータ

アルゴリズム固有のオプションを含む完全なパラメータセットは、[モデルタイプ](#%E3%83%A2%E3%83%87%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%97)を参照してください。

| **パラメータ**  | **型**  | **デフォルト**  | **必須**  | **説明**  |
|  --- | --- | --- | --- | --- |
| `input_table` | string | — | はい | `dbname.table_name` 形式のソーストランザクションテーブル。 |
| `output_table` | string | — | はい | トレーニング指標の出力先テーブル。 |
| `model_name` | string | — | はい | 学習済みモデルを保存・取得するための一意の名前。Treasure AIアカウント単位で一意です。同じ名前を再利用すると、どのアルゴリズムで作成されたかにかかわらず以前のモデルが上書きされるため、名前にアルゴリズムを含めてください。 |
| `algorithm` | string | als | いいえ | `popular`、`als`、`similar_to_latest` のいずれか。[モデルタイプ](#%E3%83%A2%E3%83%87%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%97)を参照してください。 |
| `user_column` | string | userid | いいえ | 顧客識別子の列名。 |
| `item_column` | string | itemid | いいえ | アイテム識別子の列名。 |
| `tstamp_column` | string | tstamp | いいえ | タイムスタンプの列名。 |
| `rating_column` | string | — | いいえ | 明示的な評価値や重みの列がある場合、その列名。 |
| `filter_num` | int | 0 | いいえ | トレーニングに含めるために、アイテムがインタラクションを持つ必要のあるユーザー数の下限。`0` はフィルタリングなしを意味します。値を上げるとロングテールのアイテムが除外され、モデルが小さくなります。 |
| `metrics_table` | string | — | いいえ | `output_table` とは別にトレーニング指標を書き出したい場合の、`dbname.table_name` 形式の出力先テーブル。 |


#### 出力

トレーニング実行ごとに1行が記録され、`session_id` で識別される指標の履歴テーブルです。指標の列名には使用した `topk` の値が含まれるため、`topk: 10` で実行すると `map_10`、`ndcg_10` などが書き出されます。

| **フィールド**  | **型**  | **説明**  |
|  --- | --- | --- |
| `session_id` | INTEGER | この実行を生成したワークフローセッション。モデルからトレーニングジョブをたどる際に使用します。 |
| `model_params` | VARCHAR | 使用したパラメータセットをシリアライズしたもの。実行間の比較に役立ちます。 |
| `map_{topk}` | FLOAT | Mean Average Precision at K。 |
| `ndcg_{topk}` | FLOAT | Normalized Discounted Cumulative Gain at K。 |
| `precision_{topk}` | FLOAT | Precision at K。 |
| `recall_{topk}` | FLOAT | Recall at K。 |
| `mrr_{topk}` | FLOAT | Mean Reciprocal Rank at K。 |


このテーブルは追記型のため、時系列で推移を追える履歴が蓄積されます。数値の読み方については[トレーニング指標の読み方](#%E3%83%88%E3%83%AC%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E6%8C%87%E6%A8%99%E3%81%AE%E8%AA%AD%E3%81%BF%E6%96%B9)を参照してください。

### `nbp_predict`

`nbp_predict` は登録済みのモデルを読み込み、ランク付きレコメンデーションを書き出します。

#### データ準備

[`nbp_train`](#nbp_train)で説明したものと同じ、トランザクションレベルのテーブル形式です。予測の入力はトレーニング時の形式と一致している必要があります。

#### ワークフローパラメータ

| **パラメータ**  | **型**  | **デフォルト**  | **必須**  | **説明**  |
|  --- | --- | --- | --- | --- |
| `input_table` | string | — | はい | レコメンデーションを生成する対象ユーザーのテーブル。`dbname.table_name` 形式で指定します。 |
| `output_table` | string | — | はい | レコメンデーションの出力先テーブル。 |
| `model_name` | string | — | はい | トレーニング時に使用した名前と一致させる必要があります。 |
| `algorithm` | string | als | いいえ | 登録済みモデルが使用するアルゴリズム: `popular`、`als`、`similar_to_latest` のいずれか。トレーニング時に使用したアルゴリズムと一致させる必要があります。 |
| `output_mode` | string | overwrite | いいえ | `overwrite` はテーブルを置き換えます。顧客基盤全体を対象とする実行に適しています。増分的な一部のみを対象とする場合は `append` を使用してください。 |
| `user_column` | string | userid | いいえ | 顧客識別子の列名。 |
| `item_column` | string | itemid | いいえ | アイテム識別子の列名。 |
| `tstamp_column` | string | tstamp | いいえ | タイムスタンプの列名。 |
| `rating_column` | string | — | いいえ | 明示的な評価値や重みの列がある場合、その列名。 |
| `topk` | int | 10 | いいえ | 顧客ごとに推奨するアイテム数。最大100です。 |
| `lastk` | int | 1 | いいえ | レコメンデーションの生成に使用する、顧客の直近トランザクション数。`similar_to_latest` にのみ適用されます。[アイテム類似度 (`similar_to_latest`)](#%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E9%A1%9E%E4%BC%BC%E5%BA%A6--similar_to_latest-)を参照してください。 |


#### 出力

顧客ごとに1行が出力されます。

| **フィールド**  | **型**  | **説明**  |
|  --- | --- | --- |
| `user_id` | VARCHAR | 入力から引き継がれた顧客識別子。 |
| `rec_items` | ARRAY | 推奨アイテムの識別子。予測されたランクの順に並び、最も強いものが先頭になります。長さは `topk` で制御します。 |


```
user_id          rec_items
A1146YGPNU9EUL   [B007FHX9OK, B008DJIIG8]
44039871         [79255, 82886, 93487, 48930, 30495]
```

**レコメンデーションの活用。** 出力を顧客テーブルに結合して `rec_items` をマスターセグメントのルールで使用できる属性にし、標準のCDPアクティベーションワークフローを通じてJourneys、Triggers、Personalization、Segment Builder、Agent Consoleに連携します。配列は順序付きのため、先頭の要素を取り出せば単一のメインとなるレコメンデーションになり、配列全体はカルーセルに使用できます。

## モデルタイプ

NBPは[RecTools](https://github.com/MobileTeleSystems/RecTools)ライブラリの3つのアルゴリズムに対応しています。顧客に何を求めるか、そして何をカバーできるかが異なるため、多くのチームは複数を併用します。

| **アルゴリズム**  | **カバー範囲**  | **強み**  | **主なトレードオフ**  |
|  --- | --- | --- | --- |
| `popular` (トレンドアイテム) | 新規顧客を含むすべての顧客 | 高速かつ安定していて、必ず何かを返す | パーソナライズされない |
| `als` (協調フィルタリング) | トレーニングデータに存在するユーザー | パーソナライゼーションの品質が最も高い | 大規模データでは低速。コールドスタートには対応できない |
| `similar_to_latest` (アイテム類似度) | トランザクションが1件以上あるすべての顧客 | 新規顧客と新しいカタログアイテムに強い | トレーニングに出現しないアイテムは推奨できない |


以下の各セクションでは、そのアルゴリズムの完全な `nbp_train` パラメータセットを掲載しているため、1つのテーブルから設定できます。

### トレンドアイテム (`popular`)

顧客基盤全体で最も購入されている、または最も閲覧されているアイテムを推奨します。パーソナライゼーションは行われず、対象となるすべての顧客が同じリストを受け取ることがあります。

その価値はカバレッジにあります。`popular` は履歴がまったくない顧客にも機能するため、標準的なフォールバックの層として、また他の2つを評価する際のベースラインとして適しています。

#### モデル固有のパラメータ

**太字**のパラメータはこのアルゴリズム固有のものです。それ以外は3つのアルゴリズムで共通です。

| **パラメータ**  | **型**  | **デフォルト**  | **必須**  | **説明**  |
|  --- | --- | --- | --- | --- |
| `input_table` | string | — | はい | `dbname.table_name` 形式のソーストランザクションテーブル。 |
| `output_table` | string | — | はい | トレーニング指標の出力先テーブル。 |
| `model_name` | string | — | はい | 学習済みモデルを保存・取得するための一意の名前。 |
| `algorithm` | string | als | いいえ | `"popular"`。デフォルトが `als` のため、明示的に設定する必要があります。 |
| `user_column` | string | userid | いいえ | 顧客識別子の列名。 |
| `item_column` | string | itemid | いいえ | アイテム識別子の列名。 |
| `tstamp_column` | string | tstamp | いいえ | タイムスタンプの列名。 |
| `rating_column` | string | — | いいえ | 明示的な評価値や重みの列がある場合、その列名。 |
| `filter_num` | int | 0 | いいえ | トレーニングに含めるために、アイテムが必要とするユーザー数の下限。 |
| **`popularity`** | string | n_users | いいえ | 人気度の測定方法。たとえば、生のインタラクション数ではなくユニークユーザー数で測定します。 |
| **`period`** | string | — | いいえ | 人気度を測定する移動ウィンドウ。たとえば直近30日間です。指定しない場合は全履歴で測定されるため、長く販売されているアイテムが有利になります。 |
| **`begin_from`** | string | — | いいえ | 人気度のウィンドウの開始日を固定で指定します。`period` の代替です。 |
| `filter_viewed` | boolean | false | いいえ | 顧客が既にインタラクションを持つアイテムを除外します。 |


このアルゴリズムは、トレーニング時に `factors`、`regularization`、`iterations`、`alpha`、`tunable`、`k`、`distance`、`similar_items_table`、`topk` を使用しません。

#### ワークフロー例

```yaml
solution_arguments:
  model_name: "nbp_retail_popular_v1"
  algorithm: "popular"
  user_column: "user_id"
  item_column: "item_id"
  tstamp_column: "timestamp"
  period: "30D"
  filter_viewed: true
```

### 協調フィルタリング (`als`)

Alternating Least Squares (交互最小二乗法) による行列分解のアプローチです。ユーザー・アイテムのインタラクション行列を2つのより小さな行列の積として表現し、顧客基盤全体の行動から潜在的な嗜好を学習します。商品のメタデータを必要とせずに、併買のパターンを発見します。

3つの中で最も高品質なパーソナライゼーションであり、同時に最も負荷が高い方法です。大規模データでは低速で、トレーニングデータに存在したユーザーにしか推奨できないため、コールドスタートをカバーするには別のアルゴリズムとの併用が必要です。

#### モデル固有のパラメータ

**太字**のパラメータはこのアルゴリズム固有のものです。`similar_items_table` と `topk` は `similar_to_latest` と共通で、それ以外は3つのアルゴリズムで共通です。

| **パラメータ**  | **型**  | **デフォルト**  | **必須**  | **説明**  |
|  --- | --- | --- | --- | --- |
| `input_table` | string | — | はい | `dbname.table_name` 形式のソーストランザクションテーブル。 |
| `output_table` | string | — | はい | トレーニング指標の出力先テーブル。 |
| `model_name` | string | — | はい | 学習済みモデルを保存・取得するための一意の名前。 |
| `algorithm` | string | als | いいえ | `"als"`。デフォルトのため、未設定のままでもかまいません。 |
| `user_column` | string | userid | いいえ | 顧客識別子の列名。 |
| `item_column` | string | itemid | いいえ | アイテム識別子の列名。 |
| `tstamp_column` | string | tstamp | いいえ | タイムスタンプの列名。 |
| `rating_column` | string | — | いいえ | 明示的な評価値や重みの列がある場合、その列名。 |
| `filter_num` | int | 0 | いいえ | トレーニングに含めるために、アイテムが必要とするユーザー数の下限。 |
| **`factors`** | int | 10 | いいえ | 潜在表現のサイズ。大きくすると細かなニュアンスを捉えられますが、メモリと時間を消費します。 |
| **`regularization`** | float | 0.1 | いいえ | 正則化の強さ。ヘビーバイヤーへの過学習を抑えます。 |
| **`iterations`** | int | 10 | いいえ | 最適化の反復回数。 |
| **`alpha`** | float | 50 | いいえ | 観測されたインタラクションに適用する信頼度の重み。 |
| **`tunable`** | boolean | false | いいえ | デフォルト値を使う代わりに、データからハイパーパラメータを学習します。品質は向上しますが、実行時間とメモリが予測しづらくなるため、制約の厳しいスケジュールでは避けてください。 |
| `similar_items_table` | string | — | いいえ | アイテムごとの類似アイテム上位をこのテーブルに書き出します。`dbname.table_name` 形式で指定します。[類似アイテムテーブル](#%E9%A1%9E%E4%BC%BC%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB)を参照してください。 |
| `topk` | int | 10 | いいえ | `similar_items_table` を設定した場合に、アイテムごとに書き出す類似アイテム数。 |
| `filter_viewed` | boolean | false | いいえ | 顧客が既にインタラクションを持つアイテムを除外します。 |


このアルゴリズムは `popularity`、`period`、`begin_from`、`k`、`distance` を使用しません。

#### ワークフロー例

```yaml
solution_arguments:
  model_name: "nbp_retail_als_v1"
  algorithm: "als"
  user_column: "user_id"
  item_column: "item_id"
  tstamp_column: "timestamp"
  factors: 32
  iterations: 15
  similar_items_table: your_database.nbp_similar_items
```

### アイテム類似度 (`similar_to_latest`)

顧客が直近に購入したものに最も似たアイテムを推奨します。類似度は商品のメタデータではなく、顧客基盤全体での共起から算出されます。

品質とカバレッジの両面で、他の2つの中間に位置します。トランザクションが1件以上ある顧客であれば、トレーニングデータに含まれていなかった人も含めてパーソナライズされたリストを受け取れます。これは `als` にはできないことです。頻繁に変わるカタログにも対応できます。一方で制約は逆向きで、トレーニングに一度も出現しないアイテムは推奨できません。

#### モデル固有のパラメータ

**太字**のパラメータはこのアルゴリズム固有のものです。`similar_items_table` と `topk` は `als` と共通で、それ以外は3つのアルゴリズムで共通です。

| **パラメータ**  | **型**  | **デフォルト**  | **必須**  | **説明**  |
|  --- | --- | --- | --- | --- |
| `input_table` | string | — | はい | `dbname.table_name` 形式のソーストランザクションテーブル。 |
| `output_table` | string | — | はい | トレーニング指標の出力先テーブル。 |
| `model_name` | string | — | はい | 学習済みモデルを保存・取得するための一意の名前。 |
| `algorithm` | string | als | いいえ | `"similar_to_latest"`。デフォルトが `als` のため、明示的に設定する必要があります。 |
| `user_column` | string | userid | いいえ | 顧客識別子の列名。 |
| `item_column` | string | itemid | いいえ | アイテム識別子の列名。 |
| `tstamp_column` | string | tstamp | いいえ | タイムスタンプの列名。 |
| `rating_column` | string | — | いいえ | 明示的な評価値や重みの列がある場合、その列名。 |
| `filter_num` | int | 0 | いいえ | トレーニングに含めるために、アイテムが必要とするユーザー数の下限。 |
| **`k`** | int | 20 | いいえ | アイテムごとに考慮する最近傍の数。 |
| **`distance`** | string | bm25 | いいえ | 類似度の尺度。`bm25`、`tf-idf`、`cosine` のいずれかです。 |
| `similar_items_table` | string | — | いいえ | アイテムごとの類似アイテム上位をこのテーブルに書き出します。`dbname.table_name` 形式で指定します。[類似アイテムテーブル](#%E9%A1%9E%E4%BC%BC%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB)を参照してください。 |
| `topk` | int | 10 | いいえ | `similar_items_table` を設定した場合に、アイテムごとに書き出す類似アイテム数。 |
| `filter_viewed` | boolean | false | いいえ | 顧客が既にインタラクションを持つアイテムを除外します。 |


このアルゴリズムは `popularity`、`period`、`begin_from`、`factors`、`regularization`、`iterations`、`alpha`、`tunable` を使用しません。

**`lastk` は予測時にこのアルゴリズムへ適用されます。** デフォルトでは直近1件のトランザクションのみがレコメンデーションの起点になります。`lastk` を上げるとその件数の直近アイテムを使用し、`lastk * topk` 件の候補をランク付けして上位 `topk` 件を返します。複数商品をまとめて購入する顧客では品質が向上することが多い一方、時間とメモリを消費します。

#### ワークフロー例

```yaml
solution_arguments:
  model_name: "nbp_retail_sim_v1"
  algorithm: "similar_to_latest"
  user_column: "user_id"
  item_column: "item_id"
  tstamp_column: "timestamp"
  k: 20
  distance: "bm25"
```

## 関連トピック

### カバレッジのためのアルゴリズムの組み合わせ

単一のアルゴリズムですべての顧客をカバーすることはできません。そのため、3つすべてを学習して出力をマージするパターンが推奨されます。

| **顧客**  | **利用できる最適なアルゴリズム**  |
|  --- | --- |
| トレーニングデータに存在し、履歴がある | `als` (最も高品質なパーソナライゼーション) |
| トランザクションが1件以上あるが、トレーニングには含まれていない | `similar_to_latest` |
| まったく新規で、トランザクションがない | `popular` |


各アルゴリズムをそれぞれの `model_name` で個別のモデルとして学習し、それぞれで予測を実行したうえで、`als`、`similar_to_latest`、`popular` の優先順でマージします。各顧客は自分に利用できる最も優先度の高いレコメンデーションを受け取り、`popular` によって誰も空のまま残らないことが保証されます。

マージはNBPの外側、自社のワークフローまたはSQLで行います。NBPは1つのタスク内で複数のモデルを組み合わせることはしません。

### 類似アイテムテーブル

`als` と `similar_to_latest` はいずれも、`similar_items_table` を設定することでトレーニング時にアイテム間の類似度テーブルを書き出せます。

| **フィールド**  | **型**  | **説明**  |
|  --- | --- | --- |
| `target_item_id` | VARCHAR | 比較の起点となるアイテム。 |
| `item_id` | VARCHAR | 類似アイテム。 |
| `score` | FLOAT | 類似度の強さ。値が大きいほど似ています。 |


このテーブルはそれ自体でも有用です。ユーザーごとの予測実行なしに「この商品を買った人はこれも買っています」のようなモジュールを実現でき、`filter_num` によってトレーニングから除外されたものの購入履歴が1件以上ある顧客に対して推奨する手段にもなります。

### トレーニング指標の読み方

トレーニングを実行するたびに、指定した `topk` における5つのランキング指標が指標テーブルに1行追記されます。

| **指標**  | **評価する内容**  |
|  --- | --- |
| `precision_{topk}` | 推奨したアイテムのうち、実際に関連していたものの割合。リストに無駄がないかを示します。 |
| `recall_{topk}` | 関連するアイテムのうち、リストに入ったものの割合。リストに漏れがないかを示します。 |
| `map_{topk}` | 順位ごとに平均した精度。上位にある正解ほど高く評価されます。 |
| `ndcg_{topk}` | MAPに似ていますが、順位による減衰がより滑らかです。ランキング品質の代表的な指標として使われます。 |
| `mrr_{topk}` | 最初の関連アイテムがどれだけ上位に現れるか。カルーセルではなく単一のレコメンデーションを表示する場合に最も重要です。 |


5つすべて、値が大きいほど良好です。どれを主要指標にするかは表示方法によって決まります。単一のメイン枠であれば `mrr`、ランク付きのカルーセルであれば `ndcg` または `map`、後段でフィルタリングする候補プールとして使うのであれば `recall` です。

このテーブルは追記型のため、単一の数値よりも推移を見るのが最も有用です。同じアルゴリズムを実行間で比較し、さらに各アルゴリズムを `popular` をベースラインとして比較してください。トレンドアイテムに勝てないパーソナライズモデルは、実行コストに見合っていません。

### スケールと並列化

トレーニングは低頻度での実行を前提としており、多くのチームでは週次です。予測はコストが低く、保存済みのモデルに対して日次または時間単位で実行できます。

大規模なプロファイル基盤では、入力テーブルを複数の同時タスクに分割することで予測を並列化できます。分割方法には2つの制約があります。

- **ランダムではなく、必ずユーザー単位で分割してください。** ユーザーの途中で分割すると、複数のインスタンスから重複したレコメンデーションが生成されます。
- **並列化にはオーバーヘッドがあります。** おおよそ1,000万プロファイルを下回る場合、単一タスクの方が並列実行より早く完了します。


トレーニングのスケール特性はアルゴリズムによって異なります。`als` はトレーニングに存在しないユーザーへ推奨できないため、データセット全体を学習する必要があります。`similar_to_latest` と `popular` は代表的なサンプルで学習し、顧客基盤全体に対して予測できます。これが非常に大規模な場合の一般的なアプローチです。すべてのアイテムを含むトレーニングデータでは、`similar_to_latest` はカタログ全体が含まれていないと、欠けているアイテムをコールドアイテムとして扱います。

### モデルの保存と有効期限

学習済みモデルは `model_name` でマネージドストレージに保存され (Treasure AIアカウント単位で一意)、`nbp_predict` が自動的に取得します。

計画時に押さえておくべき点が2つあります。

- **モデルは6か月で失効します。** 失効後の予測実行には新しく学習したモデルが必要になるため、キャンペーン中に気づくのではなく、期限前に再トレーニングしてください。
- **`model_name` を再利用すると以前のモデルが上書きされます。** どのアルゴリズムで作成されたかは問われません。3つすべてのアルゴリズムを実行するパターンが推奨されるため、`nbp_retail_als_v1` のように名前にアルゴリズムを含め、あるトレーニング実行が別のモデルを意図せず置き換えないようにしてください。


## よくある質問

### はじめに

**どのようなデータが必要ですか?** インタラクションごとに1行、ユーザー識別子、アイテム識別子、タイムスタンプを持つトランザクションレベルのテーブルです。3つとも列名を設定できます。履歴の長さに最低要件はありませんが、`als` は履歴が多いほど大きく改善します。

**どのアルゴリズムを使うべきですか?** 多くのチームは3つすべてを使用します。既存顧客には `als`、トランザクションが1件以上あるすべての顧客には `similar_to_latest`、フォールバックには `popular` です。この優先順で出力をマージしてください。[カバレッジのためのアルゴリズムの組み合わせ](#%E3%82%AB%E3%83%90%E3%83%AC%E3%83%83%E3%82%B8%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B)を参照してください。

**商品ではなくコンテンツを推奨できますか?** はい。`itemid` には記事、動画、ポッドキャストのエピソード、サービスなど、あらゆるアセットを指定できます。NBPはインタラクションごとにユーザー、アイテム、時刻のみを必要とし、アイテムが実際に何であるかは一切参照しません。

### データとカバレッジ

**トランザクション履歴のない新規顧客はどう扱えばよいですか?** `popular` を全体向けのフォールバックとして使用してください。顧客側に何も必要とせず、常にリストを返すため、他の2つの下に重ねるのが標準的なパターンです。

**一部の顧客に `als` からレコメンデーションが返らないのはなぜですか?** ALSはトレーニングデータに存在したユーザーにしか推奨できません。前回のトレーニング以降に増えた顧客はALSからは見えません。トレーニング頻度を上げるのではなく、`similar_to_latest` または `popular` でカバーしてください。

**NBPは発売直後の商品を推奨できますか?** `similar_to_latest` からは推奨されません。トレーニングに一度も出現しないアイテムは推奨できないためです。`popular` は売れ始めれば拾い上げます。新商品の立ち上げでは、モデルが浮上させることを期待するのではなく、マーチャンダイジングのルールで露出させてください。

**集計済みのデータを使えますか?** いいえ。NBPは生のトランザクション行を必要とし、集計は自身で行います。これは事前集計が必要なRFMとは逆です。

### チューニングと運用

**`topk` と `lastk` は何をするパラメータですか?** `topk` は各顧客が受け取るアイテム数で、デフォルトは10、最大は100です。`lastk` はレコメンデーションに反映する顧客の直近トランザクション数で、`similar_to_latest` にのみ適用されます。複数商品をまとめて購入する顧客では、`lastk` を上げると改善することが多いです。

**どのくらいの頻度で再トレーニングすべきですか?** トレーニングのコストに対して嗜好の変化は緩やかなため、多くのチームには週次が適しています。予測は保存済みモデルに対して、日次または時間単位でより頻繁に実行してください。モデルは6か月で失効するため、少なくともその頻度での再トレーニングが必要です。

**`als` の `tunable` は有効にすべきですか?** 実行時間とメモリの変動を許容できる場合にのみ有効にしてください。データからハイパーパラメータを学習し、通常は品質が向上しますが、固定スケジュールでのリソース見積もりが難しくなります。

**`filter_num` は役立ちますか?** インタラクションを持つユーザーが少なすぎるアイテムを除外するため、モデルが小さくなり、トレーニングが高速になります。トレードオフは除外されたアイテムが推奨されなくなることなので、ロングテールのカバレッジが重要でない場合にのみ値を上げてください。

### スケールと制限

**データセットが2億プロファイルあります。NBPで扱えますか?** 注意すれば可能です。`similar_to_latest` と `popular` は代表的なサンプルで学習し、顧客基盤全体に対して予測してください。`als` はそのユーザーをカバーするためにデータセット全体で学習する必要があります。予測はユーザー単位で複数の並列タスクに分割してください。この規模でのサイジングについては、Treasure AIのアカウントチームにお問い合わせください。

**並列化はどのくらいの規模から有効ですか?** おおよそ1,000万プロファイルを超える規模からです。[スケールと並列化](#%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%A8%E4%B8%A6%E5%88%97%E5%8C%96)を参照してください。

**新しいトランザクションが届くたびに増分学習できますか?** いいえ。トレーニングは低頻度でのフル実行を前提としています。部分学習やオンライン学習には対応していないため、定期的なフル再トレーニングをスケジュールしてください。

**キャンペーンでレコメンデーションを活用するにはどうしますか?** `rec_items` を顧客テーブルに結合してマスターセグメントの属性にし、標準のCDPアクティベーションワークフローを通じてJourneys、Triggers、Personalization、Segment Builder、Agent Consoleに連携します。

## 用語集

| **用語**  | **定義**  |
|  --- | --- |
| コールドスタート | 履歴がほとんど、またはまったくないユーザーやアイテムに対して推奨する際の問題。 |
| コールドアイテム | トレーニング時のインタラクションが少なすぎて、単独では推奨できないアイテム。 |
| 協調フィルタリング | アイテムの属性ではなく、多数のユーザーの行動パターンに基づいてアイテムを推奨する手法。 |
| ALS | Alternating Least Squares (交互最小二乗法)。潜在的なユーザーとアイテムの嗜好を学習する行列分解の手法。 |
| 行列分解 | ユーザー・アイテムのインタラクション行列を、2つのより小さな行列の積として表現すること。 |
| 人気度モデル | 顧客基盤全体で最も購入されている、または最も閲覧されているアイテムを推奨するモデル。 |
| `similar_to_latest` | 顧客の直近のトランザクションに最も似たアイテムを推奨するアルゴリズム。 |
| `topk` | 顧客ごとに返されるアイテム数。デフォルトは10、最大は100。 |
| `lastk` | `similar_to_latest` でレコメンデーションに反映する直近トランザクションの数。 |
| `filter_num` | トレーニングに含めるために、アイテムがインタラクションを持つ必要のあるユーザー数の下限。 |
| MAP、nDCG、Precision、Recall、MRR at K | トレーニング指標テーブルに書き出される標準的なランキング指標。いずれも値が大きいほど良好です。[トレーニング指標の読み方](#%E3%83%88%E3%83%AC%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E6%8C%87%E6%A8%99%E3%81%AE%E8%AA%AD%E3%81%BF%E6%96%B9)を参照してください。 |
| RecTools | NBPを支えるオープンソースのレコメンデーションライブラリ。 |
| PrecisionML | NBP AI Signalsを支える本番MLインフラストラクチャ。AI Signalsスイート全体で共通です。 |