商品评论情感分析之思路分析
1 课程概览
本课分析商品评论情感分析的实现思路。需求是根据商品评论进行好评和差评分类。核心步骤包括:读数据、分词、删除无效词、特征提取、训练模型。
2 核心概念与定义
- 情感分类:好评和差评的二分类。
- 分词:将句子拆分成词语。
- 结巴分词器:jieba,Python分词库。
- 无效词:对分类无意义的词(如标点符号)。
- 特征:评论内容。
- 标签:1表示好评,0表示差评。
3 算法与模型详解
3.1 需求分析
需求:已知商品评论,根据数据进行情感分类(好评和差评)
数据:
- 内容列:评论内容(特征)
- 标签:好评/差评(需新增labels列)
标签处理:
- 1:好评
- 0:差评
3.2 为什么需要分词
问题:直接用整句话判断没有意义
示例:
- "从编程小白的角度看,入门极佳"
- "从编程角度看"(去掉"小白"和"从")
- "从编程角度看"(太灵活,无法判断)
原因:
- 整句话太灵活
- 需要拆分成词语
- 不同词语组合有不同含义
示例:
- "小明一把把把把住了"
- "一把"(动词)、"把"(车把)、"把住了"(抓住了)
3.3 为什么需要删除无效词
问题:分词后有些词对分类无意义
无效词示例:
- 逗号、句号等标点符号
- "从"、"的"等虚词
- 模棱两可的词
目的:只保留决定好评或差评的词
3.4 实现步骤
- 读数据:加载商品评论
- 新增标签列:好评1,差评0
- 分词:使用jieba分词器
- 删除无效词:去除标点符号等
- 特征提取:词频向量化
- 训练模型:朴素贝叶斯
- 评估模型
3.5 结巴分词器
安装:
pip install jieba
使用:
import jieba
words = jieba.cut("从编程小白的角度看,入门极佳")
特点:
- 不仅Python使用,Java等其他语言也支持
- 是一个分词库
3.6 朴素贝叶斯API
from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB(alpha=1.0) # alpha是拉普拉斯平滑系数
参数:
alpha:拉普拉斯平滑系数,默认1.0- 作用:防止分母为0
4 代码示例
import pandas as pd
import numpy as np
import jieba
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 1. 模拟商品评论数据
print("=== 模拟商品评论数据 ===")
data = pd.DataFrame({
'content': [
'从编程小白的角度看,入门极佳,推荐购买',
'质量很好,用起来很舒服,好评',
'性价比高,值得入手,非常满意',
'物流快,包装好,质量不错',
'差评,质量太差了,浪费钱',
'不好用,太失望了,不推荐',
'太差了,退货了,质量堪忧',
'失望,与描述不符,差评'
],
'sentiment': ['好评', '好评', '好评', '好评', '差评', '差评', '差评', '差评']
})
# 新增labels列
data['labels'] = data['sentiment'].map({'好评': 1, '差评': 0})
print(data)
# 2. 分词
print("\n=== 分词 ===")
def cut_words(text):
"""使用jieba分词"""
words = jieba.cut(text)
return ' '.join(words)
# 对所有评论进行分词
data['cut_content'] = data['content'].apply(cut_words)
for _, row in data.iterrows():
print(f"原文: {row['content']}")
print(f"分词: {row['cut_content']}")
print()
# 3. 删除无效词
print("=== 删除无效词 ===")
# 定义无效词列表
stop_words = [',', '。', '、', '了', '的', '从', '看', '很', '太']
def remove_stop_words(text):
"""删除无效词"""
words = text.split()
valid_words = [word for word in words if word not in stop_words]
return ' '.join(valid_words)
data['clean_content'] = data['cut_content'].apply(remove_stop_words)
for _, row in data.iterrows():
print(f"分词后: {row['cut_content']}")
print(f"清理后: {row['clean_content']}")
print()
# 4. 特征提取
print("=== 特征提取 ===")
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(data['clean_content'])
print(f"特征矩阵形状: {X.shape}")
print(f"特征名称: {vectorizer.get_feature_names_out()}")
# 5. 划分数据集
print("\n=== 划分数据集 ===")
y = data['labels']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42
)
print(f"训练集: {X_train.shape}")
print(f"测试集: {X_test.shape}")
# 6. 训练模型
print("\n=== 训练模型 ===")
nb = MultinomialNB(alpha=1.0)
nb.fit(X_train, y_train)
# 7. 评估模型
print("\n=== 评估模型 ===")
y_pred = nb.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f"准确率: {acc:.4f}")
# 8. 预测新评论
print("\n=== 预测新评论 ===")
new_comments = [
'质量很好,推荐购买',
'太差了,浪费钱'
]
for comment in new_comments:
# 分词
cut_comment = cut_words(comment)
# 删除无效词
clean_comment = remove_stop_words(cut_comment)
# 向量化
X_new = vectorizer.transform([clean_comment])
# 预测
pred = nb.predict(X_new)[0]
proba = nb.predict_proba(X_new)[0]
label = '好评' if pred == 1 else '差评'
print(f"评论: {comment}")
print(f"分词: {cut_comment}")
print(f"清理: {clean_comment}")
print(f"预测: {label} (好评概率: {proba[1]:.4f})")
print()
# 9. 完整流程函数
def sentiment_analysis_pipeline():
"""情感分析完整流程"""
print("=" * 50)
print("商品评论情感分析")
print("=" * 50)
# 1. 读数据
print("\n1. 读数据")
data = pd.DataFrame({
'content': [
'从编程小白的角度看,入门极佳,推荐购买',
'质量很好,用起来很舒服,好评',
'性价比高,值得入手,非常满意',
'物流快,包装好,质量不错',
'差评,质量太差了,浪费钱',
'不好用,太失望了,不推荐',
'太差了,退货了,质量堪忧',
'失望,与描述不符,差评'
],
'labels': [1, 1, 1, 1, 0, 0, 0, 0]
})
print(f" 数据量: {len(data)}")
# 2. 分词
print("\n2. 分词")
data['cut_content'] = data['content'].apply(cut_words)
# 3. 删除无效词
print("\n3. 删除无效词")
data['clean_content'] = data['cut_content'].apply(remove_stop_words)
# 4. 特征提取
print("\n4. 特征提取")
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(data['clean_content'])
y = data['labels']
print(f" 特征数: {X.shape[1]}")
# 5. 划分数据集
print("\n5. 划分数据集")
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42
)
# 6. 训练模型
print("\n6. 训练模型")
nb = MultinomialNB(alpha=1.0)
nb.fit(X_train, y_train)
# 7. 评估
print("\n7. 评估模型")
y_pred = nb.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f" 准确率: {acc:.4f}")
return nb, vectorizer
# 运行完整流程
nb, vectorizer = sentiment_analysis_pipeline()
输出示例:
=== 模拟商品评论数据 ===
content sentiment labels
0 从编程小白的角度看,入门极佳,推荐购买 好评 1
...
=== 分词 ===
原文: 从编程小白的角度看,入门极佳,推荐购买
分词: 从 编程 小白 的 角度 看 , 入门 极佳 , 推荐 购买
=== 删除无效词 ===
分词后: 从 编程 小白 的 角度 看 , 入门 极佳 , 推荐 购买
清理后: 编程 小白 角度 入门 极佳 推荐 购买
=== 特征提取 ===
特征矩阵形状: (8, 20)
=== 划分数据集 ===
训练集: (6, 20)
测试集: (2, 20)
=== 训练模型 ===
=== 评估模型 ===
准确率: 1.0000
=== 预测新评论 ===
评论: 质量很好,推荐购买
分词: 质量 很好 , 推荐 购买
清理: 质量 很好 推荐 购买
预测: 好评 (好评概率: 0.7856)
评论: 太差了,浪费钱
分词: 太差 了 , 浪费 钱
清理: 太差 浪费 钱
预测: 差评 (好评概率: 0.1234)
5 重难点与易错提醒
- ❗重点:分词是情感分析的关键步骤。
- ❗重点:删除无效词提高分类效果。
- ❗重点:标签用1和0表示好评和差评。
- ❗重点:使用jieba进行中文分词。
- ⚠️易错:忘记分词直接用整句话。
- ⚠️易错:无效词未删除导致干扰。
- 💡深入理解:分词和清理是NLP的基础步骤。
6 课堂问答精选
Q: 为什么需要分词?
A: 直接用整句话判断没有意义,因为:
- 整句话太灵活,不同组合有不同含义
- 程序无法理解整句话的语义
- 需要拆分成词语,提取关键词
- 例如"小明一把把把把住了",需要正确分词才能理解
Q: 什么是无效词?为什么要删除?
A: 无效词是对分类无意义的词,如标点符号(逗号、句号)、虚词(的、了、从)等。删除无效词的原因:
- 这些词对判断好评或差评没有帮助
- 会干扰模型的判断
- 只保留有意义的词,提高分类效果
7 本课小结
- 需求:商品评论情感分类(好评/差评)。
- 步骤:读数据 → 分词 → 删无效词 → 特征提取 → 训练。
- 分词:使用jieba分词器。
- 删词:去除标点符号等无效词。
- 标签:1好评,0差评。
8 延伸思考与实践
- 实践:运行情感分析示例。
- 预习:数据预处理详细步骤。
- 思考:如何选择有效的无效词列表?