paper2skills Playbook

非商品页路径建模 - 导航页在用户旅程中的转化贡献

Skill-NonItem-Page-Path-Modeling · 14-用户分析

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

1. 解决的问题

母婴独立站(如 Momcozy/Graco 品牌站)的首页、分类页(奶瓶/奶粉/童车)、搜索页在转化漏斗中起什么作用

2. 核心算法逻辑

传统序列推荐系统只捕获「商品交互」(PDP 页面点击),忽略了用户在商品页之间穿插访问的非商品页——如首页、搜索结果页、分类页(Category Listing Page,CLP)、博客详情页、购物车页等。论文证明:这些非商品页携带了关于用户意图的关键信号,能显著提升 NextItem 预测性能。

3. 业务应用场景

业务问题:母婴独立站(如 Momcozy/Graco 品牌站)的首页、分类页(奶瓶/奶粉/童车)、搜索页在转化漏斗中起什么作用?桑基图中这些节点的「转化贡献权重」该如何科学量化?砍掉或降级某个导航页会损失多少转化?

| 母婴独立站页面类型 | 论文非商品页类型 | 表征策略推荐 | |-----------------|---------------|------------| | 首页(Homepage) | 单体非商品页 | CPID: `type:homepage` | | 搜索结果页(SRP) | 商品列表页 | PE: 用搜索词嵌入 / CPID: 频繁分类组合 | | 分类页(CLP,如 `/breast-pumps/`) | 商品列表页 | CPID: `category:breast-pump` | | 博客/选购指南页 | 单体非商品页 | PE: 页面文本嵌入 | | 购物车页 | 单

| 字段 | 类型 | 示例 | |------|------|------| | `session_id` | string | `"sess_abc123"` | | `event_time` | datetime | `"2026-05-01 10:23:45"` | | `page_type` | string | `"pdp"` / `"clp"` / `"srp"` / `"homepage"` / `"cart"` | | `page_id` | string | `"pdp_M001"` / `"clp_breast-pump"` / `"srp_q123"` | | `ite

4. 输入数据要求

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

5. 输出结果

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

6. 业务价值 / ROI

5000 万

7. 代码模板

代码块数量:2 · 路径:未检测到

"""
Non-Item Page Path Modeling — 非商品页路径建模
论文: arXiv:2408.15953 (ACM TORS 2025)
场景: 母婴出海独立站,桑基图导航节点权重量化 + 含非商品页的 Next-Item 预测

包含:
1. 页面序列数据模拟(母婴电商场景)
2. HypTrails 假设检验:验证非商品页影响力
3. 非商品页 CPID/PE 编码
4. 序列推荐模型(简化 SASRec 变体):对比 Items-Only vs 含非商品页
5. 非商品页贡献度消融实验(Ablation Study)
"""

from __future__ import annotations

import random
import math
from collections import defaultdict, Counter
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple
import numpy as np


# ============================================================
# 1. 数据结构定义
# ============================================================

@dataclass
class PageEvent:
    """单次页面交互事件"""
    page_type: str          # "pdp" / "clp" / "srp" / "homepage" / "cart" / "blog"
    page_id: str            # 页面唯一标识
    item_id: Optional[str]  # 仅 PDP 有商品 ID
    categories: List[str]   # 页面分类标签(非商品页最重要的内容信号)
    query_embedding: Optional[List[float]] = None  # 搜索页专用

    @property
    def is_item(self) -> bool:
        """是否为商品页(PDP)"""
        return self.page_type == "pdp" and self.item_id is not None

    def get_cpid(self) -> str:
        """构造 Content-based Page ID"""
        if self.is_item:
            return f"item:{self.item_id}"
        if self.categories:
            cat_str = "|".join(sorted(self.categories))
            return f"{self.page_type}:{cat_str}"
        return f"{self.page_type}:{self.page_id}"


@dataclass
class UserSession:
    """用户会话:包含商品页和非商品页的混合序列"""
    session_id: str
    events: List[PageEvent] = field(default_factory=list)

    def get_item_sequence(self) -> List[str]:
        """仅返回商品页序列(传统方式)"""
        return [e.item_id for e in self.events if e.is_item]

8. 论文来源

  • 2408.15953