LESSON

推薦理由の生成

「『あなたへのおすすめ』と表示されても、なぜおすすめなのか分からなければ信頼されない。」

田中VPoEが競合サービスの推薦画面を比較する。

「推薦理由があるだけでCTRが30%向上するというデータがある。ユーザーに納得感を与える理由生成が、推薦システムの説得力を決める。」

推薦理由の種類

タイプ根拠
協調フィルタリング型「あなたと似た嗜好の人がよく買っています」ユーザー類似度
コンテンツベース型「以前購入した商品Aと同じブランドです」アイテム類似度
属性マッチ型「ご希望の赤色・3万円以内のアイテムです」嗜好条件一致
トレンド型「今週の人気急上昇アイテムです」人気度データ
補完型「購入された商品とよく一緒に買われています」共起データ

推薦理由テンプレート

class ReasonGenerator:
    """推薦理由の生成"""

    def __init__(self):
        self.templates = {
            'collaborative': [
                "あなたと似た嗜好の{n_similar}人のユーザーが高評価しています",
                "あなたが好きな{liked_item}を購入した人の{pct}%が一緒に購入しています",
            ],
            'content_based': [
                "お気に入りの{similar_item}と同じ{attribute}のアイテムです",
                "よく閲覧する{category}カテゴリの新着アイテムです",
            ],
            'attribute_match': [
                "ご希望の{matched_attrs}に一致するアイテムです",
                "{price_range}のご予算に合った{category}です",
            ],
            'trending': [
                "今週の{category}カテゴリで人気が急上昇中です(先週比+{growth}%)",
                "{n_buyers}人が過去24時間に購入しています",
            ],
        }

    def generate(self, item, user_profile, recommendation_source):
        """推薦元に応じた理由を生成"""
        source = recommendation_source['type']
        params = recommendation_source['params']

        if source == 'collaborative':
            return self._format_collaborative(params)
        elif source == 'content_based':
            return self._format_content(params, user_profile)
        elif source == 'attribute_match':
            return self._format_attribute(params)
        elif source == 'trending':
            return self._format_trending(params)
        else:
            return "あなたにおすすめのアイテムです"

    def _format_collaborative(self, params):
        template = self.templates['collaborative'][0]
        return template.format(n_similar=params.get('n_similar', 50))

    def _format_content(self, params, profile):
        template = self.templates['content_based'][0]
        return template.format(
            similar_item=params.get('similar_item', ''),
            attribute=params.get('shared_attribute', ''),
        )

    def _format_attribute(self, params):
        matched = '、'.join(params.get('matched_attributes', []))
        template = self.templates['attribute_match'][0]
        return template.format(matched_attrs=matched)

    def _format_trending(self, params):
        template = self.templates['trending'][0]
        return template.format(
            category=params.get('category', ''),
            growth=params.get('growth_pct', 0),
        )

LLMによる自然言語理由生成

def generate_natural_reason(item, user_profile, context, recommendation_data):
    """LLMで自然な推薦理由を生成"""
    from langchain_openai import ChatOpenAI

    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)

    prompt = f"""
    以下の情報を基に、ユーザーに表示する推薦理由を1〜2文で生成してください。
    自然で説得力のある日本語にしてください。

    ユーザープロファイル:
    - よく購入するカテゴリ: {user_profile.get('top_categories', [])}
    - 好みのブランド: {user_profile.get('favorite_brands', [])}
    - 価格帯: {user_profile.get('price_range', '')}

    推薦アイテム:
    - 商品名: {item['name']}
    - カテゴリ: {item['category']}
    - 価格: {item['price']}
    - 特徴: {item.get('features', '')}

    推薦の根拠:
    - ソース: {recommendation_data['type']}
    - スコア: {recommendation_data['score']}
    - 詳細: {recommendation_data.get('detail', '')}

    コンテキスト:
    - 季節: {context.get('season', '')}
    - 用途: {context.get('occasion', '')}
    """

    response = llm.invoke(prompt)
    return response.content

まとめ

項目ポイント
理由の種類5タイプ(協調/コンテンツ/属性/トレンド/補完)
テンプレート推薦ソースに応じた定型文
LLM生成文脈を考慮した自然な理由文
効果CTR +30%、ユーザー信頼度向上

チェックリスト

  • 推薦理由の5つのタイプを説明できる
  • テンプレートベースの理由生成を実装できる
  • LLMを使った自然言語理由生成を実装できる
  • 推薦理由がビジネスKPIに与える影響を理解した

次のステップへ

推薦理由の生成を実装した。次はA/Bテストの設計を学ぼう。

推定読了時間: 30分