paper2skills Playbook

GPLR 用户人群标签生成 - 购买行为到可解释 Persona 的低成本桥接

Skill-GPLR-Persona-Generation · 14-用户分析

causalexperimentrecommendationpricing广告与投放客服与VOC推荐与搜索定价与利润WF-B 广告优化WF-C 客服分诊WF-D 选品扫描WF-E Review监控WF-F 动态定价WF-H 复购增长
年化 ROI10 万
实现难度⭐⭐☆☆☆
业务优先级⭐⭐☆☆☆
业务视角
适用角色运营负责人 / 用户增长负责人 · CMO · 产品经理
适用平台Amazon 买家分层 · DTC 站 LTV 预测 · Klaviyo/Brevo 邮件分群
什么情况下用有大量老客户,但不知道谁是高价值客户、谁快要流失;新客获取成本越来越高,老客复购却上不去
成功是什么样的用户按 RFM/LTV 分层精准触达,高价值用户留存率提升,老客贡献收入占比从 30% 提升到 50%
业务痛点
老客复购率上不去不知道哪些用户要流失了所有用户用同一套活动买过一次就不见了

1. 解决的问题

用户购买行为包含丰富的人群信号,但直接为百万用户调用 LLM 标注成本极高。GPLR 解决这个矛盾:用少量 LLM 标注 + 图结构传播覆盖全量用户。三步流程:① Diversity-Uncertainty(DU)采样选出最有代表性的"原型用户"做 LLM 标注;② LLM 基于购买历史为原型用户赋予 Persona 标签;③ 在用户-产品交互图上随机游走,将标签从有标注用户传播至全量未标注用户。

2. 核心算法逻辑

用户购买行为包含丰富的人群信号,但直接为百万用户调用 LLM 标注成本极高。GPLR 解决这个矛盾:用少量 LLM 标注 + 图结构传播覆盖全量用户。三步流程:① DiversityUncertainty(DU)采样选出最有代表性的"原型用户"做 LLM 标注;② LLM 基于购买历史为原型用户赋予 Persona 标签;③ 在用户产品交互图上随机游走,将标签从有标注用户传播至全量未标注用户。

3. 业务应用场景

- 业务问题:Momcozy 在 Amazon US 有 10 万+ 活跃用户,现有 RFM 分群只能区分"高消费/低消费",营销团队无法针对"出差妈妈""新手妈妈"制定差异化素材;人工打标既慢又贵 - 数据要求:Amazon 订单数据(`user_id`, `product_id`, `purchase_date`)+ 预定义 Persona 集合(如:职场背奶妈妈 / 全职新手妈妈 / 出差旅行妈妈 / 静音敏感型 / 价格敏感型) - GPLR 配置: - 构建用户-产品交互图(购买=1.0,浏览=0.3) - DU 采样 5,000 名原型用户(5 万用户 5% 预算)→ LLM 基于

- 业务问题:Momcozy 静音款 S12 Pro 上市 1 个月,仅有 800 条购买记录,运营不确定核心人群是"职场妈妈"还是"夜晚哺乳妈妈";若判断错误,亚马逊广告关键词投放偏差,前 2 个月 ROI 极低 - 数据要求:新品 800 条购买记录 + 已有成熟产品 5 万条历史购买记录(图传播底座) - GPLR 配置: - 使用全品类历史用户图作为传播底座(已包含各 Persona 原型) - 新品购买用户作为待推断节点加入图 - 无需额外 LLM 标注(复用历史原型),直接随机游走 2 步得出 Persona 分布 - 输出:新品用户 Persona 分布饼图 + 主导人群推荐广告

4. 输入数据要求

请查看原始代码模板获取输入规格。

5. 输出结果

请查看原始代码模板获取输出规格。

6. 业务价值 / ROI

  • 现状:10 万用户 RFM 分层 3 档,广告 ROAS ≈ 3.0
  • GPLR 后:6 档精准 Persona 定投,ROAS 提升 20-30%
  • 广告月预算 100 万 × 25% ROAS 提升 → 净增利润 8-12 万/月 = 96-144 万/年
  • LLM 标注成本:5,000 用户 × 0.002 元/次 = 10 元(极低)
  • 避免前 2 个月广告定向偏差损失:10 万广告费 × 30% 浪费率减少 = 3 万/新品
  • 年化 20 款新品 = 60 万/年

7. 代码模板

代码块数量:1 · 路径:paper2skills-code/nlp_voc/gplr_persona_generation

"""
GPLR: Generating Personas with LLM and Random Walk
论文 arXiv:2504.17304 (SIGIR 2025)
完整实现见 paper2skills-code/nlp_voc/gplr_persona_generation/model.py
"""
from __future__ import annotations
import numpy as np
from typing import List, Dict, Tuple
from collections import defaultdict
from dataclasses import dataclass


@dataclass
class UserInteraction:
    user_id: str
    product_id: str
    interaction_type: str  # 'purchase', 'view', 'review'
    timestamp: str
    value: float = 1.0


class InteractionGraph:
    """用户-产品交互图"""

    def __init__(self):
        self.interactions: Dict[str, List[UserInteraction]] = defaultdict(list)
        self._user_set: set = set()

    def add_interaction(self, interaction: UserInteraction):
        self.interactions[interaction.user_id].append(interaction)
        self._user_set.add(interaction.user_id)

    def build_index(self):
        self.user_ids = list(self._user_set)
        self.user_to_idx = {u: i for i, u in enumerate(self.user_ids)}

    def get_user_interactions(self, user_id: str) -> List[UserInteraction]:
        return self.interactions.get(user_id, [])

    def get_user_index(self, user_id: str) -> int:
        return self.user_to_idx.get(user_id, -1)

    def get_similar_users(self, user_idx: int, top_k: int = 10) -> List[Tuple[int, float]]:
        """Jaccard 相似度找相似用户"""
        user_id = self.user_ids[user_idx]
        user_products = set(i.product_id for i in self.interactions[user_id])
        sims = []
        for other_id, other_idx in self.user_to_idx.items():
            if other_id == user_id:
                continue
            other_products = set(i.product_id for i in self.interactions[other_id])
            union = user_products | other_products
            if union:
                sim = len(user_products & other_products) / len(union)
                sims.append((other_idx, sim))
        sims.sort(key=lambda x: -x[1])
        return sims[:top_k]


class GPLRProfiler:

8. 论文来源

  • 2504.17304