商品评论情感分析之模型训练和预测
1 课程概览
本课完成商品评论情感分析的模型训练和预测部分。包括特征和标签准备、数据集划分、模型训练、预测和评估。
2 核心概念与定义
- fit_transform:先训练再转换,一个函数抵两个。
- 词频矩阵:每行代表一条评论,每列代表一个词。
- 数据集划分:前10条训练,后3条测试。
- MultinomialNB:朴素贝叶斯分类器。
- accuracy_score:准确率评估。
3 算法与模型详解
3.1 特征和标签
X(特征):词频矩阵
- 每行代表一条评论
- 每列代表一个词
- 值表示该词在评论中出现的次数
Y(标签):
- 1:好评
- 0:差评
3.2 fit_transform优化
原始写法:
transfer = CountVectorizer()
X = transfer.fit(data['cut_content'])
X = transfer.transform(data['cut_content'])
优化写法:
transfer = CountVectorizer()
X = transfer.fit_transform(data['cut_content'])
说明:fit_transform = fit + transform
3.3 词频矩阵解读
示例:37个词的特征矩阵
第一条评论:[0, 0, 0, 0, 0, 1, 0, ...]
- 第6个词(入门)出现1次
- 其他词为0
说明:
- 数据量越大,切词后词越多
- 词越多,预测越精准
- 但运算量也越大
3.4 数据集划分
# 前10条训练,后3条测试
X_train = X[:10]
X_test = X[10:]
y_train = y[:10]
y_test = y[10:]
3.5 模型训练
from sklearn.naive_bayes import MultinomialNB
estimator = MultinomialNB()
estimator.fit(X_train, y_train)
3.6 模型预测和评估
# 预测
y_predict = estimator.predict(X_test)
print(f"模型预测结果: {y_predict}")
# 评估
acc = accuracy_score(y_test, y_predict)
print(f"准确率: {acc}")
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.metrics import accuracy_score
# 1. 准备数据
print("=== 1. 准备数据 ===")
data = pd.DataFrame({
'content': [
'从编程小白的角度看,入门极佳,推荐购买',
'质量很好,用起来很舒服,好评',
'性价比高,值得入手,非常满意',
'物流快,包装好,质量不错',
'差评,质量太差了,浪费钱',
'不好用,太失望了,不推荐',
'太差了,退货了,质量堪忧',
'失望,与描述不符,差评',
'这本书写得很好,通俗易懂,推荐',
'内容丰富,案例多,值得一看',
'纸张质量差,印刷模糊,差评',
'内容空洞,没有实质内容,不推荐',
'一般般,不值得这个价格'
],
'sentiment': ['好评', '好评', '好评', '好评', '差评', '差评',
'差评', '差评', '好评', '好评', '差评', '差评', '差评']
})
# 新增标签列
data['labels'] = np.where(data['sentiment'] == '好评', 1, 0)
print(f"数据量: {len(data)}")
print(f"好评数: {sum(data['labels'] == 1)}")
print(f"差评数: {sum(data['labels'] == 0)}")
# 2. 分词和清理
print("\n=== 2. 分词和清理 ===")
stop_words = [',', '。', '、', '了', '的', '从', '看', '很', '太', '是',
'在', '和', '与', '都', '也', '就', '只', '还', '又', '但']
def cut_words(text):
"""分词并删除停用词"""
words = jieba.lcut(text)
valid_words = [word for word in words if word not in stop_words and word.strip()]
return ' '.join(valid_words)
data['cut_content'] = data['content'].apply(cut_words)
# 3. 特征提取
print("\n=== 3. 特征提取 ===")
# 使用fit_transform(优化写法)
transfer = CountVectorizer()
X = transfer.fit_transform(data['cut_content'])
print(f"词频矩阵形状: {X.shape}")
print(f"特征数量: {X.shape[1]}")
# 查看特征名称
feature_names = transfer.get_feature_names_out()
print(f"\n前10个特征: {feature_names[:10]}")
# 查看第一条评论的词频
print(f"\n第一条评论词频: {X[0].toarray()}")
# 4. 准备标签
y = data['labels']
# 5. 划分数据集
print("\n=== 5. 划分数据集 ===")
# 前10条训练,后3条测试
X_train = X[:10]
X_test = X[10:]
y_train = y[:10]
y_test = y[10:]
print(f"训练集: {X_train.shape}")
print(f"测试集: {X_test.shape}")
# 6. 模型训练
print("\n=== 6. 模型训练 ===")
estimator = MultinomialNB()
estimator.fit(X_train, y_train)
print("模型训练完成")
# 7. 模型预测
print("\n=== 7. 模型预测 ===")
y_predict = estimator.predict(X_test)
print(f"模型预测结果: {y_predict}")
print(f"真实标签: {y_test.values}")
# 8. 模型评估
print("\n=== 8. 模型评估 ===")
acc = accuracy_score(y_test, y_predict)
print(f"准确率: {acc:.4f}")
# 使用score方法
score = estimator.score(X_test, y_test)
print(f"score方法准确率: {score:.4f}")
# 9. 预测新评论
print("\n=== 9. 预测新评论 ===")
new_comments = [
'质量很好,推荐购买,非常满意',
'太差了,浪费钱,不推荐',
'一般般,不值得这个价格'
]
for comment in new_comments:
# 分词
cut_comment = cut_words(comment)
# 向量化
X_new = transfer.transform([cut_comment])
# 预测
pred = estimator.predict(X_new)[0]
proba = estimator.predict_proba(X_new)[0]
label = '好评' if pred == 1 else '差评'
print(f"评论: {comment}")
print(f"分词: {cut_comment}")
print(f"预测: {label} (好评概率: {proba[1]:.4f})")
print()
# 10. 完整流程
def sentiment_analysis_complete():
"""情感分析完整流程"""
print("=" * 50)
print("商品评论情感分析 - 完整流程")
print("=" * 50)
# 1. 数据准备
print("\n1. 数据准备")
data = pd.DataFrame({
'content': [
'从编程小白的角度看,入门极佳,推荐购买',
'质量很好,用起来很舒服,好评',
'性价比高,值得入手,非常满意',
'物流快,包装好,质量不错',
'差评,质量太差了,浪费钱',
'不好用,太失望了,不推荐',
'太差了,退货了,质量堪忧',
'失望,与描述不符,差评',
'这本书写得很好,通俗易懂,推荐',
'内容丰富,案例多,值得一看',
'纸张质量差,印刷模糊,差评',
'内容空洞,没有实质内容,不推荐',
'一般般,不值得这个价格'
],
'labels': [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0]
})
# 2. 分词
print("\n2. 分词")
stop_words = [',', '。', '、', '了', '的', '从', '看', '很', '太', '是']
data['cut_content'] = data['content'].apply(
lambda x: ' '.join([w for w in jieba.lcut(x)
if w not in stop_words and w.strip()])
)
# 3. 特征提取
print("\n3. 特征提取")
transfer = CountVectorizer()
X = transfer.fit_transform(data['cut_content'])
y = data['labels']
print(f" 特征数: {X.shape[1]}")
# 4. 划分数据集
print("\n4. 划分数据集")
X_train, X_test = X[:10], X[10:]
y_train, y_test = y[:10], y[10:]
# 5. 模型训练
print("\n5. 模型训练")
estimator = MultinomialNB()
estimator.fit(X_train, y_train)
# 6. 模型预测
print("\n6. 模型预测")
y_pred = estimator.predict(X_test)
print(f" 预测结果: {y_pred}")
print(f" 真实标签: {y_test.values}")
# 7. 模型评估
print("\n7. 模型评估")
acc = accuracy_score(y_test, y_pred)
print(f" 准确率: {acc:.4f}")
return estimator, transfer
# 运行
estimator, transfer = sentiment_analysis_complete()
输出示例:
=== 1. 准备数据 ===
数据量: 13
好评数: 6
差评数: 7
=== 2. 分词和清理 ===
=== 3. 特征提取 ===
词频矩阵形状: (13, 37)
特征数量: 37
=== 5. 划分数据集 ===
训练集: (10, 37)
测试集: (3, 37)
=== 6. 模型训练 ===
模型训练完成
=== 7. 模型预测 ===
模型预测结果: [0 0 0]
真实标签: [0 0 0]
=== 8. 模型评估 ===
准确率: 1.0000
score方法准确率: 1.0000
=== 9. 预测新评论 ===
评论: 质量很好,推荐购买,非常满意
预测: 好评 (好评概率: 0.7856)
评论: 太差了,浪费钱,不推荐
预测: 差评 (好评概率: 0.1234)
5 重难点与易错提醒
- ❗重点:fit_transform = fit + transform。
- ❗重点:词频矩阵每行代表一条评论。
- ❗重点:数据量越大,词越多,预测越精准。
- ❗重点:MultinomialNB是朴素贝叶斯分类器。
- ⚠️易错:忘记划分训练集和测试集。
- ⚠️易错:混淆predict和predict_proba。
- 💡深入理解:词频矩阵是文本分类的基础。
6 课堂问答精选
Q: fit_transform和fit + transform有什么区别?
A: 没有区别,fit_transform就是fit和transform的组合,一个函数抵两个:
# 等价写法
transfer.fit(data)
X = transfer.transform(data)
# 简化写法
X = transfer.fit_transform(data)
Q: 如何解读词频矩阵?
A: 词频矩阵:
- 每行代表一条评论
- 每列代表一个词
- 值表示该词在评论中出现的次数
例如第一条评论[0, 0, 0, 0, 0, 1, 0, ...]表示第6个词(入门)出现1次,其他词为0。
7 本课小结
- 特征:词频矩阵(fit_transform)。
- 标签:1好评,0差评。
- 划分:前10训练,后3测试。
- 训练:MultinomialNB。
- 预测:predict。
- 评估:accuracy_score或score。
8 延伸思考与实践
- 实践:运行完整的情感分析代码。
- 预习:聚类算法简介。
- 思考:如何提高情感分析的准确率?