包含 Persona 锚定聚类、LLM 报告生成、方法论文档及 .gitignore 更新,便于在 Gitee 独立部署。 Co-authored-by: Cursor <cursoragent@cursor.com>
33 KiB
VOC 数据清洗、分析与报告生成通用方法论
文档版本:v1.0 · 2026-06-11
适用范围:亚马逊任意品类竞品 VOC 分析
数据来源:卖家精灵 / Shulex 导出的实时评论 CSV
报告输出:双层结构 HTML 报告(描述层 What + 分析层 Why)
目录
- 原始数据结构
- 数据清洗规则
- 描述层 What — 分析逻辑
- 3.1 有效评论统计
- 3.2 用户画像(Persona)识别
- 3.3 正负反馈主题提取
- 3.4 情感关键词分析
- 分析层 Why — 分析逻辑
- 4.1 KANO 模型需求分类
- 4.2 JTBD 动机框架
- 4.3 人群 × 场景 × 需求矩阵
- 4.4 痛点根因分析
- 报告生成逻辑
- 5.1 HTML 整体结构
- 5.2 可视化组件
- 5.3 使用场景字段写入规则(核心规则)
- 执行 SOP(逐步操作流程)
- 关键阈值与判断规则速查表
- 新品类接入清单
1. 原始数据结构
文件命名规则
{ASIN}_realtime.csv
每个竞品 ASIN 对应一个独立文件,分析时批量读取同一目录下的全部文件。
CSV 字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
asin |
string | 亚马逊标准识别号,文件可能带 BOM 头(\ufeffasin),读取时须用 utf-8-sig 编码 |
rating |
float(字符串形式) | 评分,取值 1.0 / 2.0 / 3.0 / 4.0 / 5.0,须用 float() 转换,不能用 int() |
title |
string | 评论标题 |
content |
string | 评论正文(主要分析字段) |
verified |
string | "True" / "False",是否已验证购买 |
vine |
string | "True" / "False",是否为 Vine 评测 |
review_date |
string | ISO 8601 格式,如 2026-05-28T00:00:00+00:00 |
2. 数据清洗规则
2.1 有效评论筛选(不可更改的核心规则)
只保留以下两类评论,其余全部排除:
def is_valid(row):
return (
row.get('verified', '').strip().lower() == 'true'
or
row.get('vine', '').strip().lower() == 'true'
)
排除理由:未验证且非 Vine 的评论可能包含刷评、竞品恶意差评或未实际购买的猜测,会干扰真实用户体验数据。
2.2 差评 / 好评 / 中性评论定义
| 分类 | 星级 | 用途 |
|---|---|---|
| 好评(Positive) | ★★★★★ / ★★★★ | 提取正向主题、魅力型需求、用户满意点 |
| 中性(Neutral) | ★★★ | 单独记录,不进入主题频次统计 |
| 差评(Negative) | ★★ / ★ | 主要分析对象,提取痛点主题和根因 |
2.3 新买家 vs 复购买家区分规则
| 类型 | content 字段识别关键词 |
|---|---|
| 新买家 | first time / just got / just bought / new to |
| 复购买家 | reorder / bought again / second time / repurchase / keep buying |
两类买家的差评重点通常不同:
- 新买家 → 效果不符预期、开箱即坏、使用门槛高
- 复购买家 → 某个功能在长期使用后失效、品质下降
3. 描述层 What — 分析逻辑
3.1 有效评论统计
对每个 ASIN 分别计算,再汇总全市场数据:
| 指标 | 计算公式 |
|---|---|
| 有效评论数 | 通过 is_valid() 筛选后的总行数 |
| 加权平均评分 | Σ(各ASIN均分 × 各ASIN有效评论数) / 全市场有效评论总数 |
| 差评率 | ≤2星评论数 / 有效总数 |
| 正评率 | ≥4星评论数 / 有效总数 |
| 各星级分布 | 1–5 星各自数量及占比 |
市场竞争状态判断:
| 加权均分 | 判断 |
|---|---|
| < 3.5 | 市场存在严重系统性缺陷,是新品进入的明确窗口期 |
| 3.5 – 4.0 | 市场有改进空间,部分功能存在普遍短板 |
| > 4.0 | 市场整体较成熟,需通过差异化或细分切入 |
3.2 用户画像(Persona)识别
识别方法
在评论 title + content 字段中搜索特征词,将评论人归入对应 Persona。一条评论可同时归入多个 Persona。
Persona 识别词的建立原则
- 阅读全部差评(≤2星),找出用户描述自身处境的词汇("I have... / I am... / As a...")
- 阅读全部好评(≥4星),找出用户描述自身需求背景的词汇
- 从中归纳出 4–6 个差异化的用户群体
- 每个群体设定 5–10 个识别关键词
⚠️ Persona 必须覆盖的三个分类维度(缺一不可)
在最终确认 Persona 列表前,必须检查是否已从以下三个维度进行了覆盖,不能只按其中一个维度拆分就停止:
| 维度 | 说明 | 典型信号词 |
|---|---|---|
| A. 物理/生理特征 | 用户身体特征决定了产品对他们的效果上限(最易被遗漏) | thick/dark/coarse hair / sensitive skin / pregnant / curly / Latina / Type 4 hair |
| B. 行为/场景 | 用户在什么情境下使用产品 | travel / in the shower / gift / daily |
| C. 购买动机/背景 | 用户为何从其他方案切换过来 | switched from razor / too expensive / saw on TikTok / first time |
关键原则:如果你的 Persona 列表里只有场景类和动机类群体,而没有任何一个群体是按身体特征定义的,说明维度 A 被遗漏了,必须重新检查差评中的自我标注词汇。
自我标注信号强制检查步骤
在完成初步 Persona 归纳后,必须额外执行以下搜索,确认是否有被遗漏的物理特征用户群:
搜索差评中所有含以下模式的句子:
"I have [adj] [noun]"(如 I have thick hair / I have sensitive skin)
"My [noun] is/are [adj]"(如 My skin is super sensitive)
"As a [noun/adj person]"(如 As a Latina / As a curly-haired person)
"[族裔/肤色/发质形容词]"(如 Latina / dark hair / coarse / Type 4)
若上述词汇出现 ≥ 5 条,则该物理特征代表一个独立 Persona,必须单独列出。
Persona 识别词模板格式
PERSONA_KEYWORDS = {
'{群体名称A}': ['{关键词1}', '{关键词2}', ...],
'{群体名称B}': ['{关键词1}', '{关键词2}', ...],
# 根据实际品类补充
}
Persona 占比估算规则
占比 = 命中该Persona识别词的评论数 / 有效评论总数
四舍五入至整5%
因一条评论可被多个 Persona 命中,各 Persona 占比之和可超过 100%。
Persona 卡片内容规格(每个群体输出以下信息)
| 字段 | 来源 | 说明 |
|---|---|---|
| 群体名称 | 自定义 | 简洁描述身份特征,≤6 字 |
| 占比 | 统计计算 | 见上方公式 |
| 核心痛点 | 该群体差评 | ≤3 条,原文语义概括 |
| 核心需求 | 该群体好评+诉求 | ≤3 条 |
| 购买动机 | JTBD 分析 | 用"雇佣产品做什么"句式 |
| 代表性引用 | 真实评论原文 | 必须来自实际评论,注明 ASIN |
3.3 正负反馈主题提取
主题识别关键词组的建立方法
- 阅读全部差评(≤2星),记录用户描述问题时的高频词
- 将语义相近的词归为同一主题,形成关键词组
- 每个主题设定 5–10 个关键词
- 覆盖 80%+ 的差评内容(长尾主题可合并为"其他")
⚠️ 主题拆分规则:相近但机制不同的问题必须独立成主题
语义相近不等于根因相同。以下情况必须拆分为独立主题,不得合并:
| 合并后失真的典型例子 | 应该如何拆分 | 原因 |
|---|---|---|
| "剃效差"(笼统) | ① 留茬/剃不干净 ② 拉扯/扯毛而非切断 | 机制不同:留茬=刀头贴肤不足;拉扯=刀片咬不断粗硬毛,影响人群完全不同 |
| "皮肤问题"(笼统) | ① 割伤/出血 ② 摩擦热/灼烧感 ③ 剃须疹/内生毛 | 根因不同,对应不同的工程解决方案 |
| "产品损坏"(笼统) | ① 充电失效 ② 配件断裂/脱落 | 分属电气系统和结构系统,受影响时间节点不同(充电=使用初期;断裂=一段时间后) |
判断是否需要拆分的问题:
"同一主题下的差评,是否描述的是同一个物理/工程原因?"
如果不是,必须拆开。
通用差评主题模板格式:
NEGATIVE_THEMES = {
'{主题名称}': ['{关键词1}', '{关键词2}', ...],
# 品类相关主题
}
通用好评主题模板格式:
POSITIVE_THEMES = {
'{主题名称}': ['{关键词1}', '{关键词2}', ...],
}
频次统计规则
- 在
title + content中搜索关键词 - 同一评论中同一关键词出现多次,仍计为 1 次(避免重复计数)
- 差评主题只统计 ≤2 星评论;好评主题只统计 ≥4 星评论
- 频次 = 命中该主题的评论条数(非词语出现总次数)
主题优先级判定规则
| 优先级 | 差评频次门槛 | 涉及竞品范围 |
|---|---|---|
| P0(立即处理) | ≥ 总有效差评数的 20% | 80%+ 竞品均出现 |
| P1(短期处理) | 总有效差评数的 10–20% | 60%+ 竞品出现 |
| P2(中期关注) | 总有效差评数的 3–10% | 40%+ 竞品出现 |
频次门槛的动态计算:
P0 绝对门槛 = 全市场有效差评数 × 20%
例:1123 条有效评论,差评率 35% ≈ 393 条差评,P0 门槛 ≈ 79 条
3.4 情感关键词分析
对所有有效评论进行词频统计,提取高频情感词。
输出字段规格:
| 字段 | 说明 | 规则 |
|---|---|---|
| 词汇 | 英文原词或词组 | 保留原文,不翻译 |
| 出现频次 | 在有效评论中出现的条数 | 同一评论多次出现计1次 |
| 情感极性 | 正面 / 负面 / 中性 | 根据语境判断,同一词在不同语境可有不同极性 |
| 含义/使用场景 | 该词汇在评论中的具体语境 | 只写评论中明确出现的内容,不推断 |
| 主要关联人群 | 对应的 Persona 名称 | 可多个 |
4. 分析层 Why — 分析逻辑
4.0 Persona 完整性验证(进入分析层前的强制关卡)
在开始 KANO / JTBD 分析之前,必须完成以下交叉验证,发现遗漏立即返回 3.2 节补充。
验证方法:每个 P0/P1 主题 → 强制归因到 Persona
为每一个 P0/P1 差评主题填写下表:
| 差评主题 | 频次 | 该主题的典型描述 | 主要影响哪类用户? | 对应已有 Persona? |
|---|---|---|---|---|
| {主题1} | {N条} | {原文特征} | {用户特征描述} | {Persona名 / ❌未覆盖} |
| {主题2} | ... | ... | ... | ... |
如果某个 P0/P1 主题在"对应已有 Persona"列填写了 ❌,说明存在遗漏的用户群体,必须新增 Persona。
常见漏洞场景
| 被遗漏的情况 | 漏洞原因 | 补救方式 |
|---|---|---|
| 身体特征群体(如粗硬发质用户) | 只按场景/动机分群,未检查维度 A(物理特征) | 返回 3.2 节执行自我标注信号强制检查 |
| 长期使用复购用户 | 只看差评内容,未注意时间轴("after months of use") | 检查含 months / after a while / second bottle 的差评是否形成独立群体 |
| 特定人群的特殊需求 | 该群体占比较小但痛点极具体 | 即使占比低(~5%),若痛点独特且无法被其他 Persona 代表,必须单独列出 |
4.1 KANO 模型需求分类
四种类型定义与判断标准
| 类型 | 定义 | 判断标准 | 常见错误 |
|---|---|---|---|
| 基本型(Must-be) | 不满足→强烈差评;满足→用户不会特别提及或表扬 | ① 差评频次达 P0 级别 ② 80%+ 竞品均出现该缺陷 ③ 好评中几乎不出现"因为做到了 X 所以好评" | 把"剃净度"归为基本型——剃净度好坏都会被用户提及,属期望型 |
| 期望型(Performance) | 做得越好评分越高,做得越差评分越低,线性关系 | ① 好评中被作为"这款优于竞品"的主要理由 ② 差评中作为"原本期待但未达到"的失望点 ③ 用户用程度词描述(better/worse/not as good as) |
把"电池续航"归为基本型——续航差才差评,续航超长会被用户特别称赞 |
| 魅力型(Attractive) | 满足→产生超预期惊喜和好评;不满足→用户不会差评 | ① 好评中出现强情感词 love / obsessed / amazing / didn't expect / bonus ② 该功能在差评中几乎不出现 ③ 竞品普遍缺失,属市场空白 |
把"附赠收纳袋"归为期望型——用户从未因为"没有收纳袋"而差评,属意外惊喜 |
| 反向型(Reverse) | 某些用户认为该功能是负担,反而差评 | ① 差评中出现对某个"功能"的明确抱怨 ② 该内容在好评中也受另一部分人喜爱(说明用户分歧) | 把"产品损坏"归为反向型——没有用户"希望产品能损坏" |
各类型的输出格式要求
每个 KANO 条目必须包含以下 5 个字段,缺一不可:
需求项:[具体需求描述,动词+名词形式]
评论频次证据:[支撑该分类的评论条数及代表性原文片段]
主要影响 Persona:[哪类用户群对该需求最敏感]
分类原因:[用一句话解释为什么是这个 KANO 类型,而不是其他类型]
竞品现状:[现有竞品是否满足,满足程度如何]
示例(基本型):
需求项:充电后可正常启动
评论频次证据:118条差评(P0级别),"stopped working after a few uses" / "won't charge at all"
主要影响 Persona:所有群体,尤其是复购用户(第二台也坏后彻底失去信任)
分类原因:充电失效是"有就正常、坏了就1星"的底线需求,好评中没有人因"能充电"而特别表扬
竞品现状:全部5款竞品均有此问题,说明是行业普遍工程缺陷
示例(魅力型):
需求项:LCD 电量显示
评论频次证据:好评中 28条提及,"love that I can see the battery level" / "so convenient",差评中0条因缺少LCD而差评
主要影响 Persona:旅行护理族(出行前确认电量)/ 所有群体
分类原因:用户不会因为"没有电量显示"而差评,但有了之后会主动提及并作为推荐理由
竞品现状:仅1款(FANKRUAI)有此功能,属差异化空白
KANO 归类操作步骤
步骤一:基本型识别
- 列出所有 P0/P1 差评主题
- 检查每个主题对应的好评:如果好评中几乎没有人因"做到了这点"而表扬,确认为基本型
- 每个基本型需求必须注明:频次(条数)+ 出现该问题的竞品数量
步骤二:期望型 vs 魅力型区分
在好评中对每个高频好评主题做以下判断:
| 判断问题 | 若"是"→ | 若"否"→ |
|---|---|---|
| 差评中有人因该功能不够好而差评? | 期望型 | 魅力型候选 |
好评用程度词描述(better/works great/very)? |
期望型 | 魅力型候选 |
好评中出现 love/obsessed/amazing/bonus/didn't expect? |
魅力型 | 继续判断 |
| 竞品普遍缺失,属市场新鲜感? | 魅力型 | 继续判断 |
步骤三:反向型搜索(不得以"未发现"一笔带过)
必须主动在差评中搜索以下关键词,并记录每个词的出现频次:
搜索词组(在全部有效评论 title+content 中搜索):
过于复杂:too many parts / too complicated / confusing / hard to use
过于嘈杂:too loud / so loud / noise / noisy
功能多余:don't need / unnecessary / didn't ask for / useless feature
操作繁琐:takes too long / too many steps / annoying to clean
结果处理规则:
- 若任意词组频次 ≥ 5 条 → 该功能为反向型,单独列出并附引用
- 若所有词组总频次 < 5 条 → 填写:"反向型:经主动搜索 [列出搜索词],出现频次共 [N] 条,低于阈值,本品类暂无明确反向需求"(禁止直接写"无"或"未发现")
4.2 JTBD 动机框架
JTBD(Jobs To Be Done):用户"雇佣"产品来完成什么任务。分析维度:功能性动机、情感性动机、社会性动机。
输出格式(每个 Persona 一行):
| 字段 | 说明 | 填写规则 |
|---|---|---|
| 用户群 | Persona 名称 | — |
| 核心 Job | 用户想完成的任务 | 动词+宾语形式,如"用电动工具替代传统方式" |
| 功能性动机 | 实用层面的驱动因素 | 必须能从评论中找到佐证句子 |
| 情感性动机 | 情绪/心理层面的驱动因素 | 必须能从评论中找到佐证句子 |
| 社会性动机 | 他人视角/社交驱动(如无评论佐证则留空) | 可选 |
| 购买触发时机 | 什么具体事件让用户决定购买 | 来自评论中的具体描述 |
4.3 人群 × 场景 × 需求矩阵
矩阵将 Persona、使用场景、KANO 需求分层和当前满意度整合为一张全景视图。
列结构:
| 列 | 填写来源 |
|---|---|
| 用户群 | Persona 名称 + 占比 |
| 使用场景(When/Where) | 严格遵守场景字段规则(见 5.3 节) |
| 基本型需求 | KANO 基本型 + 该群体 P0 差评 |
| 期望型需求 | KANO 期望型 + 该群体 P1 差评 |
| 魅力型需求 | KANO 魅力型 + 该群体好评加分点 |
| 当前满意度 | 该群体对应评论的均分和好评率综合判断 |
满意度评级标准:
| 当前满意度 | 对应均分参考 | 显示样式 |
|---|---|---|
| 高 | ≥ 4.0 | 绿色 |
| 中等 | 3.3 – 3.9 | 黄色 |
| 低 ⚠ | < 3.3 | 红色 |
4.4 痛点根因分析
适用条件:差评主题达到 P0 或 P1 级别时,必须进行根因分析。
分析框架:
根因 N:[工程/设计/材料/体验设计问题名称]
→ 导致后果:[差评主题名称] × [频次]
→ 失效机制:[从产品结构或工作原理层面解释为什么会出现这个问题]
→ 关键引用:[2-3条真实评论原文(英文)— 所属ASIN品牌]
根因分析的层次要求:
| 层次 | 示例(错误 → 正确) |
|---|---|
| 停留在现象层(❌) | "产品质量差" |
| 到达机制层(✅) | "充电口防水胶圈未达到IP67标准,浴室蒸汽渗入导致腐蚀" |
5. 报告生成逻辑
5.1 HTML 整体结构
报告采用纯 HTML 内嵌 CSS + JS,无外部文件依赖,单文件可直接分享。
{产品关键词}-voc-v{版本号}.html
├── <head>
│ ├── Chart.js CDN(可视化依赖)
│ │ └── https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js
│ └── <style> 内嵌 CSS
│
├── <nav class="top-nav">(固定顶部导航,支持锚点跳转)
│ ├── [描述层 What] → 数据总览 / 受众画像 / 正负反馈 / 各ASIN主题分布 / 情感词频
│ └── [分析层 Why] → KANO模型 / JTBD动机 / 人群矩阵 / 痛点根因
│
└── <div class="page">(主体内容)
├── 标题 + 副标题 + 阅读指引 callout
├── ── 描述层 What ──
│ ├── #sec-overview:KPI 总览卡片
│ ├── #sec-persona:Persona 卡片网格
│ ├── #sec-feedback:全市场差评/好评主题柱状图(汇总)
│ ├── #sec-asin-theme:各 ASIN 差评/好评主题频次分布(新增)
│ └── #sec-keyword:情感词频表格
├── ── 分析层 Why ──
│ ├── #sec-kano:KANO 四象限卡片
│ ├── #sec-jtbd:JTBD 动机表格
│ ├── #sec-matrix:人群×场景×需求矩阵
│ └── #sec-rootcause:痛点根因分析块
└── <footer>(数据来源声明)
文件存放路径:{产品文件夹}/分析报告 HTML/
文件命名:{产品关键词(连字符)}-voc-v{版本号}.html
示例:dog-calming-chews-voc-v1.html
5.2 可视化组件规格
KPI 卡片(4 个,固定布局)
| 位置 | 指标 | 颜色规则 |
|---|---|---|
| 卡片1 | 有效评论总数 | 蓝色(中性) |
| 卡片2 | 加权平均评分 | < 3.5 红色 / 3.5–4.0 黄色 / > 4.0 绿色 |
| 卡片3 | 正评率(≥4星占比) | 绿色 |
| 卡片4 | 差评率(≤2星占比) | 红色 |
柱状图(使用 Chart.js,水平条形图)
差评主题柱状图(全市场汇总):
new Chart(document.getElementById('negChart'), {
type: 'bar',
data: {
labels: ['主题1', '主题2', ...], // 按频次降序排列
datasets: [{
data: [频次1, 频次2, ...],
// 颜色按优先级:P0 = '#ef4444',P1 = '#f97316',P2 = '#eab308'
backgroundColor: ['#ef4444', '#ef4444', '#f97316', '#f97316', '#eab308', '#eab308'],
}]
},
options: {
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: { x: { beginAtZero: true } }
}
});
好评主题柱状图(全市场汇总):配色统一使用绿色系(#22c55e)。
各 ASIN 主题频次分布图(新增,ID: sec-asin-theme)
用途:揭示同一痛点在不同竞品间的严重程度差异,帮助判断哪款竞品在哪个维度最弱/最强。
图表类型:分组柱状图(Grouped Bar Chart),每个主题一组,每组内各 ASIN 一根柱子。
差评版 — 数据结构:
new Chart(document.getElementById('asinNegChart'), {
type: 'bar',
data: {
labels: ['主题1', '主题2', ...], // x轴:差评主题(P0/P1 主题,按全市场频次降序)
datasets: [
// 每个 ASIN 一个 dataset
{ label: 'ASIN1(品牌名)', data: [主题1频次, 主题2频次, ...], backgroundColor: '#色值' },
{ label: 'ASIN2(品牌名)', data: [...], backgroundColor: '#色值' },
// ...
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: true, position: 'bottom' }
},
scales: {
x: { beginAtZero: true },
y: { beginAtZero: true }
}
}
});
好评版 — 与差评版结构完全相同,labels 换成好评主题,颜色使用绿色系渐变。
ASIN 配色规则(固定,每次分析保持一致):
| ASIN 序号 | 差评图颜色 | 好评图颜色 |
|---|---|---|
| ASIN 1 | #ef4444(红) |
#22c55e(绿) |
| ASIN 2 | #f97316(橙) |
#86efac(浅绿) |
| ASIN 3 | #eab308(黄) |
#4ade80(草绿) |
| ASIN 4 | #8b5cf6(紫) |
#2dd4bf(青绿) |
| ASIN 5 | #3b82f6(蓝) |
#60a5fa(浅蓝绿) |
数据提取逻辑(Python):
def count_theme_per_asin(all_reviews, themes, neg=True):
"""
按 ASIN 分别统计各主题的差评/好评频次
返回格式:{asin: {theme: count}}
"""
from collections import defaultdict
result = defaultdict(lambda: defaultdict(int))
for r in all_reviews:
if neg and r['rating'] > 2: continue
if not neg and r['rating'] < 4: continue
text = (r['title'] + ' ' + r['content']).lower()
for theme, keywords in themes.items():
if any(kw.lower() in text for kw in keywords):
result[r['asin']][theme] += 1
return dict(result)
# 转为 Chart.js datasets 格式
def to_chartjs_datasets(per_asin_data, asin_labels, theme_order):
"""
asin_labels: {asin: '品牌名'} 映射
theme_order: 主题列表(按全市场频次排序)
"""
colors = ['#ef4444', '#f97316', '#eab308', '#8b5cf6', '#3b82f6']
datasets = []
for i, (asin, label) in enumerate(asin_labels.items()):
datasets.append({
'label': label,
'data': [per_asin_data.get(asin, {}).get(t, 0) for t in theme_order],
'backgroundColor': colors[i % len(colors)],
})
return datasets
图表尺寸:高度建议 360px(主题数 ≤ 8)或 480px(主题数 > 8)。
图表标题规则:
- 差评版:
各竞品差评主题频次对比(≤2星评论) - 好评版:
各竞品好评主题频次对比(≥4星评论)
表格通用样式规则
| 元素 | CSS 类 | 用途 |
|---|---|---|
| P0 行 | .row-r |
红色背景底色(#fff5f5) |
| P1 行 | .row-y |
黄色背景底色(#fffbeb) |
| P2 行 | .row-b |
蓝色背景底色(#eff6ff) |
| 机会行 | .row-g |
绿色背景底色(#f0fdf4) |
| 优先级徽章 | .pill pill-danger / .pill-warn / .pill-info |
红/黄/蓝圆角标签 |
5.3 使用场景字段写入规则(核心规则)
这是本方法论中最容易出错、最需要严格执行的规则:
【强制规则】
所有涉及"使用场景(When/Where)"的字段,
只允许填写在评论 content 中能找到原词佐证的场景描述。
如果找不到评论佐证,一律填写 "—"。
禁止基于产品功能、品类常识或逻辑推断填写任何场景描述。
执行步骤
Step 1:确定该 Persona 的特征词组
Step 2:在该 Persona 对应的评论中搜索场景类词汇
(地点词:shower / bathroom / office / car / gym...)
(时间词:morning / night / before / after / daily...)
(情境词:traveling / pregnant / postpartum / gift...)
Step 3:统计每个场景词在该 Persona 评论中的出现条数
Step 4:按以下规则决定是否填写
| 出现条数 | 处理方式 |
|---|---|
| ≥ 5 条 | 可以填写该场景 |
| 2 – 4 条 | 慎重填写,建议留空或标注"少数提及" |
| < 2 条 | 必须留空,填写 — |
常见错误示例
| 错误写法(❌ 推断) | 正确写法(✅ 仅来自评论) |
|---|---|
| 夏季前突击整理 | —(无评论提及"before summer"作为使用时机) |
| 日常护理 | —("daily"在评论中属产品使用频率描述,非场景) |
| 坐姿/斜靠操作 | —(用户姿势属推断,评论未明确提及) |
| 任何场所 | —(无具体场景词,不可用"泛化"代替留空) |
| 浴室/淋浴 | ✅(评论中出现 in the shower / bathroom ≥5条) |
| 旅行途中 | ✅(评论中出现 travel / on a trip ≥5条) |
| 孕期护理 | ✅(评论中出现 pregnant / 37 weeks pregnant ≥5条) |
6. 执行 SOP(逐步操作流程)
Step 1:数据读取
import csv
import os
def load_reviews(filepath):
"""读取单个ASIN的评论CSV,返回有效评论列表"""
reviews = []
with open(filepath, encoding='utf-8-sig') as f: # utf-8-sig 处理BOM头
for row in csv.DictReader(f):
if (row.get('verified', '').strip().lower() == 'true' or
row.get('vine', '').strip().lower() == 'true'):
reviews.append({
'asin': row.get('asin', '').strip(),
'rating': float(row.get('rating', 0) or 0),
'title': row.get('title', ''),
'content': row.get('content', ''),
'date': row.get('review_date', ''),
})
return reviews
def load_all_reviews(directory):
"""批量读取目录下所有ASIN的评论"""
all_reviews = []
for fname in os.listdir(directory):
if fname.endswith('_realtime.csv'):
all_reviews.extend(load_reviews(os.path.join(directory, fname)))
return all_reviews
Step 2:基础统计
def basic_stats(reviews):
"""计算有效评论的基础统计指标"""
ratings = [r['rating'] for r in reviews if r['rating'] > 0]
total = len(ratings)
if not total:
return {}
return {
'total': total,
'avg': round(sum(ratings) / total, 2),
'pos_rate': round(sum(1 for r in ratings if r >= 4) / total, 3),
'neg_rate': round(sum(1 for r in ratings if r <= 2) / total, 3),
'dist': {i: ratings.count(float(i)) for i in range(1, 6)},
}
Step 3:主题频次统计
# 根据品类自定义主题关键词(见第3.3节)
NEGATIVE_THEMES = {
'{主题名称}': ['{关键词1}', '{关键词2}', ...],
}
POSITIVE_THEMES = {
'{主题名称}': ['{关键词1}', '{关键词2}', ...],
}
def count_themes(reviews, themes, neg=True):
"""
统计各主题频次
neg=True 时只统计差评(≤2星),neg=False 时只统计好评(≥4星)
"""
result = {}
for theme, keywords in themes.items():
count = 0
for r in reviews:
if neg and r['rating'] > 2: continue
if not neg and r['rating'] < 4: continue
text = (r['title'] + ' ' + r['content']).lower()
if any(kw.lower() in text for kw in keywords):
count += 1
result[theme] = count
return dict(sorted(result.items(), key=lambda x: x[1], reverse=True))
Step 4:Persona 识别
# 根据品类自定义(见第3.2节)
PERSONA_KEYWORDS = {
'{群体名称}': ['{关键词1}', '{关键词2}', ...],
}
def identify_personas(reviews, persona_keywords):
"""统计各Persona的命中评论数量"""
result = {p: 0 for p in persona_keywords}
for r in reviews:
text = (r['title'] + ' ' + r['content']).lower()
for persona, kws in persona_keywords.items():
if any(kw.lower() in text for kw in kws):
result[persona] += 1
total = len(reviews)
return {p: {'count': c, 'pct': round(c / total * 100)} for p, c in result.items()}
Step 5:场景词验证(填写矩阵前必须执行)
def verify_scene(persona_reviews, scene_keywords, min_count=5):
"""
验证某个场景词是否在该Persona评论中出现足够多次
返回 (是否可填写, 实际出现条数)
"""
count = 0
for r in persona_reviews:
text = (r['title'] + ' ' + r['content']).lower()
if any(kw.lower() in text for kw in scene_keywords):
count += 1
return count >= min_count, count
# 示例用法
persona_reviews = [r for r in all_reviews if '粗硬发质' in identify_personas_for_review(r)]
can_fill, cnt = verify_scene(persona_reviews, ['shower', 'bathroom', 'in the shower'])
scene_text = '浴室/淋浴' if can_fill else '—'
Step 6:报告组装流程
- 准备数据:运行 Step 1–5,收集所有统计结果
- 起草 Canvas(在 IDE 中生成
.canvas.tsx文件),等待用户确认内容无误 - 用户确认后:生成 HTML 文件,保存至
分析报告 HTML/目录 - Canvas 与 HTML 内容必须保持同步,修改 Canvas 后须同步更新 HTML
7. 关键阈值与判断规则速查表
| 决策点 | 规则 |
|---|---|
| 有效评论筛选 | verified == True 或 vine == True |
| 差评定义 | rating ≤ 2.0 |
| 好评定义 | rating ≥ 4.0 |
| P0 主题门槛 | 频次 ≥ 有效差评数 × 20%,且 80%+ 竞品出现 |
| P1 主题门槛 | 频次为有效差评数的 10–20%,60%+ 竞品出现 |
| P2 主题门槛 | 频次为有效差评数的 3–10%,40%+ 竞品出现 |
| Persona 占比 | 命中评论数 / 有效总数,四舍五入至整5% |
| 场景词可填写门槛 | ≥ 5 条 Persona 评论中出现该场景词,否则填 — |
| 市场整体判断 | 均分 < 3.5 = 系统性缺陷,新品窗口期 |
| KANO 基本型判断 | P0 级差评,且与低评分强相关 |
| KANO 魅力型判断 | 好评中出现 love/amazing/didn't expect,非差评主题 |
| 新买家识别 | content 含 first time/just got/just bought/new to |
| 复购买家识别 | content 含 reorder/bought again/second time/repurchase |
| 根因分析触发 | 差评主题达到 P0 或 P1 级别 |
| Persona 引用合规 | 只能引用 content 中确实存在的原文,禁止改写或虚构 |
8. 新品类接入清单
每次分析新品类时,依次完成以下配置,其余分析框架直接复用:
□ 1. 确认 CSV 文件路径和 ASIN 列表
□ 2. 阅读**全部差评和全部好评**,按三个维度(A物理特征 / B行为场景 / C购买动机)归纳 Persona,编写 PERSONA_KEYWORDS
□ 3. 执行**自我标注信号强制检查**(搜索 "I have [adj]..." / "As a [noun]..." 等模式),确认无遗漏的物理特征群体
□ 4. 阅读**全部差评(≤2星)**,归纳差评主题,注意根因不同的问题必须拆分为独立主题,编写 NEGATIVE_THEMES
□ 5. 阅读**全部好评(≥4星)**,归纳 4–6 个好评主题,编写 POSITIVE_THEMES
□ 6. 运行 Step 1–3,验证频次统计结果与人工阅读印象一致;同时用 count_theme_per_asin() 生成各 ASIN 的主题频次分布数据,用于 #sec-asin-theme 图表
□ 7. **Persona 完整性验证**:为每个 P0/P1 主题强制归因到 Persona,有 ❌ 则返回步骤 2 补充
□ 8. 对每个 Persona 执行 verify_scene(),确认使用场景字段
□ 9. 完成 KANO 归类(基于统计结果,无需额外数据)
□ 10. 完成 JTBD 框架(基于 Persona 评论,无需额外数据)
□ 11. 撰写根因分析(P0/P1 主题,每条根因附 2-3 条原文引用)
□ 12. 生成 Canvas → 用户确认 → 生成 HTML
本文档为通用框架,无品类特定数据。新品类分析时,只需填写第 8 节清单中的品类相关配置,其余规则和代码模板均可直接复用。