470_情感分析方法¶
一句话说明¶
情感分析(Sentiment Analysis)自动判断文本的情感倾向(正面/负面/中性),是应用最广的NLP任务之一,常用于评论挖掘、舆情监控。
核心知识点¶
- 粒度层次:
- 文档级:整篇文章情感
- 句子级:单句情感
- 方面级(ABSA):对"手机屏幕"好评、"电池"差评——更精细
- 情绪分类 vs 情感强度:二分类/多分类 vs 连续评分(1-5星)
- 方面级情感分析(ABSA):四元组(方面词、观点词、情感极性、类别)
经典模型/方法¶
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| VADER(词典规则) | 社交媒体英文 | 无需训练 | 域迁移差 |
| SnowNLP | 中文简单场景 | 轻量 | 精度有限 |
| BERT微调 | 通用情感分类 | 精度高 | 资源大 |
| ABSA-BERT | 方面级情感 | 细粒度 | 需标注方面 |
| LLM zero-shot | 无标注场景 | 无需训练数据 | 成本高 |
代码示例¶
# ---- 方案1:使用 transformers pipeline(最快验证)----
from transformers import pipeline
# 加载情感分析流水线(内置fine-tuned模型)
sentiment_pipe = pipeline(
"sentiment-analysis",
model="lxyuan/distilbert-base-multilingual-cased-sentiments-student",
# 支持中文的多语言情感模型
)
texts = [
"这款产品真的太好用了,强烈推荐!",
"服务态度差,等了半小时没人理",
"还行吧,一般般"
]
for text in texts:
result = sentiment_pipe(text)[0] # {'label': 'positive', 'score': 0.98}
print(f"{text[:15]}... → {result['label']} ({result['score']:.2f})")
# ---- 方案2:BERT微调(自定义数据集)----
from transformers import BertTokenizer, BertForSequenceClassification
import torch
import torch.nn.functional as F
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
model = BertForSequenceClassification.from_pretrained(
'bert-base-chinese',
num_labels=3 # 0=负面, 1=中性, 2=正面
)
def predict_sentiment(text, model, tokenizer):
"""预测单条文本情感"""
model.eval()
enc = tokenizer(text, return_tensors='pt',
max_length=128, truncation=True, padding='max_length')
with torch.no_grad():
logits = model(**enc).logits # (1, 3)
probs = F.softmax(logits, dim=-1) # 转成概率
pred = probs.argmax(dim=-1).item()
labels = {0: '负面', 1: '中性', 2: '正面'}
return labels[pred], probs[0][pred].item()
# ---- 方案3:方面级情感分析(ABSA)----
# 把方面词拼接到句子中,让模型判断该方面的情感
def absa_predict(sentence, aspect, model, tokenizer):
"""
方面级情感:将 sentence 和 aspect 拼接,
格式:[CLS] 方面词 [SEP] 句子 [SEP]
"""
# 以方面词作为"问题",原句作为"段落",类似QA格式
enc = tokenizer(
aspect, sentence, # (question, context) 格式
return_tensors='pt',
max_length=128,
truncation=True,
padding='max_length'
)
with torch.no_grad():
logits = model(**enc).logits
pred = logits.argmax(dim=-1).item()
return {0: '负面', 1: '中性', 2: '正面'}[pred]
# ---- 方案4:中文词典方法(快速基线)----
# pip install snownlp
from snownlp import SnowNLP
text = "这本书写得非常好,推荐给大家"
s = SnowNLP(text)
print(f"SnowNLP情感分数: {s.sentiments:.3f}") # 0~1,越大越正面
面试常问点¶
- 情感分析和方面级情感分析的区别?
- 普通:整句"这手机好用" → 正面
ABSA:"屏幕好看但电池差" → 屏幕=正,电池=负
如何处理隐式情感(没有明显情感词)?
- "这个宾馆连WiFi都没有"——没有情感词但明显负面
需要常识推理,LLM表现更好
跨域情感分析的挑战?
- 不同领域情感词权重不同("unpredictable"在影评正面,在金融负面)
方案:域自适应、对抗训练
VADER的工作原理?
- 基于情感词典+规则(否定词、强调词、标点增强)计算compound分数
速查表¶
| 场景 | 工具/模型 |
|---|---|
| 快速原型(中文) | SnowNLP |
| 快速原型(英文) | VADER / TextBlob |
| 高精度中文 | bert-base-chinese 微调 |
| 多语言 | xlm-roberta-base |
| 方面级ABSA | BERT-ATE + BERT-ASC |
| 零样本 | GPT-4 prompt |