すべてのプロダクト
Search
ドキュメントセンター

Platform For AI:SimRank++ 類似度アルゴリズムの使用

最終更新日:Oct 30, 2025

このトピックでは、推薦システムで使用される SimRank 協調フィルタリングアルゴリズムについて説明します。これには、アルゴリズムの原理やパーソナライズされた推薦シナリオでの最適化が含まれます。また、このトピックでは、本番環境で SimRank++ アルゴリズムを使用する方法についても説明します。

概要

SimRank アルゴリズムは、構造的なコンテキストにおけるオブジェクト間の類似度を測定するために使用されます。その中心的な考え方は、オブジェクト a とオブジェクト b がオブジェクト c とオブジェクト d に関連し、かつオブジェクト c がオブジェクト d に類似している場合、オブジェクト a はオブジェクト b に類似していると見なされる、というものです。さらに、各オブジェクトはそれ自体と最も類似しており、その類似度は 1 です。SimRank アルゴリズムは、既存のオブジェクトの類似度を使用して、それらに関連する他のオブジェクトの類似度を計算します。

SimRank アルゴリズムは、単純で直感的なグラフ理論モデルに基づいています。これは、有向グラフ G = (V, E) 内のオブジェクト間の類似度のメジャーです。V はアプリケーションドメイン内のすべてのオブジェクトを示す頂点のコレクションであり、E はオブジェクト間の関係を示すエッジのコレクションです。グラフ内のオブジェクト image.svg について、入力エッジに関連付けられた入力近傍のコレクションは image.svg と表され、出力エッジに関連付けられた出力近傍のコレクションは image.svg と表されます。オブジェクト image.svg とオブジェクト image.svg の間の類似度は image.svg と表され、次の数式に基づいて計算されます。

image.svg

この数式は、オブジェクト image.svg とオブジェクト image.svg の間の類似度が、オブジェクト image.svg とオブジェクト image.svg に関連するすべてのオブジェクト間の類似度に依存することを示しています。数式中の image.svg は定数の減衰係数です。

上記の数式は行列形式で表現できます。たとえば、S は有向グラフ G の SimRank 類似度行列を示します。image.svg はオブジェクト image.svg とオブジェクト image.svg の間の類似度スコアを示します。P は有向グラフ G の隣接行列を示し、image.svg は頂点 image.svg から頂点 image.svg へのエッジの数を示します。

image.svg

上記の数式は、次の行列で表現できます。

image.svg

image.svg 行列は image.svg 列正規化行列を示します。image.svgimage.svg の単位行列です。image.svgimage.svg 行列の主対角要素を 1 に設定することを指定します。

SimRank++ アルゴリズムは、SimRank アルゴリズムに基づいて新しい関数 image.svg を導入し、二部グラフ内のノード間の遷移確率を示します。

image.svg

次のセクションでは、新しいアルゴリズムの反復数式について説明します。

image.svg

image.svg

image.svgimage.svg は任意の 2 つのクエリを示します。image.svgimage.svg は任意の 2 つの広告を示し、image.svgimage.svg の係数は次の数式を使用して定義されます。

image.svg

image.svg

SimRank++ アルゴリズムは、「重み」と「証拠値」を使用して元の計算結果を改良することにより、前述の 2 つの側面で SimRank アルゴリズムを拡張します。

SimRank++ アルゴリズムは、2008 年に Antonellis によって、スポンサード広告検索ドメインにおけるクエリリライティングアプリケーションのために特別に提案されました。

推薦システムでのアルゴリズムの使用

元の SimRank++ アルゴリズムは、計算広告ドメインでクエリリライティングを実行するために使用されます。ほとんどの場合、最近の期間の累積クリック動作データを使用して、クエリ間および広告間の関係を計算します。

クエリによって表現されるクエリ意図は、短期間で安定する可能性があります。したがって、複数日の動作データを使用して類似度を計算することは合理的です。

推薦システムに明確な意図を持つクエリが存在しない場合、クリックやその他の動作に基づくユーザー-アイテム二部グラフを SimRank++ アルゴリズムの入力として使用できます。

クエリの関連性に制限がない推薦シナリオでは、ユーザーの意図が曖昧になることがあります。ユーザーは同時に複数の興味を持つことがあり、その興味は時間とともに変化する可能性があります。

さらに、ユーザー数はクエリ数よりもはるかに多く、数百万から数十億に及ぶことが多く、これは SimRank++ アルゴリズムの実装に大きな課題をもたらします。

前述の理由から、セッションベースの行動二部グラフを使用してアイテム間の類似度を計算することをお勧めします。セッション内のユーザーの興味は集中しており、複数のアイテムカテゴリにまたがることはありません。明示的なセッション ID 追跡がないシナリオでは、concat(user_id, date) をセッション ID として使用できます。

増分計算

セッション ID が多数ある場合、計算の実現可能性を確保するために、複数日のデータをマージしてアルゴリズムの入力としないことをお勧めします。

カバレッジの問題を解決するために、増分計算ソリューションが提供されています。SimRank++ アルゴリズムツールキットは、複数日にわたるアイテムの類似度データを保持します。T 日目のアイテム類似度を計算するために、アルゴリズムは T-1 日目のアイテム類似度を使用して類似度行列を初期化します。ツールキットはセッションの類似度データを保持しません。

最後に、複数日からの類似度スコアがアイテムの最終的な類似度スコア image.svg として累積されます。

image.svg

image.svg は割引係数です。以前の類似度スコアが現在のスコアに累積される際に、割引が適用されます。時間が長いほど、割引が大きくなります。

注: 複数日にわたって累積された類似度スコアからの類似度スコア image.svg は保証されません。ビジネス要件に基づいてスコアを正規化する必要があります。

改善点 1: 人気度抑制

推薦シナリオでは、介入が適用されない場合、アルゴリズムは人気のあるアイテムを他の多くのアイテムと類似していると見なす可能性があります。これは、人気のあるアイテムがより多くの露出機会を得るためです。この問題を解決するために、SimRank アルゴリズムツールキットは人気度抑制メカニズムを導入しています。

具体的には、行動二部グラフから各アイテムに対応するエッジの重みを合計して、人気アイテムを特定します。 z-score 変換を、 image.svg で指定されたアイテムの人気度に適用します。

image.svg

image.svg を 0 から 1 の範囲の単調減少関数に変換します。

image.svg

エッジの元の重みに image.svg を乗じたものを新しい重みとして使用します。これは、ランダムウォーク中に人気のあるアイテムに向かって移動する際の抵抗を増加させることと等価です。

改善点 2: プリファレンスカテゴリによる重み付けの再設定

推薦シナリオでは、偶発的なクリックによりユーザーのクリック動作にノイズが含まれることがあります。ノイズの影響を軽減するために、行動二部グラフの重みは、アイテムカテゴリに対するユーザープリファレンスの計算に基づいて調整されます。

特定のユーザーの image.svg アイテムカテゴリに対するプリファレンスは、次の数式を使用して計算されます。

image.svg

アイテム image.svg の重みは image.svg から image.svg に変更されます。アイテム image.svgimage.svg カテゴリに属します。

入力と出力のフォーマット

パーティションテーブルなどの入力テーブルには、次の列が含まれます。

  • user_id: ユーザー ID、セッション ID、クエリ、またはその他のタイプ。

  • item_id: アイテム ID またはその他のタイプ。

  • weight: double タイプの重み。

  • category (オプション): アイテムのカテゴリまたはその他のタイプ。この列を指定して精度を向上させることができます。

  • 入力テーブルには、重複する <user_id, item_id> バイナリグループを含めることはできません。事前に重みをマージする必要があります。

  • カテゴリデータを使用してアルゴリズムのパフォーマンスを向上させる場合、列の値が null のレコードは削除されます。カテゴリ列に null 値が含まれていないか確認してください。

  • 注: 同じクエリに対する重みの分散を特定の範囲内に維持してください。分散が非常に大きい場合、重み遷移行列の要素値が 0 になり、取得率が大幅に低下します

    • min-max、z-score、log、または sigmoid などの変換を適用して、事前に重み列を正規化または標準化することをお勧めします。

    • また、input_weight_normalizer パラメーターを設定することもできます。

  • アルゴリズムのパフォーマンスを向上させるには、二部グラフのエッジの重みを設定する必要があります。

    • ctr を重みとして使用すると、ctr の値が大きいレコードの露出回数 (pv) が非常に少なくなる可能性があるため、ノイズデータが導入される場合があります。

    • この場合、log(1+click) をエッジの重みとして使用できます。

  • データをクレンジングし、特定のノイズデータをフィルターで除外することをお勧めします。

    • 特定のクエリに基づいて click/sum(click) < threshold データをフィルターで除外できます。たとえば、threshold = 3e - 5 です。

アイテム類似度の出力テーブルは次のフォーマットで、パーティション列を含むことができます。

  • item1: アイテムの ID。

  • item2: 類似アイテムの ID。

  • cumulative_score: 複数日のデータから計算された累積類似度スコア (最終結果としてフィールド値を使用)。

  • score: その日のデータから計算された類似度スコア。空の場合があります。

注: および cumulative_score の値は正規化されていません。

クエリ類似度の出力テーブルは次のフォーマットで、パーティション列を含むことができます。

  • query1: 元のクエリ。

  • query2: 類似クエリ。

  • score: 類似度スコア。

ジョブの送信

  1. simrank_plus_plus-1.3.jar アルゴリズムパッケージをダウンロードします。

  2. アルゴリズムパッケージを MaxCompute プロジェクトにアップロードします。

    image.png

  3. DataWorks で ODPS MR ノードを作成し、次のコマンドを実行してジョブを送信します。ODPS SQL ノードを作成するとエラーが発生する可能性があります。

    --@resource_reference{"simrank_plus_plus-1.3.jar"}
    jar -resources simrank_plus_plus-1.3.jar
    -classpath simrank_plus_plus-1.3.jar
    com.aliyun.pai.simrank.SimRankDriver
    -project ${max_compute_project}
    -end_point http://service.cn-hangzhou.maxcompute.aliyun.com/api
    -access_id ${access_id}
    -access_key ${access_key}
    -input_table simrank_i2i_input
    -input_table_partition ds=${bizdate}
    -output_table simrank_i2i_output
    -output_table_partition ds=${bizdate}
    -init_partition ds=${yesterday}
    -session_column device_id
    -item_column item_id
    -category_column cate_lv3_id
    -num_matmul_reducer 2000
    ;

パラメーター

パラメーター

タイプ

説明

デフォルト値

access_id

string

Alibaba Cloud アカウントの AccessKey ID。

なし

access_key

string

Alibaba Cloud アカウントの AccessKey シークレット。

なし

sts_token

string

Alibaba Cloud アカウントのセキュリティトークン。

end_point

string

MaxCompute のエンドポイント。詳細については、「エンドポイント」をご参照ください。

なし

project

string

デフォルトの MaxCompute プロジェクト。

なし

input_table

string

入力テーブルの名前。

なし

input_table_partition

string

入力テーブルのパーティション。

なし

init_partition

string

アイテム類似度テーブルのパーティション。アイテム類似度行列の初期化に使用されます。

なし。ほとんどの場合、前日のパーティションがアイテム類似度行列の初期化に使用されます。

output_table

string

アイテム類似度テーブル。

なし

output_table_partition

string

出力テーブルのパーティション。

なし

session_output_table

string

クエリ類似度テーブル。

なし

session_output_table_partition

string

クエリ類似度テーブルのパーティション。

なし

session_column

string

入力テーブルのクエリ列の名前。

user_id

item_column

string

入力テーブルのアイテム列の名前。

item_id

category_column

string

入力テーブルのアイテムカテゴリ列の名前。

なし

job_name

string

ジョブの名前。中間テーブルのプレフィックスでもあります。このパラメーターを設定すると、中断されたジョブを再開できます。ジョブ名が一意であることを確認してください。

UUID の文字列が自動的に生成されます。

debug

bool

デバッグモードを有効にするかどうかを指定します。

false

iter_times

int

アルゴリズムの反復回数。

3

decay_factor

float

SimRank アルゴリズムの定数減衰係数。有効値: (0,1)。

0.8

discount_factor

float

時間とともに減少する類似度スコアの減衰係数。有効値: (0,1]。このパラメーターは増分計算にのみ使用されます。

0.95

sim_threshold

float

SimRank アルゴリズムの反復で使用される類似度のしきい値。

0.000001

weight_threshold

float

二部グラフのエッジの重みのしきい値。

1e-6

input_weight_normalizer

string

重みの正規化関数。例: LOG10(1+weight)

なし

zero_spread_weight_cnt

int

重み遷移行列スコア内のゼロ値の数。ゼロ値は、重みの分散が非常に高いことを示します。

100

default_evidence

float

SimRank++ アルゴリズムで使用されるデフォルトの証拠の重み。有効値: (0,0.5)。

0.25

evidence_amplifier

float

証拠の重みの増幅係数。有効値: [default_evidence, evidence_amplifier]。

1/decay_factor

anti_popular

bool

「ハリー・ポッター効果」を処理するために人気度抑制機能を有効にするかどうかを指定します。

true

item_block_size

int

アイテム行列のブロックサイズ。パフォーマンスに関連します。このパラメーターは変更しないことをお勧めします。パラメーター値が小さいと、行列ブロッキングはトリガーされません。

50000

session_block_size

int

クエリ行列のブロックサイズ。パフォーマンスに関連します。このパラメーターは変更しないことをお勧めします。パラメーター値が小さいと、行列ブロッキングはトリガーされません。

50000

matmul_strategy

int

行列ブロッキング戦略。有効値: 2、3、4。パラメーター値が小さいと、行列ブロッキングはトリガーされません。

4

matmul_reducer_memory

int

行列乗算の最初のジョブにおける reducer のメモリ。単位: MB。

行列ブロッキングがトリガーされた場合、デフォルト値は 12288 です。行列ブロッキングがトリガーされない場合、デフォルト値は 3072 です。

matmul_split_size

int

行列乗算における mapper のスライスサイズ。単位: MB。

行列ブロッキングがトリガーされた場合、デフォルト値は 16 です。行列ブロッキングがトリガーされない場合、デフォルト値は 256 です。

num_matmul_reducer

int

行列乗算の最初のジョブにおける reducer の数。

行列ブロッキングがトリガーされた場合、デフォルト値は自動的に計算されます。行列ブロッキングがトリガーされない場合、デフォルト値は関与しません。

num_matmul_reducer2

int

行列乗算の 2 番目のジョブにおける reducer の数。ブロッキングがトリガーされない場合、行列乗算の 2 番目のジョブの reducer は不要です。

なし

evidence_split_size

int

証拠行列における mapper のスライスサイズ。単位: MB。

16

num_evidence_reducer1

int

証拠行列の最初のジョブにおける reducer の数。

なし

num_evidence_reducer2

int

証拠行列の 2 番目のジョブにおける reducer の数。

なし

priority

int

ジョブの優先度。

1

クエリリライティングなどの検索シナリオでは、anti_popular パラメーターを false に設定できます。推薦シナリオでは、このパラメーターを true に設定できます。

ケース分析

検索シナリオでは、入力データ量は約 1,700 万、クエリ数は 120 万、アイテム数は 150 万です。次のパラメーターを使用すると、全体のプロセスは約 87 分で完了します。

--@resource_reference{"simrank_plus_plus-1.0.jar"}
jar -resources simrank_plus_plus-1.0.jar
-classpath simrank_plus_plus-1.0.jar
com.aliyun.pai.simrank.SimRankDriver
-project ${project}
-end_point http://service.cn-shanghai.maxcompute.aliyun.com/api
-access_id ${access_id}
-access_key ${access_key}
-input_table ${input_table}
-input_table_partition dt=20240512
-output_table simrank_i2i_score
-output_table_partition dt=20240512
-session_output_table simrank_q2q_score
-session_output_table_partition dt=20240512
-output_table_lifecycle 7
-session_column query_word
-item_column item_id
-category_column category
-anti_popular false
-num_matmul_reducer 2000
-num_evidence_reducer1 1000
-num_evidence_reducer2 200