包含 Persona 锚定聚类、LLM 报告生成、方法论文档及 .gitignore 更新,便于在 Gitee 独立部署。 Co-authored-by: Cursor <cursoragent@cursor.com>
815 lines
33 KiB
Markdown
815 lines
33 KiB
Markdown
# VOC 数据清洗、分析与报告生成通用方法论
|
||
|
||
> 文档版本:v1.0 · 2026-06-11
|
||
> 适用范围:亚马逊任意品类竞品 VOC 分析
|
||
> 数据来源:卖家精灵 / Shulex 导出的实时评论 CSV
|
||
> 报告输出:双层结构 HTML 报告(描述层 What + 分析层 Why)
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [原始数据结构](#1-原始数据结构)
|
||
2. [数据清洗规则](#2-数据清洗规则)
|
||
3. [描述层 What — 分析逻辑](#3-描述层-what--分析逻辑)
|
||
- 3.1 有效评论统计
|
||
- 3.2 用户画像(Persona)识别
|
||
- 3.3 正负反馈主题提取
|
||
- 3.4 情感关键词分析
|
||
4. [分析层 Why — 分析逻辑](#4-分析层-why--分析逻辑)
|
||
- 4.1 KANO 模型需求分类
|
||
- 4.2 JTBD 动机框架
|
||
- 4.3 人群 × 场景 × 需求矩阵
|
||
- 4.4 痛点根因分析
|
||
5. [报告生成逻辑](#5-报告生成逻辑)
|
||
- 5.1 HTML 整体结构
|
||
- 5.2 可视化组件
|
||
- 5.3 使用场景字段写入规则(核心规则)
|
||
6. [执行 SOP(逐步操作流程)](#6-执行-sop逐步操作流程)
|
||
7. [关键阈值与判断规则速查表](#7-关键阈值与判断规则速查表)
|
||
8. [新品类接入清单](#8-新品类接入清单)
|
||
|
||
---
|
||
|
||
## 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 有效评论筛选(不可更改的核心规则)
|
||
|
||
**只保留以下两类评论,其余全部排除:**
|
||
|
||
```python
|
||
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 识别词的建立原则
|
||
|
||
1. **阅读全部差评(≤2星)**,找出用户描述自身处境的词汇("I have... / I am... / As a...")
|
||
2. **阅读全部好评(≥4星)**,找出用户描述自身需求背景的词汇
|
||
3. 从中归纳出 4–6 个差异化的用户群体
|
||
4. 每个群体设定 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 识别词模板格式
|
||
|
||
```python
|
||
PERSONA_KEYWORDS = {
|
||
'{群体名称A}': ['{关键词1}', '{关键词2}', ...],
|
||
'{群体名称B}': ['{关键词1}', '{关键词2}', ...],
|
||
# 根据实际品类补充
|
||
}
|
||
```
|
||
|
||
#### Persona 占比估算规则
|
||
|
||
```
|
||
占比 = 命中该Persona识别词的评论数 / 有效评论总数
|
||
四舍五入至整5%
|
||
```
|
||
|
||
> 因一条评论可被多个 Persona 命中,各 Persona 占比之和可超过 100%。
|
||
|
||
#### Persona 卡片内容规格(每个群体输出以下信息)
|
||
|
||
| 字段 | 来源 | 说明 |
|
||
|---|---|---|
|
||
| 群体名称 | 自定义 | 简洁描述身份特征,≤6 字 |
|
||
| 占比 | 统计计算 | 见上方公式 |
|
||
| 核心痛点 | 该群体差评 | ≤3 条,原文语义概括 |
|
||
| 核心需求 | 该群体好评+诉求 | ≤3 条 |
|
||
| 购买动机 | JTBD 分析 | 用"雇佣产品做什么"句式 |
|
||
| 代表性引用 | 真实评论原文 | 必须来自实际评论,注明 ASIN |
|
||
|
||
### 3.3 正负反馈主题提取
|
||
|
||
#### 主题识别关键词组的建立方法
|
||
|
||
1. 阅读**全部差评(≤2星)**,记录用户描述问题时的高频词
|
||
2. 将语义相近的词归为同一主题,形成关键词组
|
||
3. 每个主题设定 5–10 个关键词
|
||
4. 覆盖 80%+ 的差评内容(长尾主题可合并为"其他")
|
||
|
||
#### ⚠️ 主题拆分规则:相近但机制不同的问题必须独立成主题
|
||
|
||
语义相近不等于根因相同。以下情况**必须拆分为独立主题,不得合并**:
|
||
|
||
| 合并后失真的典型例子 | 应该如何拆分 | 原因 |
|
||
|---|---|---|
|
||
| "剃效差"(笼统) | ① 留茬/剃不干净 ② 拉扯/扯毛而非切断 | 机制不同:留茬=刀头贴肤不足;拉扯=刀片咬不断粗硬毛,影响人群完全不同 |
|
||
| "皮肤问题"(笼统) | ① 割伤/出血 ② 摩擦热/灼烧感 ③ 剃须疹/内生毛 | 根因不同,对应不同的工程解决方案 |
|
||
| "产品损坏"(笼统) | ① 充电失效 ② 配件断裂/脱落 | 分属电气系统和结构系统,受影响时间节点不同(充电=使用初期;断裂=一段时间后) |
|
||
|
||
> **判断是否需要拆分的问题**:
|
||
> "同一主题下的差评,是否描述的是同一个物理/工程原因?"
|
||
> 如果不是,必须拆开。
|
||
|
||
**通用差评主题模板格式**:
|
||
|
||
```python
|
||
NEGATIVE_THEMES = {
|
||
'{主题名称}': ['{关键词1}', '{关键词2}', ...],
|
||
# 品类相关主题
|
||
}
|
||
```
|
||
|
||
**通用好评主题模板格式**:
|
||
|
||
```python
|
||
POSITIVE_THEMES = {
|
||
'{主题名称}': ['{关键词1}', '{关键词2}', ...],
|
||
}
|
||
```
|
||
|
||
#### 频次统计规则
|
||
|
||
1. 在 `title + content` 中搜索关键词
|
||
2. 同一评论中同一关键词出现多次,仍计为 1 次(避免重复计数)
|
||
3. 差评主题只统计 ≤2 星评论;好评主题只统计 ≥4 星评论
|
||
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,水平条形图)
|
||
|
||
**差评主题柱状图(全市场汇总)**:
|
||
|
||
```javascript
|
||
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 一根柱子。
|
||
|
||
**差评版 — 数据结构**:
|
||
|
||
```javascript
|
||
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)**:
|
||
|
||
```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:数据读取
|
||
|
||
```python
|
||
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:基础统计
|
||
|
||
```python
|
||
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:主题频次统计
|
||
|
||
```python
|
||
# 根据品类自定义主题关键词(见第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 识别
|
||
|
||
```python
|
||
# 根据品类自定义(见第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:场景词验证(填写矩阵前必须执行)
|
||
|
||
```python
|
||
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:报告组装流程
|
||
|
||
1. **准备数据**:运行 Step 1–5,收集所有统计结果
|
||
2. **起草 Canvas**(在 IDE 中生成 `.canvas.tsx` 文件),等待用户确认内容无误
|
||
3. **用户确认后**:生成 HTML 文件,保存至 `分析报告 HTML/` 目录
|
||
4. **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 节清单中的品类相关配置,其余规则和代码模板均可直接复用。*
|