Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

B7. Review 智能分析系统:NLP + 主题建模 + 情感分析

路径: Path B: 技术人 · 模块: B7 最后更新: 2026-03-15 难度: 中级 预计时间: 每天 1 小时,2 周 前置模块: B1 数据采集与处理


章节导航

  1. 为什么需要 Review NLP 系统 · 2. 技术栈选择 · 3. 数据采集与预处理 · 4. 情感分析实战 · 5. BERTopic 主题建模 · 6. LLM 增强分析 · 7. 构建完整 Pipeline · 8. 完成标志

本模块你将构建

  • 一个 Amazon Review 自动采集和清洗 Pipeline
  • 一个基于 BERT 的情感分析模型(正面/负面/中性)
  • 一个 BERTopic 主题建模系统(自动发现 Review 中的核心话题)
  • 一个 LLM 增强的 Review 洞察生成器(从数据到可执行建议)
  • 一个完整的 Review 分析 Dashboard

核心理念:Review 是电商最有价值的非结构化数据。传统方法是人工阅读,AI 方法是自动提取主题、情感和可执行洞察。一个好的 Review NLP 系统可以指导选品、改进产品、优化 Listing、预防差评。


1. 为什么需要 Review NLP 系统

1.1 Review 数据的价值

应用场景输入输出业务价值
选品验证竞品 Review用户痛点排名找到差异化方向
产品改进自己的差评问题分类+频率优先修复最高频问题
Listing 优化好评关键词用户最看重的卖点标题/Bullet 优化
广告优化Review 高频词用户搜索意图广告关键词扩展
客服预防差评趋势早期预警在差评爆发前介入
竞品监控竞品 Review 变化竞品问题/优势变化竞争策略调整

1.2 人工 vs AI 分析对比

维度人工阅读AI NLP 分析
速度100 条/小时10,000 条/分钟
一致性主观判断,不同人结果不同客观一致
覆盖度通常只看最近/最差的全量分析
深度表面理解主题聚类+情感量化+趋势分析
成本高(人力时间)低(一次开发,持续使用)

2. 技术栈选择

2.1 推荐技术栈

Review NLP 系统技术栈:

数据层:
pandas 数据处理
SP-API / 爬虫 Review 采集
SQLite / PostgreSQL 数据存储

NLP 层:
transformers (HuggingFace) BERT 模型
BERTopic 主题建模
sentence-transformers 文本向量化
TextBlob / VADER 快速情感分析(轻量)
spaCy 文本预处理

LLM 增强层:
OpenAI API / Claude API 深度分析
本地 LLM (Ollama) 隐私敏感场景

可视化层:
Streamlit 交互式 Dashboard
matplotlib / plotly 图表
wordcloud 词云

2.2 依赖安装

# 核心依赖
pip3 install pandas numpy
pip3 install transformers torch sentence-transformers
pip3 install bertopic
pip3 install textblob vaderSentiment
pip3 install spacy
python3 -m spacy download en_core_web_sm

# 可视化
pip3 install streamlit plotly wordcloud matplotlib

# LLM(可选)
pip3 install openai anthropic

3. 数据采集与预处理

3.1 Review 数据获取方式

方式优点缺点适合
Amazon SP-API官方 API,稳定合规只能获取自己产品的 Review自有产品分析
网页抓取可获取竞品 Review需要处理反爬、合规风险竞品分析
第三方工具导出简单快速数据格式不统一快速分析
公开数据集免费、大量数据可能过时学习和测试

真实资源:多个教程展示了如何用 Python 抓取 Amazon Review 数据,包括使用 BeautifulSoup、Scrapy 和专业 API 服务(ScrapingBeeOxylabs)。抓取的数据通常包含评分、标题、正文、日期、验证购买状态和有用投票数。

Content rephrased for compliance with licensing restrictions.

真实案例:跨产品 Review 分析 学术研究展示了使用上下文主题建模(Contextual Topic Modeling)和关联规则挖掘对耳机品类的 Amazon Review 进行跨产品分析,发现不同产品之间共享的用户关注点和差异化特征(MDPI)。

Content rephrased for compliance with licensing restrictions.

3.2 Review 数据结构

import pandas as pd

# Review 数据标准格式
review_schema = {
"asin": str, # 产品 ASIN
"rating": int, # 1-5 星
"title": str, # Review 标题
"body": str, # Review 正文
"date": str, # 日期
"verified": bool, # 是否验证购买
"helpful_votes": int, # 有用投票数
"marketplace": str # 市场(US/UK/DE/JP)
}

3.2 数据清洗 Pipeline

import re
import spacy

nlp = spacy.load("en_core_web_sm")

def clean_review(text: str) -> str:
"""清洗 Review 文本"""
if not text or not isinstance(text, str):
return ""

# 移除 HTML 标签
text = re.sub(r'<[^>]+>', '', text)
# 移除 URL
text = re.sub(r'http\S+', '', text)
# 移除多余空白
text = re.sub(r'\s+', ' ', text).strip()

return text

def preprocess_reviews(df: pd.DataFrame) -> pd.DataFrame:
"""预处理 Review DataFrame"""
# 清洗文本
df['clean_body'] = df['body'].apply(clean_review)
df['clean_title'] = df['title'].apply(clean_review)

# 合并标题和正文
df['full_text'] = df['clean_title'] + '. ' + df['clean_body']

# 过滤空文本
df = df[df['full_text'].str.len() > 10]

# 标记情感标签(基于星级的粗略分类)
df['sentiment_label'] = df['rating'].map({
1: 'negative', 2: 'negative',
3: 'neutral',
4: 'positive', 5: 'positive'
})

return df

4. 情感分析实战

4.1 方法对比

方法准确度速度成本适合
VADER中等(70-75%)极快免费快速筛选、大量数据
TextBlob中等(70-75%)极快免费简单场景
DistilBERT高(85-90%)中等免费(本地)精确分析
GPT/Claude API最高(90%+)付费小量高价值分析

4.2 VADER 快速情感分析

from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer

analyzer = SentimentIntensityAnalyzer()

def vader_sentiment(text: str) -> dict:
"""VADER 情感分析(适合英文 Review)"""
scores = analyzer.polarity_scores(text)

# 判断情感
if scores['compound'] >= 0.05:
label = 'positive'
elif scores['compound'] <= -0.05:
label = 'negative'
else:
label = 'neutral'

return {
'label': label,
'score': scores['compound'],
'positive': scores['pos'],
'negative': scores['neg'],
'neutral': scores['neu']
}

# 批量分析
df['vader'] = df['full_text'].apply(vader_sentiment)
df['vader_label'] = df['vader'].apply(lambda x: x['label'])
df['vader_score'] = df['vader'].apply(lambda x: x['score'])

4.3 DistilBERT 深度情感分析

from transformers import pipeline

# 加载预训练情感分析模型
sentiment_pipeline = pipeline(
"sentiment-analysis",
model="distilbert-base-uncased-finetuned-sst-2-english",
device=0 # GPU,如果没有 GPU 用 -1
)

def bert_sentiment(texts: list, batch_size: int = 32) -> list:
"""批量 BERT 情感分析"""
results = sentiment_pipeline(texts, batch_size=batch_size, truncation=True)
return [
{
'label': r['label'].lower(),
'score': r['score'] if r['label'] == 'POSITIVE' else -r['score']
}
for r in results
]

# 批量处理(比逐条快 10x)
texts = df['full_text'].tolist()
sentiments = bert_sentiment(texts)
df['bert_label'] = [s['label'] for s in sentiments]
df['bert_score'] = [s['score'] for s in sentiments]

真实案例:学术研究表明,基于 BERT 的情感分析在 Amazon Review 数据集上可以达到 90%+ 的准确率,显著优于传统机器学习方法(MDPI)。BERTopic 结合 Amazon Review 数据可以自动发现产品的核心话题和用户关注点(Amalytix)。

Content rephrased for compliance with licensing restrictions.


5. BERTopic 主题建模

5.1 BERTopic 核心概念

BERTopic 使用 BERT 嵌入 + UMAP 降维 + HDBSCAN 聚类来自动发现文本中的主题。

from bertopic import BERTopic
from sentence_transformers import SentenceTransformer

# 使用轻量级嵌入模型
embedding_model = SentenceTransformer("all-MiniLM-L6-v2")

# 创建 BERTopic 模型
topic_model = BERTopic(
embedding_model=embedding_model,
nr_topics="auto", # 自动确定主题数
min_topic_size=10, # 最小主题大小
language="english",
verbose=True
)

# 训练模型
topics, probs = topic_model.fit_transform(df['full_text'].tolist())

# 查看主题
topic_info = topic_model.get_topic_info()
print(topic_info.head(20))

# 查看每个主题的关键词
for topic_id in range(min(10, len(topic_info))):
print(f"\nTopic {topic_id}:")
print(topic_model.get_topic(topic_id))

5.2 差评专项主题分析

# 只分析差评(1-2 星)的主题
negative_reviews = df[df['rating'] <= 2]['full_text'].tolist()

negative_topic_model = BERTopic(
embedding_model=embedding_model,
nr_topics=10, # 限制主题数
min_topic_size=5,
language="english"
)

neg_topics, neg_probs = negative_topic_model.fit_transform(negative_reviews)

# 差评主题排名(按频率)
neg_topic_info = negative_topic_model.get_topic_info()
print("=== 差评核心问题 TOP 10 ===")
for _, row in neg_topic_info.head(10).iterrows():
print(f"Topic {row['Topic']}: {row['Name']} ({row['Count']} reviews)")

5.3 主题趋势分析

# 分析主题随时间的变化
topics_over_time = topic_model.topics_over_time(
df['full_text'].tolist(),
df['date'].tolist()
)

# 可视化
fig = topic_model.visualize_topics_over_time(topics_over_time)
fig.show()

# 发现:某个质量问题的差评是否在增加?
# 这可以作为产品改进的早期预警信号

5.4 高级 BERTopic 技巧

真实案例:Amalytix 的 Amazon Review BERTopic 分析 Amalytix 展示了如何用 BERTopic 分析 Amazon Review,自动发现产品的核心话题。BERTopic 使用基于 BERT 的方法和修改后的 TF-IDF 分析,能够从非结构化的 Review 文本中提取有意义的主题聚类(Amalytix)。

Content rephrased for compliance with licensing restrictions.

# 高级技巧 1:按品类分组的主题分析
def analyze_by_category(df: pd.DataFrame, categories: list):
"""按品类分别做主题分析,发现品类特有的问题"""
results = {}
for cat in categories:
cat_df = df[df['category'] == cat]
if len(cat_df) < 50:
continue

model = BERTopic(
embedding_model=embedding_model,
nr_topics=8,
min_topic_size=5
)
topics, _ = model.fit_transform(cat_df['full_text'].tolist())
results[cat] = {
'model': model,
'topics': model.get_topic_info(),
'negative_topics': cat_df[cat_df['rating'] <= 2].groupby(
pd.Series(topics)[cat_df['rating'] <= 2].values
).size().sort_values(ascending=False)
}
return results

# 高级技巧 2:多语言 Review 分析
from sentence_transformers import SentenceTransformer

# 使用多语言嵌入模型(支持 100+ 语言)
multilingual_model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")

multilingual_topic_model = BERTopic(
embedding_model=multilingual_model,
language="multilingual"
)

# 可以同时分析英语、德语、日语的 Review
all_reviews = pd.concat([us_reviews, de_reviews, jp_reviews])
topics, _ = multilingual_topic_model.fit_transform(all_reviews['full_text'].tolist())

# 高级技巧 3:主题标签自动生成(用 LLM)
def auto_label_topics(topic_model, top_n_topics=20):
"""用 LLM 为 BERTopic 发现的主题生成人类可读的标签"""
labels = {}
for topic_id in range(top_n_topics):
keywords = topic_model.get_topic(topic_id)
if not keywords:
continue

keyword_str = ", ".join([w for w, _ in keywords[:10]])

prompt = f"""
以下是从产品 Review 中提取的一个主题的关键词:
{keyword_str}

请用一个简短的中文标签(3-6 个字)描述这个主题。
只返回标签,不要解释。
"""
label = llm_call(prompt).strip()
labels[topic_id] = label

return labels

# 高级技巧 4:Review 质量评分
def score_review_quality(df: pd.DataFrame) -> pd.DataFrame:
"""评估 Review 的信息质量(用于筛选高价值 Review)"""
df['word_count'] = df['full_text'].str.split().str.len()
df['has_specific_detail'] = df['full_text'].str.contains(
r'\d+\s*(day|week|month|hour|minute|inch|cm|kg|lb|oz)',
case=False, regex=True
)
df['has_comparison'] = df['full_text'].str.contains(
r'(better than|worse than|compared to|vs|versus|unlike)',
case=False, regex=True
)
df['quality_score'] = (
(df['word_count'] > 30).astype(int) * 2 +
df['has_specific_detail'].astype(int) * 3 +
df['has_comparison'].astype(int) * 3 +
(df['helpful_votes'] > 0).astype(int) * 2
)
return df

6. LLM 增强分析

6.1 用 LLM 生成可执行洞察

BERTopic 发现主题,LLM 解读主题并生成建议:

import anthropic # 或 openai

client = anthropic.Anthropic()

def generate_review_insights(topic_info: dict, sample_reviews: list) -> str:
"""用 LLM 从 Review 主题生成可执行洞察"""
prompt = f"""
你是一个电商产品分析专家。以下是 Amazon Review 的 NLP 分析结果。

产品:[产品名]
分析的 Review 总数:{topic_info['total_reviews']}
时间范围:{topic_info['date_range']}

差评主题排名(按频率):
{topic_info['negative_topics']}

好评主题排名:
{topic_info['positive_topics']}

差评样本(每个主题 3 条):
{sample_reviews}

请生成:
1. 产品核心问题排名(按严重程度和频率)
2. 每个问题的具体改进建议
3. 用户最看重的 3 个卖点(用于 Listing 优化)
4. 竞品差异化机会(基于用户未满足的需求)
5. 预警信号(哪些问题在恶化?)
6. 优先级行动清单(ROI 最高的改进先做)
"""

response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2000,
messages=[{"role": "user", "content": prompt}]
)

return response.content[0].text

6.2 竞品 Review 对比分析

def competitive_review_analysis(my_reviews: pd.DataFrame,
competitor_reviews: pd.DataFrame) -> str:
"""对比自己和竞品的 Review 主题"""

# 分别做主题建模
my_topics = run_bertopic(my_reviews)
comp_topics = run_bertopic(competitor_reviews)

# 用 LLM 对比分析
prompt = f"""
对比两个产品的 Review 分析结果:

我的产品:
- 平均评分:{my_reviews['rating'].mean():.1f}
- 差评主题:{my_topics['negative']}
- 好评主题:{my_topics['positive']}

竞品:
- 平均评分:{competitor_reviews['rating'].mean():.1f}
- 差评主题:{comp_topics['negative']}
- 好评主题:{comp_topics['positive']}

请分析:
1. 我的产品 vs 竞品的优势和劣势
2. 竞品的差评中有哪些是我可以利用的机会
3. 我的差评中哪些问题竞品已经解决了
4. 差异化定位建议
"""
return llm_call(prompt)

7. 构建完整 Pipeline

7.1 端到端 Review 分析 Pipeline

class ReviewAnalysisPipeline:
"""完整的 Review 分析 Pipeline"""

def __init__(self, embedding_model="all-MiniLM-L6-v2"):
self.embedding_model = SentenceTransformer(embedding_model)
self.sentiment_pipeline = pipeline(
"sentiment-analysis",
model="distilbert-base-uncased-finetuned-sst-2-english"
)
self.topic_model = None

def run(self, reviews_df: pd.DataFrame) -> dict:
"""运行完整分析"""
# Step 1: 预处理
df = preprocess_reviews(reviews_df)

# Step 2: 情感分析
sentiments = self.sentiment_pipeline(
df['full_text'].tolist(),
batch_size=32, truncation=True
)
df['sentiment'] = [s['label'].lower() for s in sentiments]

# Step 3: 主题建模
self.topic_model = BERTopic(
embedding_model=self.embedding_model,
nr_topics="auto",
min_topic_size=5
)
topics, _ = self.topic_model.fit_transform(df['full_text'].tolist())
df['topic'] = topics

# Step 4: 汇总
results = {
'total_reviews': len(df),
'avg_rating': df['rating'].mean(),
'sentiment_dist': df['sentiment'].value_counts().to_dict(),
'rating_dist': df['rating'].value_counts().to_dict(),
'topics': self.topic_model.get_topic_info().to_dict(),
'negative_topics': self._get_negative_topics(df),
'positive_topics': self._get_positive_topics(df),
'trends': self._get_trends(df)
}

# Step 5: LLM 洞察
results['insights'] = generate_review_insights(results,
df[df['rating'] <= 2].sample(min(15, len(df[df['rating'] <= 2])))
)

return results

def _get_negative_topics(self, df):
neg = df[df['rating'] <= 2]
return neg.groupby('topic').size().sort_values(ascending=False).head(10)

def _get_positive_topics(self, df):
pos = df[df['rating'] >= 4]
return pos.groupby('topic').size().sort_values(ascending=False).head(10)

def _get_trends(self, df):
df['month'] = pd.to_datetime(df['date']).dt.to_period('M')
return df.groupby('month')['rating'].mean()

7.2 Streamlit Dashboard(完整实现)

# review_dashboard.py Review 智能分析 Dashboard
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np

st.set_page_config(page_title="Review 智能分析", layout="wide")
st.title(" Review 智能分析系统")

# === 侧边栏 ===
with st.sidebar:
st.header(" 数据上传")
uploaded_file = st.file_uploader("上传 Review CSV", type="csv")

if uploaded_file:
st.header(" 分析设置")
min_rating = st.slider("最低评分筛选", 1, 5, 1)
max_rating = st.slider("最高评分筛选", 1, 5, 5)
num_topics = st.slider("主题数量", 5, 30, 10)
analysis_type = st.selectbox(
"分析类型",
["全部 Review", "仅差评 (1-2星)", "仅好评 (4-5星)", "中评 (3星)"]
)

if uploaded_file:
df = pd.read_csv(uploaded_file)
df = preprocess_reviews(df)

# 筛选
df_filtered = df[(df['rating'] >= min_rating) & (df['rating'] <= max_rating)]

# === Tab 1: 概览 ===
tab1, tab2, tab3, tab4, tab5 = st.tabs([
" 概览", " 情感分析", " 主题建模", " 趋势", " AI 洞察"
])

with tab1:
# KPI 卡片
col1, col2, col3, col4, col5 = st.columns(5)
col1.metric("总 Review", f"{len(df_filtered):,}")
col2.metric("平均评分", f"{df_filtered['rating'].mean():.2f} ")
col3.metric("差评率", f"{(df_filtered['rating'] <= 2).mean()*100:.1f}%")
col4.metric("好评率", f"{(df_filtered['rating'] >= 4).mean()*100:.1f}%")
col5.metric("验证购买", f"{df_filtered['verified'].mean()*100:.0f}%")

# 评分分布
col1, col2 = st.columns(2)
with col1:
rating_dist = df_filtered['rating'].value_counts().sort_index()
fig = px.bar(x=rating_dist.index, y=rating_dist.values,
labels={'x': '评分', 'y': '数量'},
title="评分分布",
color=rating_dist.index,
color_continuous_scale=['red', 'orange', 'yellow', 'lightgreen', 'green'])
st.plotly_chart(fig, use_container_width=True)

with col2:
# 词云
all_text = ' '.join(df_filtered['full_text'].tolist())
wc = WordCloud(width=800, height=400, background_color='white',
max_words=100, colormap='viridis').generate(all_text)
fig_wc, ax = plt.subplots(figsize=(10, 5))
ax.imshow(wc, interpolation='bilinear')
ax.axis('off')
st.pyplot(fig_wc)

with tab2:
st.subheader(" 情感分析")

# 运行情感分析
with st.spinner("正在分析情感..."):
sentiments = bert_sentiment(df_filtered['full_text'].tolist())
df_filtered['sentiment'] = [s['label'] for s in sentiments]
df_filtered['sentiment_score'] = [s['score'] for s in sentiments]

# 情感分布
col1, col2 = st.columns(2)
with col1:
sent_dist = df_filtered['sentiment'].value_counts()
fig = px.pie(values=sent_dist.values, names=sent_dist.index,
title="情感分布",
color_discrete_map={'positive': 'green', 'negative': 'red', 'neutral': 'gray'})
st.plotly_chart(fig, use_container_width=True)

with col2:
# 情感 vs 评分的关系
fig = px.box(df_filtered, x='rating', y='sentiment_score',
title="情感得分 vs 评分",
labels={'rating': '评分', 'sentiment_score': '情感得分'})
st.plotly_chart(fig, use_container_width=True)

# 情感最极端的 Review
st.subheader("最正面的 Review")
top_positive = df_filtered.nlargest(3, 'sentiment_score')
for _, row in top_positive.iterrows():
st.success(f"{row['rating']} | {row['full_text'][:200]}...")

st.subheader("最负面的 Review")
top_negative = df_filtered.nsmallest(3, 'sentiment_score')
for _, row in top_negative.iterrows():
st.error(f"{row['rating']} | {row['full_text'][:200]}...")

with tab3:
st.subheader(" 主题建模 (BERTopic)")

with st.spinner("正在提取主题..."):
topic_model = BERTopic(
embedding_model=embedding_model,
nr_topics=num_topics,
min_topic_size=5
)
topics, probs = topic_model.fit_transform(df_filtered['full_text'].tolist())
df_filtered['topic'] = topics

# 主题概览
topic_info = topic_model.get_topic_info()
st.dataframe(topic_info[['Topic', 'Count', 'Name']].head(20),
use_container_width=True)

# 主题可视化
try:
fig = topic_model.visualize_barchart(top_n_topics=10)
st.plotly_chart(fig, use_container_width=True)
except:
pass

# 差评专项主题
st.subheader(" 差评核心问题")
neg_df = df_filtered[df_filtered['rating'] <= 2]
if len(neg_df) > 10:
neg_topic_counts = neg_df.groupby('topic').size().sort_values(ascending=False)
for topic_id in neg_topic_counts.head(5).index:
if topic_id == -1:
continue
keywords = topic_model.get_topic(topic_id)
keyword_str = ", ".join([w for w, _ in keywords[:5]])
count = neg_topic_counts[topic_id]
st.warning(f"**Topic {topic_id}** ({count} 条差评): {keyword_str}")

# 显示该主题的示例 Review
examples = neg_df[neg_df['topic'] == topic_id]['full_text'].head(2)
for ex in examples:
st.caption(f" → {ex[:150]}...")

with tab4:
st.subheader(" 趋势分析")

df_filtered['month'] = pd.to_datetime(df_filtered['date']).dt.to_period('M').astype(str)

# 月度评分趋势
monthly = df_filtered.groupby('month').agg({
'rating': 'mean',
'full_text': 'count'
}).reset_index()
monthly.columns = ['月份', '平均评分', 'Review 数量']

fig = go.Figure()
fig.add_trace(go.Bar(x=monthly['月份'], y=monthly['Review 数量'], name='Review 数量'))
fig.add_trace(go.Scatter(x=monthly['月份'], y=monthly['平均评分'],
name='平均评分', yaxis='y2', mode='lines+markers'))
fig.update_layout(
title="月度 Review 趋势",
yaxis=dict(title='Review 数量'),
yaxis2=dict(title='平均评分', overlaying='y', side='right', range=[1, 5])
)
st.plotly_chart(fig, use_container_width=True)

with tab5:
st.subheader(" AI 洞察")

if st.button("生成 AI 分析报告"):
with st.spinner("AI 正在分析..."):
insights = generate_review_insights({
'total_reviews': len(df_filtered),
'avg_rating': df_filtered['rating'].mean(),
'negative_topics': str(neg_topic_counts.head(5).to_dict()) if 'neg_topic_counts' in dir() else "N/A",
'positive_topics': "N/A",
'date_range': f"{df_filtered['date'].min()} to {df_filtered['date'].max()}"
}, df_filtered[df_filtered['rating'] <= 2].head(10).to_dict())

st.markdown(insights)

# 下载报告
st.download_button(
" 下载分析报告",
insights,
file_name=f"review_analysis_{datetime.now().strftime('%Y%m%d')}.md",
mime="text/markdown"
)

else:
st.info(" 请在左侧上传 Review CSV 文件开始分析")
st.markdown("""
**CSV 文件格式要求:**
- `rating`: 评分 (1-5)
- `title`: Review 标题
- `body`: Review 正文
- `date`: 日期
- `verified`: 是否验证购买 (True/False)
- `helpful_votes`: 有用投票数(可选)
""")

运行:streamlit run review_dashboard.py

7.3 导出分析结果

def export_analysis_results(df: pd.DataFrame, topic_model, output_dir: str = "output"):
"""导出完整的分析结果"""
from pathlib import Path
Path(output_dir).mkdir(exist_ok=True)

# 1. 导出带标注的 Review 数据
df.to_csv(f"{output_dir}/reviews_analyzed.csv", index=False)

# 2. 导出主题摘要
topic_info = topic_model.get_topic_info()
topic_info.to_csv(f"{output_dir}/topics_summary.csv", index=False)

# 3. 导出差评主题详情
neg_df = df[df['rating'] <= 2]
neg_topics = neg_df.groupby('topic').agg({
'full_text': 'count',
'rating': 'mean'
}).sort_values('full_text', ascending=False)
neg_topics.to_csv(f"{output_dir}/negative_topics.csv")

# 4. 生成 HTML 报告
html_report = topic_model.visualize_topics()
html_report.write_html(f"{output_dir}/topic_visualization.html")

print(f"分析结果已导出到 {output_dir}/")

8. 完成标志

  • 构建 Review 数据采集和清洗 Pipeline
  • 实现 VADER + BERT 双层情感分析
  • 用 BERTopic 对至少 1000 条 Review 做主题建模
  • 用 LLM 生成可执行的 Review 洞察报告
  • 构建 Streamlit Dashboard 展示分析结果
  • 完成一次竞品 Review 对比分析

(b6-mcp-agentic-workflow.md) | Path 总览 | B8 Dashboard >