跳转至

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,越大越正面

面试常问点

  1. 情感分析和方面级情感分析的区别?
  2. 普通:整句"这手机好用" → 正面
  3. ABSA:"屏幕好看但电池差" → 屏幕=正,电池=负

  4. 如何处理隐式情感(没有明显情感词)?

  5. "这个宾馆连WiFi都没有"——没有情感词但明显负面
  6. 需要常识推理,LLM表现更好

  7. 跨域情感分析的挑战?

  8. 不同领域情感词权重不同("unpredictable"在影评正面,在金融负面)
  9. 方案:域自适应、对抗训练

  10. VADER的工作原理?

  11. 基于情感词典+规则(否定词、强调词、标点增强)计算compound分数

速查表

场景工具/模型
快速原型(中文)SnowNLP
快速原型(英文)VADER / TextBlob
高精度中文bert-base-chinese 微调
多语言xlm-roberta-base
方面级ABSABERT-ATE + BERT-ASC
零样本GPT-4 prompt