第 八 章

情感分析

察言观色,辨其褒贬

一、情感分析的任务层级

情感分析(Sentiment Analysis)又称意见挖掘(Opinion Mining),旨在识别文本中蕴含的主观情绪与评价倾向。按分析粒度可分为:

粒度问题示例
篇章级整文褒还是贬?这篇电商评论总体为差评
句子级这句的情绪正负?「画质惊艳」为正向
方面级(ABSA)对哪个方面、是何评价?续航好评 / 拍照差评

此外还可按情感类别分为二元(褒/贬)、三元(褒/中/贬)与细粒度情绪(喜、怒、哀、惧、惊、恶)。典型应用:商品评论洞察、舆情监控、品牌口碑、金融舆情与智能客服的情绪安抚。

二、情感词典法

最直觉的方法:预先准备情感词典(褒义词表、贬义词表),统计文本中正负词的数量或强度,加权计分。中文常用词典有 知网 Hownet 情感词集、大连理工情感词汇本体、台湾大学 NTUSD。

但光数词远远不够,必须处理三个「反转器」:

  1. 否定词翻转极性:「不好」= 负向;「不是不喜欢」= 双重否定回正向。规则:情感词前窗口内每出现一个否定词(不、没、无、别、未……),极性乘 −1。
  2. 程度副词调整强度:「非常好」强于「好」,「有点差」弱于「差」。给程度词设权重(非常 1.5、有点 0.7)。
  3. 转折以分句为准:「虽然便宜,但是质量很差」——「但是」之后才是说话人真正的态度,可对转折后分句加权。
python · 情感词典法核心逻辑NEGATIONS = {"不", "没", "无", "别", "未"}
DEGREE = {"非常": 1.5, "特别": 1.5, "有点": 0.7}

def score_clause(clause, pos_words, neg_words):
    score = 0
    for i, w in enumerate(jieba.lcut(clause)):
        polarity = 1 if w in pos_words else (-1 if w in neg_words else 0)
        if polarity == 0:
            continue
        window = clause[max(0, i - 3):i]
        if any(neg in window for neg in NEGATIONS):
            polarity *= -1                       # 否定翻转
        for d, weight in DEGREE.items():
            if d in window:
                polarity *= weight               # 程度加权
        score += polarity
    return score

词典法无需训练数据、可解释、冷启动快;缺点是依赖词典覆盖,对反语(「真是太棒了,又晚点三小时」)、隐喻、领域词义(「这手机很烫手」)无能为力。

三、机器学习法

当手头有一批标注好褒贬的评论时,可把情感分析转化为文本分类问题:

文本 → 分词 → 特征向量化 → 分类器 → 褒/贬
                ↑ TF-IDF / n-gram / 情感词计数
                              ↑ 朴素贝叶斯 / SVM / 逻辑回归

朴素贝叶斯(Naive Bayes)是经典基线:它统计「某词在褒/贬评论中出现的条件概率」,依据贝叶斯公式判断整句类别,训练快、对短文本效果好。

python · sklearn 情感分类基线import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split

raw = [("手机流畅,拍照惊艳,非常满意", 1),
       ("续航很差,卡顿严重,后悔买了", 0),
       ("客服态度好,物流也快", 1),
       ("价格太贵,屏幕还有瑕疵", 0)]       # 实际需上万条

X = [" ".join(jieba.lcut(t)) for t, _ in raw]
y = [label for _, label in raw]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.25)

clf = Pipeline([
    ("tfidf", TfidfVectorizer(ngram_range=(1, 2))),
    ("nb", MultinomialNB())
])
clf.fit(X_train, y_train)
print(clf.score(X_test, y_test))
print(clf.predict([" ".join(jieba.lcut("画面精彩,值得推荐"))]))  # [1]

特征工程是传统方法的胜负手:TF-IDF unigram+bigram、情感词数量、否定词、标点(!!!)、表情符号都是有效特征。

四、深度学习法

  • Word2Vec + TextCNN / BiLSTM:词向量输入,卷积或循环网络自动提取情感特征,省去手工特征;
  • BERT 微调:句首加 <[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]> 标记接一个分类层,用几千到几万条标注评论微调即可,是当前中文情感分类的强基线;
  • 方面级 ABSA:序列标注 + 情感分类联合模型,输出「续航—正、拍照—负」这样的方面—情感对;
  • 大模型零样本:直接用提示词「请判断这条评论的情感倾向:褒/贬/中,并说明理由」,在无标注冷启动场景表现亮眼。
text · BERT 风格提示词(零样本)请判断以下电商评论的情感倾向(正向 / 负向 / 中性),
并指出涉及的方面:
「屏幕很清晰,但是电池不耐用,续航让人失望。」

输出:屏幕=正向;电池/续航=负向;整体=负向

五、工程流程与评估

  1. 数据准备:采集评论(第二章),清洗去广告,按评分弱标注或人工标注;
  2. 标注规范:明确「中性」边界(客观描述 vs 弱褒贬)、反语处理原则;
  3. 建模:词典法先行跑通,再上 TF-IDF+NB 基线,最后 BERT 精调;
  4. 评估:准确率 Accuracy、精确率/召回率/F1(关注贬类别漏报)、混淆矩阵;
  5. 上线迭代:收集 badcase 回流标注,定期重训;方面级结果接入 BI 看板。
类别不平衡是评论数据的常态(好评远多于差评)。可用过采样、class_weight 加权、F1 替代 Accuracy来避免模型「全都猜好评」。

六、交互演示:评论打分

下面的演示复刻了本章的情感词典法:分句 → 匹配正负情感词 → 检查前置否定词(极性翻转)与程度副词(强度加权)→ 汇总得分。可点击示例快速体验,也可自己改写句子验证规则:

情感分析台词典 + 否定 + 程度词

思考两个反例:「我难道不喜欢吗?」(反问)与「快递快得离谱,手机烫得吓人」(领域歧义)——它们正是规则法失效、需要机器学习与语义理解的地方。