🧠 第六章 自然语言处理
📄 一句话概括

16 个情感词、5 个否定词、5 个程度词,12 句测试。 裸词典只对 8 / 12(0.667),加上否定翻转和程度放大后 12 / 12。 翻错的那四句,全靠「不」「没」和「有点」「非常」救回来。

📝 本节和前面几节的关系

上一节把语料洗干净了。这一节用最朴素的办法做第一个真实任务:判断一句话是夸还是骂。

一、最朴素的做法:数情感词

给每个情感词一个分值,正面为正、负面为负,句子里出现哪个就加哪个。最后看总分符号。 这个方法的全部参数就是 16 个分值。 它不训练、不占显存、结果可解释——用户问「为什么判成负面」,你能直接指出来是哪两个字扣的分。 Demo 里裸词典只对 8 / 12。翻错的四句是:这款软件不难用、界面不卡、不怎么推荐、效果没那么好。 四句全栽在同一件事上:否定。

二、否定翻转:往前看三个字

规则很简单:情感词前面三个字里出现「不、没、无、别、未」,就把这个词的分值取反。 「不难用」:难用是 -0.9,前面有「不」,翻成 +0.9,判正。对。 「不怎么推荐」:推荐是 +0.9,往前三字是「不怎么」,命中「不」,翻成 -0.9,判负。对。 「效果没那么好」:好是 +1.0,往前三字是「没那么」,命中「没」,翻成 -1.0,判负。对。 窗口取三个字是我拍的。 取太短会漏(「没有想象中那么好」够不着),取太长会误伤(「不但好而且便宜」里的「不」不该翻)。

三、程度副词:放大还是缩小

「非常满意」比「满意」重,「有点失望」比「失望」轻。 这个差别用乘数表达:非常 1.8 倍、很 1.5 倍、太 1.6 倍、有点 0.6 倍、稍微 0.5 倍。 Demo 里「有点失望」从 -0.90 变成 -0.54,「非常糟糕」从 -1.20 变成 -2.16。 注意程度调整不影响符号,只影响幅度。 所以对「判正负」这个任务,它其实是多余的——真正起作用的是否定翻转。 那为什么还要加?因为实际系统经常要输出强度,不只输出正负。排序、预警、打分都要用到幅度。

四、这套方法的三个硬伤

  1. 反讽完全无效。「这个价格真是便宜得让人心疼」会被判成正面。
  2. 转折句只看后半段才准。 「东西不错,但是太贵了」里两个词都算了分,总分可能落到中性附近,而人的判断是负面。
  3. 领域词不认识。「这手机发热控制得很克制」——「克制」不在表里,整句得 0 分。 这三条决定了词典法只能做第一版。 它的价值在于快、能解释、能立刻上线,然后拿它的输出当标注起点,去训练一个模型。 这个顺序很重要:先用规则跑起来收集数据,再用数据训练模型,而不是等标注完再动手。

五、动手 Demo:情感打分:裸词典与加否定、加程度两版对照

建 16 个情感词的分值表、5 个否定词、5 个程度词; 对 12 句人工标好正负的句子跑两遍——一遍只数情感词,一遍加否定翻转和程度放大; 逐句打出两种分数与判断,最后算两个版本的准确率。

for w, v in DICT.items():
    p = s.find(w)
    while p >= 0:
        x = v
        if any(n in s[max(0, p - 3):p] for n in NEG):
            x = -x                       # 否定翻转
        sc += x
        p = s.find(w, p + 1)

实跑输出:

--------------------------------------------------------------------
情感分析:裸词典、加否定与程度词
--------------------------------------------------------------------
  情感词                   16 个(正 8 / 负 8)
  否定词                   5 个
  程度词                   5 个
  句子              裸分   裸判   改进分   改进判   人工
  -----------------------------------------------------
  这个课程很好     +1.00     正   +1.50        正   正
  这家店服务很差   -1.00     负   -1.50        负   负
  我很喜欢这本书   +1.00     正   +1.50        正   正
  这款软件不难用   -0.90     负   +0.90        正   正
  界面不卡         -0.60     负   +0.60        正   正
  非常满意         +0.80     正   +1.44        正   正
  有点失望         -0.90     负   -0.54        负   负
  非常糟糕         -1.20     负   -2.16        负   负
  速度挺快         +0.50     正   +0.50        正   正
  画质模糊         -0.70     负   -0.70        负   负
  不怎么推荐       +0.90     正   -0.90        负   负
  效果没那么好     +1.00     正   -1.00        负   负

  裸词典                   8 / 12 = 0.667
  加否定与程度             12 / 12 = 1.000
  分数只看符号:正数判正面,负数判负面。分数本身不是概率,别当置信度用。

两张分数列一对比,能看出否定翻转改的正是符号:不难用从 -0.90 翻到 +0.90, 不怎么推荐从 +0.90 翻到 -0.90。 「速度挺快」两版都是 +0.50——「挺」不在程度词表里,所以没被放大。 漏一个程度词不影响符号,只影响幅度。 「有点失望」-0.54 仍然是负的,判断没错。程度词在这里没起决定作用,起作用的是「失望」本身。 这 12 句是我挑的,专挑否定和程度能翻盘的句子。 所以 8/12 变 12/12 的提升幅度不能外推到真实语料——真实语料里反讽、转折、领域词才是大头。

30 秒实验

  1. 把否定窗口从 3 改成 1 和 5,看哪几句判断变了。
  2. 加一句「东西不错,但是太贵了」,看总分落在哪、判成什么。
  3. 想一想:为什么反讽用词典法一定失败?

常见误区

  1. 「数情感词就够了」——否定、程度、转折一个都没处理。
  2. 「程度词能提高准确率」——它只改幅度,不改符号。
  3. 「词典法过时了」——它是拿标注数据之前最好用的过渡方案。
自测三问(点开对答案) 1. 否定翻转的窗口为什么要取三个字? —— 太短够不着(没那么好),太长会误伤(不但好而且便宜)。 2. 程度副词对「判正负」这个任务有用吗? —— 基本没用,它只改幅度不改符号;但对输出强度有用。 3. 词典法的三个硬伤是什么? —— 反讽无效、转折句算不准、领域词不认识。

会判情感了,下一节往前走一步:让机器接住用户的问题。

相关笔记