フレーズからフィルタへのマッピング:製品フィルタのセマンティック検索
この記事では、フィルタ抽出システムを支えるフレーズからフィルタへのマッピングを、どのように生成・拡張するかについて説明します。これらのマッピングは、検索クエリからの自然言語フレーズを構造化された製品フィルタに結び付けます。
問題:自然言語からのフィルタ抽出
ユーザーが「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つのステップで生成します。
このハイブリッドアプローチは、ルールベースの精度と意味的な柔軟性を組み合わせます。
ステップ 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を取得し、拡張をガイドします。
増分埋め込み
フレーズとフィルタ検索テキストの両方の埋め込みをキャッシュします。新しいクエリが到着したとき:
- 既存の埋め込みをロード
- 新しいフレーズのみを埋め込み
- キャッシュに追加
これにより、変更のないデータを再埋め込みすることを避けます。詳細は埋め込み戦略を参照してください。
衝突解決
類似度マッチングの完了後、メモリフィルタとストレージフィルタの間の衝突を解決します。
数値ベースの曖昧さ解消:
-
数値を含む曖昧なフレーズの場合: 値が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)
フィルタ抽出との統合
これらのマッピングは、フィルタ抽出アルゴリズムを支えます。
- クエリが到着: "mini pc with 16gb ram"
- フレーズを抽出: ["mini pc", "16gb ram", "mini", "pc", "16gb", "ram"]
- マッピングを使用してフレーズをフィルタにマッチング
- フィルタを返す:
{"Form Factor": ["Mini PC"], "Main Memory": ["16"]}
詳細はフィルタ抽出アルゴリズムを参照してください。
保存と配布
フレーズマッピングはJSONファイルとして永続化され、システム全体で使用されます。
-
基本マッピングファイル: ステップ3aで生成され、ルールベースのフレーズを含みます。
-
拡張マッピングファイル: ステップ4で生成され、意味的拡張の結果を含みます。
拡張マッピングは以下で使用されます。
-
クエリページ生成: クエリテキストからフィルタを抽出
-
検索サービス: リアルタイムのフィルタ抽出API
-
製品マッチング: 抽出されたフィルタで製品をフィルタリング
パフォーマンス特性
基本生成(ステップ3a):
-
処理時間はフィルタ値の数に応じてスケールします。
-
多数の基本フレーズバリアントを生成します。
-
生成中のメモリ使用量は中程度に保たれます。
意味的拡張(ステップ4):
-
処理時間はクエリ量と埋め込みサイズに応じてスケールします。
-
出力には基本生成よりも大幅に多くのフレーズが含まれます。
-
埋め込みストレージによりメモリ要件が増加します。
拡張は類似度計算のためCPUバウンドです。NumPyとBLASアクセラレーションを使用すると、行列演算が大幅に高速化されます。
SEOパイプラインとの統合
フレーズマッピング生成は、SEOパイプラインのステップ3aと4です。
- ステップ 0: ソースデータの埋め込み - 製品、部品、記事
- ステップ 1: クエリの取得 - GSC、Google Ads、ライブ、Algolia
- ステップ 2: クエリの結合 - すべてのソースをマージ
- ステップ 3a: 基本フレーズマッピングの生成 ← 現在地
- ステップ 3b: クエリの埋め込み - ベクトルに変換
- ステップ 4: フレーズマッピングの拡張 ← 現在地
- ステップ 5: クエリのクラスタリング - ページにグループ化
- ステップ 6: 製品マッチング - クエリと製品のマッチング
- ステップ 7: クエリページの構築 - HTMLを生成
- ステップ 8: 関連検索の生成 - 関連クエリを検索
- ステップ 11: Valkeyへのマイグレーション - 検索サービスにロード
完全なフローはSEOパイプライン概要を参照してください。
なぜ2つのステップなのか?
基本生成(ステップ3a)は以下を提供します。
-
精度: ルールベースのフレーズが期待どおりに正確にマッチします。
-
カバレッジ: 順列により、すべての語順をカバーします。
-
制御: フィーチャー固有のルールがドメイン知識を処理します。
意味的拡張(ステップ4)は以下を提供します。
-
柔軟性: 予期していなかったフレーズを発見します。
-
実際のユーザー言語: 実際の検索クエリから学習します。
-
同義語: 同等のフレーズを見つけます("16gb" に対する "16 gigs")。
これらを組み合わせることで、精度と再現率のバランスを取ります。
参考文献
技術的概念
モデルドキュメント
-
all-mpnet-base-v2 - Hugging Face
-
Sentence Transformers - 公式ドキュメント
関連記事
-
埋め込み戦略 - 埋め込みの生成方法
-
フィルタ抽出アルゴリズム - マッピングを使用したフィルタ抽出
-
SEOパイプライン概要 - パイプライン全体のアーキテクチャ
-
クエリクラスタリング - 類似クエリのグループ化
-
製品マッチング - 意味的マッチング
まとめ
フレーズとフィルタのマッピングは2つのステップで生成します。
ステップ 3a(基本生成):
-
見出し、キー、値、単位のすべての順列を生成
-
フィーチャー固有のルールを適用(プロセッサシリーズ、メモリ、ストレージ、フォームファクタ)
-
接続フィーチャーにポート接尾辞を追加
-
特定のフィーチャーの単独値にホワイトリストを適用
-
ルールから基本フレーズセットを出力
ステップ 4(意味的拡張):
-
実際の検索クエリからn-gramフレーズを抽出
-
フレーズとフィルタ検索テキストを埋め込む
-
しきい値以上の類似度スコアを持つフレーズをマッチング
-
手動シードフレーズを注入して拡張をガイド
-
メモリ/ストレージの衝突を解決
-
拡張および曖昧さを解消したフレーズセットを出力
その結果、期待されるフレーズ(ルールによる)と予期しないバリエーション(意味的類似性による)の両方を処理する包括的なマッピングが得られます。これらのマッピングは、クエリページ、検索、製品マッチングにわたってフィルタ抽出を支えます。