人工智能之语言领域
第六章 情感分析
文章目录
- 人工智能之语言领域
- [前言 情感分析](#前言 情感分析)
- [6.1 情感分析概述](#6.1 情感分析概述)
- [6.1.1 情感分析的层级](#6.1.1 情感分析的层级)
- [6.1.2 核心任务类型](#6.1.2 核心任务类型)
- [6.2 情感分析的关键技术](#6.2 情感分析的关键技术)
- [6.2.1 情感词典的构建与应用](#6.2.1 情感词典的构建与应用)
- [6.2.2 上下文情感消歧](#6.2.2 上下文情感消歧)
- [6.2.3 否定词与程度副词的处理](#6.2.3 否定词与程度副词的处理)
- [6.3 主流模型在情感分析中的应用](#6.3 主流模型在情感分析中的应用)
- [6.3.1 传统模型与深度学习模型对比](#6.3.1 传统模型与深度学习模型对比)
- [6.3.2 预训练模型在情感分析中的微调策略](#6.3.2 预训练模型在情感分析中的微调策略)
- [6.4 实战案例:社交媒体舆情情感分析与可视化](#6.4 实战案例:社交媒体舆情情感分析与可视化)
- 补充:情感分析挑战与前沿方向
- 小结
- 资料关注
前言 情感分析
情感分析(Sentiment Analysis),又称意见挖掘(Opinion Mining),旨在自动识别和提取文本中表达的主观情感、态度或情绪。从用户评论到社交媒体,从产品反馈到政治舆情,情感分析已成为企业决策、品牌监控和人机交互的关键技术。本章将深入介绍情感分析的层级结构、核心技术、主流模型,并通过社交媒体舆情实战案例完整演示分析与可视化流程。
6.1 情感分析概述
6.1.1 情感分析的层级
情感分析可从细粒度到粗粒度分为三个层级:
| 层级 | 目标 | 示例 |
|---|---|---|
| 词级(Word-level) | 判断单个词的情感倾向 | "好" → 正面;"差" → 负面 |
| 句级(Sentence-level) | 判断整个句子的情感极性 | "这部电影太棒了!" → 正面 |
| 篇章级(Document-level) | 判断整篇文档的总体情感 | 一篇商品评论整体是好评还是差评 |
原始文本
词级情感
句级情感
篇章级情感
'烂' → 负面
'虽然贵但质量好' → 正面
整篇影评 → 正面
💡 实际应用中,句级和篇章级最常用;词级主要用于构建情感词典或辅助分析。
6.1.2 核心任务类型
| 任务 | 说明 | 输出形式 |
|---|---|---|
| 情感极性判断 | 判断正面/负面/中性 | 三分类标签 |
| 情感强度分析 | 量化情感强烈程度 | 分数(如 -1.0 ~ +1.0) |
| 情绪分类(Emotion Detection) | 识别具体情绪类别 | 如喜、怒、哀、惧、惊讶、厌恶(Ekman 六情绪) |
🌰 示例:
- 极性:"服务很差" → 负面
- 强度:"服务极其差" → 强度得分 -0.9
- 情绪:"我气死了!" → 情绪 = "愤怒"
6.2 情感分析的关键技术
6.2.1 情感词典的构建与应用
情感词典(Sentiment Lexicon) 是包含词语及其情感极性/强度的资源库。
常见中文情感词典:
- BosonNLP 情感词典:带强度分数(-1.0 ~ +1.0)
- 知网 HowNet 情感词集
- 台湾大学 NTUSD 情感词典
- 自建词典:通过众包或远程监督构建
应用方式(基于规则):
- 分词
- 匹配情感词
- 加权求和(考虑否定、程度副词)
python
# 示例:使用 BosonNLP 词典进行简单情感打分
# 下载地址:https://github.com/bosonnlp/sentiment/blob/master/SentimentDict.txt
def load_boson_dict(path):
sentiment_dict = {}
with open(path, 'r', encoding='utf-8') as f:
for line in f:
if line.strip():
word, score = line.strip().split()
sentiment_dict[word] = float(score)
return sentiment_dict
# 简化版情感打分(忽略否定和程度)
def simple_sentiment_score(text, sentiment_dict, tokenizer):
words = tokenizer(text)
score = sum(sentiment_dict.get(w, 0) for w in words)
return 1 if score > 0 else (0 if score < 0 else 0.5) # 1:正, 0:负, 0.5:中性
# 使用 jieba 分词
import jieba
boson_dict = load_boson_dict("SentimentDict.txt")
text = "这个手机非常好用"
score = simple_sentiment_score(text, boson_dict, lambda x: jieba.lcut(x))
print("情感得分:", score) # 1
⚠️ 缺陷:无法处理上下文(如"不好的好")、讽刺("这服务真是绝了")。
6.2.2 上下文情感消歧
同一词在不同上下文中情感可能不同:
- "高":价格高(负面) vs 质量高(正面)
- "杀":杀人(负面) vs 杀价(正面,对买家)
解决方案:
- 使用上下文感知模型(如 BERT)替代静态词典
- 引入依存句法分析,定位情感修饰对象
价格太高了
依存分析
高 --nsubj--> 价格
情感: 负面
质量非常高
依存分析
高 --nsubj--> 质量
情感: 正面
✅ 现代 NLP 模型(如 BERT)天然具备上下文消歧能力。
6.2.3 否定词与程度副词的处理
否定词(如"不"、"没"、"无")会反转情感极性:
"好" → 正面;"不好" → 负面
程度副词(如"非常"、"有点"、"极其")调节情感强度:
"好" → +0.5;"非常好" → +0.8
规则系统处理策略:
- 定义否定词表、程度副词表及权重
- 扫描句子,动态调整情感值
python
# 简化规则示例
negation_words = {"不", "没", "无", "非"}
intensifiers = {"非常": 1.5, "极其": 2.0, "有点": 0.5, "稍微": 0.7}
def rule_based_sentiment(text, sentiment_dict):
words = jieba.lcut(text)
total_score = 0
negate = False
intensify = 1.0
for w in words:
if w in negation_words:
negate = not negate # 支持多重否定
elif w in intensifiers:
intensify = intensifiers[w]
elif w in sentiment_dict:
score = sentiment_dict[w]
if negate:
score = -score
total_score += score * intensify
# 重置状态(简化)
negate = False
intensify = 1.0
return total_score
🔍 工业级系统(如百度情感分析 API)通常结合规则 + 深度学习。
6.3 主流模型在情感分析中的应用
6.3.1 传统模型与深度学习模型对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 情感词典 + 规则 | 可解释、无需训练数据 | 难以覆盖复杂语言现象 | 快速原型、领域词典丰富 |
| TF-IDF + LR/SVM | 训练快、效果稳定 | 忽略语序和上下文 | 中小数据集、基线模型 |
| LSTM/CNN | 自动学习特征、捕捉序列 | 需大量数据、训练慢 | 自有标注数据、追求性能 |
| BERT 等预训练模型 | SOTA 性能、上下文感知 | 计算资源要求高 | 高精度需求、有 GPU |
📊 实验表明:在中文情感分析任务上,BERT 微调通常比传统方法高 5--10% 的 F1 值。
6.3.2 预训练模型在情感分析中的微调策略
以 BERT 为例的标准微调流程:
输入文本
BERT Tokenizer
BERT Encoder
CLS 向量
Dropout
全连接层 768→3
Softmax → 情感标签
关键实践技巧:
- 学习率 :
2e-5~5e-5(不宜过大) - Batch Size:16--32(显存允许下越大越好)
- Early Stopping:防止过拟合
- 类别平衡 :若数据不平衡,使用
class_weight或 Focal Loss
python
# 使用 transformers 微调 BERT 进行情感三分类
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset
import numpy as np
# 加载中文情感数据集(如 ChnSentiCorp 扩展为三分类)
dataset = load_dataset("seamew/ChnSentiCorp") # 二分类,可自行构造中性样本
tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")
model = AutoModelForSequenceClassification.from_pretrained(
"hfl/chinese-roberta-wwm-ext",
num_labels=3 # 正面/中性/负面
)
def tokenize_function(examples):
return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=128)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
training_args = TrainingArguments(
output_dir="./sentiment-model",
evaluation_strategy="epoch",
save_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=64,
num_train_epochs=3,
weight_decay=0.01,
load_best_model_at_end=True,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["test"],
)
trainer.train()
🌐 中文推荐模型:
bert-base-chinesehfl/chinese-roberta-wwm-ext(哈工大 & 讯飞,中文优化)Langboat/mengzi-bert-base-fin(金融领域)
6.4 实战案例:社交媒体舆情情感分析与可视化
任务目标
- 从微博/推特等平台采集关于某品牌(如"iPhone")的评论
- 分析情感分布(正面/负面/中性)
- 可视化情感趋势与关键词云
完整实现步骤
Step 1: 模拟数据(实际可用爬虫或 API 获取)
python
# 模拟微博评论数据
comments = [
"iPhone15 太贵了,不值得买",
"拍照效果超棒,爱了爱了!",
"电池续航一般,但系统流畅",
"客服态度很差,再也不买了",
"性价比还行吧,中规中矩"
]
labels = [0, 1, 2, 0, 2] # 0:负面, 1:正面, 2:中性
Step 2: 加载微调好的情感模型(或使用在线 API)
python
# 使用 pipeline 快速预测
from transformers import pipeline
classifier = pipeline(
"sentiment-analysis",
model="uer/roberta-base-finetuned-chinanews-chinese", # 中文情感模型
tokenizer="uer/roberta-base-finetuned-chinanews-chinese",
return_all_scores=True
)
results = classifier(comments)
for comment, res in zip(comments, results):
print(f"评论: {comment}")
for r in res:
print(f" {r['label']}: {r['score']:.3f}")
print()
💡 若需三分类,可微调自己的模型或使用多标签策略。
Step 3: 可视化情感分布
python
import matplotlib.pyplot as plt
from collections import Counter
# 假设已获得预测标签 pred_labels
pred_labels = [0, 1, 2, 0, 2] # 示例
label_map = {0: '负面', 1: '正面', 2: '中性'}
counts = Counter(pred_labels)
labels = [label_map[k] for k in counts.keys()]
sizes = list(counts.values())
plt.figure(figsize=(8, 6))
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140, colors=['red','green','gray'])
plt.title("iPhone 微博评论情感分布")
plt.show()
Step 4: 生成情感关键词云(按情感分组)
python
from wordcloud import WordCloud
import jieba
# 按情感分组文本
positive_text = " ".join([c for c, l in zip(comments, pred_labels) if l == 1])
negative_text = " ".join([c for c, l in zip(comments, pred_labels) if l == 0])
# 中文分词
pos_words = " ".join(jieba.lcut(positive_text))
neg_words = " ".join(jieba.lcut(negative_text))
# 生成词云
wc_pos = WordCloud(font_path="simhei.ttf", background_color="white").generate(pos_words)
wc_neg = WordCloud(font_path="simhei.ttf", background_color="white").generate(neg_words)
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.imshow(wc_pos, interpolation='bilinear')
plt.title("正面评论关键词")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.imshow(wc_neg, interpolation='bilinear')
plt.title("负面评论关键词")
plt.axis("off")
plt.show()
📝 注意:需安装中文字体(如
simhei.ttf)以支持中文显示。
补充:情感分析挑战与前沿方向
| 挑战 | 解决方案 |
|---|---|
| 讽刺/反语 | 引入常识知识、多模态(表情符号、图片) |
| 领域迁移 | 领域自适应(Domain Adaptation)、Prompt Tuning |
| 低资源语言 | 跨语言迁移(XLM-R)、少样本学习 |
| 多模态情感 | 融合文本+图像+语音(如视频评论分析) |
小结
情感分析作为 NLP 的经典任务,已从早期的词典规则发展为今天的深度学习驱动范式。尽管预训练模型(如 BERT)大幅提升了性能,但否定处理、上下文消歧、讽刺识别 等挑战依然存在。在实际应用中,应根据数据规模、领域特性、实时性要求选择合适技术栈------小项目可用规则+词典快速上线,大系统则推荐 BERT 微调以获得最佳效果。
未来,情感分析将与多模态理解 、因果推理 、可解释 AI 深度融合,迈向更智能、更人性化的文本理解。
资料关注
咚咚王
《Python 编程:从入门到实践》
《利用 Python 进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第 3 版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow 机器学习实战指南》
《Sklearn 与 TensorFlow 机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python 深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习 +(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第 2 版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨 +&+ 张孜铭
《AIGC 原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战 AI 大模型》
《AI 3.0》