フレーズからフィルタへのマッピング:製品フィルタのセマンティック検索

この記事では、フィルタ抽出システムを支えるフレーズからフィルタへのマッピングを、どのように生成・拡張するかについて説明します。これらのマッピングは、検索クエリからの自然言語フレーズを構造化された製品フィルタに結び付けます。

問題:自然言語からのフィルタ抽出

ユーザーが「mini pc with 16gb ram」を検索するとき、以下の抽出が必要です。

  • フォームファクタ: Mini PC

  • メインメモリ: 16

しかし、ユーザーは同じ意図をさまざまな方法で表現します。

  • "16gb ram mini pc"

  • "mini computer 16 gb memory"

  • "small pc 16gb"

  • "compact desktop with 16 gigs"

これらすべてのフレーズのバリエーションを正しいフィルタ値にマッピングするシステムが必要です。

2段階プロセス

フレーズマッピングは2つのステップで生成します。

  1. ステップ 3a: 順列とフィーチャー固有のルールを使用して、製品フィーチャーから基本フレーズを生成します。
  2. ステップ 4: 埋め込みを使用して意味的類似性で拡張します。

このハイブリッドアプローチは、ルールベースの精度と意味的な柔軟性を組み合わせます。

ステップ 3a:基本フレーズの生成

フィーチャーメタデータ

すべての製品フィーチャーは、フィーチャーシーケンス内にメタデータを持ちます。

  • 見出し: カテゴリ名(例: プロセッサフィーチャーでは「Processing」)

  • 単位: 測定単位(例: メモリでは「GB」、周波数では「GHz」)

このメタデータがフレーズ生成をガイドします。

順列ベースの生成

各フィーチャー値について、以下すべての順列を生成します。

  • 見出し: "processor"

  • フィーチャーキー: "series"

  • 値: "i5"

  • 単位: (シリーズの場合はなし)

これにより、次のものが生成されます。

  • "processor series i5"

  • "series processor i5"

  • "i5 processor series"

  • "i5 series processor"

  • "processor i5"

  • "series i5"

  • "i5"

すべての順列により、単語の順序に関係なくクエリをマッチングできます。

値+単位の組み合わせ

単位を持つフィーチャー(メモリ、ストレージ、周波数)の場合、スペースありとスペースなしの両方のバリアントを生成します。

  • "16 gb"(スペースあり)

  • "16gb"(スペースなし)

これらは他のコンポーネントと組み合わせられます。

  • "16gb ram"

  • "ram 16gb"

  • "processor 16gb"

ポート接尾辞ルール

接続フィーチャー(USB、HDMI、DisplayPort)には、ポート接尾辞を追加します。

  • "usb port"

  • "usb ports"

  • "2 usb ports"

  • "hdmi port"

これにより、「mini pc with 2 hdmi ports」のようなクエリにマッチングします。

フィーチャー固有のルール

各フィーチャータイプにはカスタムフレーズ生成があります。

プロセッサシリーズ(i3、i5、Nシリーズ):

  • Coreプロセッサの呼称は、製造元名、Coreブランド、組み合わせ形式のバリアントを生成します。

  • Nシリーズプロセッサ(N100など)も同様のパターンの組み合わせを生成します。

  • それぞれが「processor」を含む複数の順列を生成します。

メインメモリ:

  • 数値は、スペースありとスペースなしのGBバリアント("16gb"、"16 gb")を生成します。

  • 自動的に "ram" と "memory" の修飾語が付加されます("16gb memory"、"16 gb ram")。

SSDストレージ:

  • 数値はGBバリアント("512gb"、"512 gb")を生成します。

  • 値が1024以上の場合、TBバリアントを自動生成します(例: 1024GB → 1TB)。

  • 自動的に "ssd" と "storage" の修飾語が付加されます("512gb ssd"、"512 gb storage")。

フォームファクタ:

  • Mini PC → スペースなしの形式を含む複数のバリアント

  • All-in-One → "all in one"、"aio"、省略形

  • Thin Client → スペースあり/なしのバリアント

  • Industrial PC → 省略形と完全形

世代:

  • 数値の世代値は次のようになります: "12th gen"、"12th generation"、"gen 12"

コア数:

  • 2 → "dual core"

  • 4 → "quad core"

  • 6 → "hexa core"

  • 8 → "octa core"

  • すべて "[n] core processor" バリアントを生成します。

イーサネット:

  • "1000" → ["gigabit ethernet", "gbe", "1gbps"]

  • "2500" → ["2.5gbe", "2.5 gigabit", "2.5gbps"]

オペレーティングシステム:

  • "Windows 11" → ["windows", "windows 11", "win 11"]

  • "Ubuntu" → ["linux", "ubuntu"]

  • "FreeDOS" → ["freedos", "no os", "without os"]

単独値のホワイトリスト

誤マッチを防ぐため、特定のフィーチャーのみ単独値マッチングを許可します。

  • シリーズ: "i3"、"i5"、"N100"(ただし単一文字は不可)

  • プロセッサモデル: "N100"、"1335U"

  • オペレーティングシステム: "Windows"、"Linux"、"Ubuntu"

  • 世代: "12th"、"13th"、"14th"

  • プロセッサブランド: "Intel"、"ARM"

例えば、クエリが「2 hdmi ports」の場合、"2" が "2 cores" にマッチすべきではありません。長さチェックにより、単一文字や非常に短い曖昧な値が単独でマッチするのを防ぎます。イーサネットやポートのように明示的な単位コンポーネントを持つフィーチャーは、単位が付与された場合にのみ単独組み合わせを生成します。

衝突防止

メモリとストレージの値は重複します(両方に64、128、256などがあります)。ステップ4では、値の範囲ルールを適用して曖昧さを解消します。

  • 64 GB以下: メインメモリ(RAM)

  • 128 GB以上: SSDストレージ

  • 65〜127 GBの範囲: スキップ(曖昧)

明示的な修飾語("ram"/"memory" または "ssd"/"storage")を含むフレーズはこのルールを上書きし、任意の値にマッチできます。

さらに、多数の無関係なフィルタにマッチする曖昧な一般用語は、後処理による衝突解決中に除外されます。"connectivity"、"audio"、"display"、"processor"、"physical" のような用語は、複数のファセットにわたって曖昧さを生み出します。

ステップ 4:意味的拡張

N-gram抽出

実際の検索クエリから頻出フレーズを抽出します。単語1つ(「mini」のような1-gram)から長いシーケンス(「mini pc with 16gb ram ssd」のような最大6-gram)までを対象とします。少なくとも3回出現したフレーズのみが保持されます。このフィルタリングアプローチにより、ノイズを低減しつつ、実際のユーザー言語パターンを保持します。

フィルタ検索テキストの生成

各フィルタ値について、検索テキストを生成します。

メインメモリ:16:

  • "16gb ram memory"

  • "16 main memory"

  • "main memory 16"

SSDストレージ:512:

  • "512gb storage ssd"

  • "512 ssd storage"

  • "ssd storage 512"

これらの検索テキストは、埋め込み空間内でフィルタを表現します。

埋め込みとマッチング

クエリフレーズとフィルタ検索テキストの両方を埋め込みに変換し、それらの間のコサイン類似度を計算します。設定されたしきい値を超える類似度スコアを持つフレーズは、そのフィルタのマッピングに追加されます。

手動シードフレーズ

拡張の前に、信頼性の高い手動シードを注入します。

"Series:i5": [
    "i5",
    "core i5",
    "intel i5",
    "intel core i5",
    "i5 processor",
    "cpu i5",
]

これらのシードは、各フィルタに対して正しいと分かっている中心的なフレーズを表します。最大類似度スコアで含めることで、拡張アルゴリズムが類似した意味を持つ関連フレーズを見つけるように導きます。これらのシードは常に類似度1.0を取得し、拡張をガイドします。

増分埋め込み

フレーズとフィルタ検索テキストの両方の埋め込みをキャッシュします。新しいクエリが到着したとき:

  1. 既存の埋め込みをロード
  2. 新しいフレーズのみを埋め込み
  3. キャッシュに追加

これにより、変更のないデータを再埋め込みすることを避けます。詳細は埋め込み戦略を参照してください。

衝突解決

類似度マッチングの完了後、メモリフィルタとストレージフィルタの間の衝突を解決します。

数値ベースの曖昧さ解消:

  • 数値を含む曖昧なフレーズの場合: 値が64以下のフレーズはメモリのみに保持し、64より大きい場合はストレージのみに保持します。

  • これにより、"16gb" がSSDストレージフィルタにマッチするのを防ぎ、"512gb" がメモリフィルタにマッチするのを防ぎます。

明示的な修飾語によるルール上書き:

  • "ram"、"memory"、"cpu"、"processor" キーワードを含むフレーズ → メモリのみ

  • "ssd"、"storage"、"disk"、"nvme"、"drive" キーワードを含むフレーズ → ストレージのみ

  • 例: "processor 8gb" は数値であるにもかかわらずメモリにマッピングされます。

曖昧な用語:

  • "connectivity"、"audio"、"display" のように、複数の無関係なフィルタにマッチするフレーズは削除します。

出力形式

最終的なマッピングは、類似度(高い順)、次に長さ(短い順)でソートされます。

{
  "Main Memory:16": [
    {"phrase": "16gb ram", "similarity": 1.0},
# ... (implementation details omitted)

フィルタ抽出との統合

これらのマッピングは、フィルタ抽出アルゴリズムを支えます。

  1. クエリが到着: "mini pc with 16gb ram"
  2. フレーズを抽出: ["mini pc", "16gb ram", "mini", "pc", "16gb", "ram"]
  3. マッピングを使用してフレーズをフィルタにマッチング
  4. フィルタを返す: {"Form Factor": ["Mini PC"], "Main Memory": ["16"]}

詳細はフィルタ抽出アルゴリズムを参照してください。

保存と配布

フレーズマッピングはJSONファイルとして永続化され、システム全体で使用されます。

  • 基本マッピングファイル: ステップ3aで生成され、ルールベースのフレーズを含みます。

  • 拡張マッピングファイル: ステップ4で生成され、意味的拡張の結果を含みます。

拡張マッピングは以下で使用されます。

  • クエリページ生成: クエリテキストからフィルタを抽出

  • 検索サービス: リアルタイムのフィルタ抽出API

  • 製品マッチング: 抽出されたフィルタで製品をフィルタリング

パフォーマンス特性

基本生成(ステップ3a):

  • 処理時間はフィルタ値の数に応じてスケールします。

  • 多数の基本フレーズバリアントを生成します。

  • 生成中のメモリ使用量は中程度に保たれます。

意味的拡張(ステップ4):

  • 処理時間はクエリ量と埋め込みサイズに応じてスケールします。

  • 出力には基本生成よりも大幅に多くのフレーズが含まれます。

  • 埋め込みストレージによりメモリ要件が増加します。

拡張は類似度計算のためCPUバウンドです。NumPyとBLASアクセラレーションを使用すると、行列演算が大幅に高速化されます。

SEOパイプラインとの統合

フレーズマッピング生成は、SEOパイプラインのステップ3aと4です。

  1. ステップ 0: ソースデータの埋め込み - 製品、部品、記事
  2. ステップ 1: クエリの取得 - GSC、Google Ads、ライブ、Algolia
  3. ステップ 2: クエリの結合 - すべてのソースをマージ
  4. ステップ 3a: 基本フレーズマッピングの生成 ← 現在地
  5. ステップ 3b: クエリの埋め込み - ベクトルに変換
  6. ステップ 4: フレーズマッピングの拡張 ← 現在地
  7. ステップ 5: クエリのクラスタリング - ページにグループ化
  8. ステップ 6: 製品マッチング - クエリと製品のマッチング
  9. ステップ 7: クエリページの構築 - HTMLを生成
  10. ステップ 8: 関連検索の生成 - 関連クエリを検索
  11. ステップ 11: Valkeyへのマイグレーション - 検索サービスにロード

完全なフローはSEOパイプライン概要を参照してください。

なぜ2つのステップなのか?

基本生成(ステップ3a)は以下を提供します。

  • 精度: ルールベースのフレーズが期待どおりに正確にマッチします。

  • カバレッジ: 順列により、すべての語順をカバーします。

  • 制御: フィーチャー固有のルールがドメイン知識を処理します。

意味的拡張(ステップ4)は以下を提供します。

  • 柔軟性: 予期していなかったフレーズを発見します。

  • 実際のユーザー言語: 実際の検索クエリから学習します。

  • 同義語: 同等のフレーズを見つけます("16gb" に対する "16 gigs")。

これらを組み合わせることで、精度と再現率のバランスを取ります。

参考文献

技術的概念

モデルドキュメント

関連記事

まとめ

フレーズとフィルタのマッピングは2つのステップで生成します。

ステップ 3a(基本生成):

  • 見出し、キー、値、単位のすべての順列を生成

  • フィーチャー固有のルールを適用(プロセッサシリーズ、メモリ、ストレージ、フォームファクタ)

  • 接続フィーチャーにポート接尾辞を追加

  • 特定のフィーチャーの単独値にホワイトリストを適用

  • ルールから基本フレーズセットを出力

ステップ 4(意味的拡張):

  • 実際の検索クエリからn-gramフレーズを抽出

  • フレーズとフィルタ検索テキストを埋め込む

  • しきい値以上の類似度スコアを持つフレーズをマッチング

  • 手動シードフレーズを注入して拡張をガイド

  • メモリ/ストレージの衝突を解決

  • 拡張および曖昧さを解消したフレーズセットを出力

その結果、期待されるフレーズ(ルールによる)と予期しないバリエーション(意味的類似性による)の両方を処理する包括的なマッピングが得られます。これらのマッピングは、クエリページ、検索、製品マッチングにわたってフィルタ抽出を支えます。


← ドキュメントインデックスに戻る