词向量
为什么「国王 − 男人 + 女人 ≈ 女王」?词的含义如何变成坐标?
符号的盲点:猫和小猫是陌生人
上一课的 N-gram 学到了一件事:「猫 → 出门」在历史数据里出现过 800 次。 但现在有人写了「小猫」。N-gram 怎么处理「小猫」?
它查遍整张频率表,发现「小猫 → 出门」只出现过 3 次——样本太少,完全没把握。 它不知道「猫」和「小猫」是同一种动物, 因为在它眼里,「猫」和「小猫」是两个不同的字符串,就像「苹果」和「梨子」一样没有关联。
这个问题的根源是:N-gram 用「符号」代表词,符号之间没有任何距离或相似度。 要解决这个问题,词必须有「意思」—— 不是用字典定义来描述,而是用数字来表示, 让「猫」和「小猫」的数字表示很接近,「猫」和「飞机」的数字表示很远。
道理说通了,可「用数字表示意思」到底怎么落地?先别急着上理论——我们自己动手试一把,说不定就能撞出办法来。
先动手:自己给词的意思「打分」
要把「意思」变成数字,最朴素的念头是:挑几个语义属性当「维度」,给每个词在每个属性上打个分(0~1)。先试最简单的两个维度——维度① 动物性(像不像活物)和维度② 体型大小,把手里这几个词都摆进去:
一打分,问题就化开了:「猫」(0.86, 0.27)、「小猫」(0.90, 0.13)、「狗」(0.80, 0.32) 全挤在「小动物」那一角、彼此挨得很近; 而「飞机」(0.03, 0.95) 远在另一头。用第 2 课的距离 / 夹角一量,「猫」和「小猫」就天然地相似了。 每个词,现在都成了平面上的一个点(两个数)。
可你也看出来了:「猫」和「狗」几乎落在同一个点上——这两个维度分不开它们。 想区分,就得再添维度:「忠诚 vs 警觉」「会不会抓老鼠」「常见宠物程度」…… 而加到三维、五维,仍搞不定「自由 vs 民主」「悲伤 vs 忧郁」这类抽象词之间的细微差别。一个词的意思,牵涉成百上千种说不清却真实存在的属性。
所以真实的自然语言处理里,维度取得非常多——常见 128、300、768,甚至上千维。 每一维都是一个「说不太清、但确实有用」的语义方向;维度越多,越能容下词与词之间那些细微差别。
把一个词表示成这样一串数字 (v₁, v₂, …, v_d),就是它的词向量(word embedding,也叫词嵌入)。 其中 d 是维度(维数),实际中常达几百上千。意思相近的词,词向量在这个 d 维空间里挨得近;意思无关的词,离得远。
说穿了,它就是第 1 课的向量——只不过现在每个向量都背着一个词的「意思」, 第 2 课的点积与夹角,就成了量「两个词有多像」的尺子。
定义有了,可真正的麻烦也来了:几百维的数字、每个词都要填一串,靠人手工打分根本不可能, 而且「动物性该打 0.86 还是 0.88」全凭感觉、太主观。能不能让机器自己把这些数字学出来?——下一站揭晓。
让机器自己把这串数字学出来
上一站把目标定死了:给每个词配一串几百维的数字(词向量),意思相近的挨得近。可几百维手工填不现实—— 问题于是变成:怎么让机器自己学出这些数字?难点在于,机器既不懂「动物性」也不懂「体型」, 它凭什么知道该把哪些词放近、每一维又该填多少?
线索藏在语言学家的一句老话里:「一个词的意思,由它经常出现的场合决定。」(You shall know a word by the company it keeps.) 机器读不懂词义,但它能数上下文——看看「猫」和「小猫」都出现在什么样的句子里:
两个词的上下文几乎重合。这就给了机器一个不依赖人工、纯靠统计的判据:上下文越像的词,就该离得越近。可「上下文相似」要怎么落成「向量相近」?Word2Vec 用了一个很巧的训练游戏——遮词猜词。
先给词表里每个词随机发一串数字(随机初始化的词向量,一开始谁都不靠谱)。然后反复玩填空: 遮住句子里的一个词,让网络拿上下文词的向量去把它猜出来。比如:
→ 网络猜:「猫」0.3,「狗」0.4,「孩子」0.2,「朋友」0.1
真实答案是「猫」——「狗」的分数最高但猜错了,于是微调相关词的向量,让「猫」在这种上下文下的得分更高一点。 网络里每个词都对应一行数字(通常 128~1024 个),每错一次,被悄悄挪动的就是这行数字。
几十亿次填空之后,奇妙的事情发生了:那些总出现在相似上下文里的词(「猫」「小猫」「猫咪」), 为了都能在相似的句子里被猜出来,向量被一点点推到了相近的位置。这串自动学出来的数字,正是第 2 站定义的词向量—— 只不过它的每一维不再是「动物性」这种人能命名的属性,而是机器自己摸索出的、说不清却很好用的语义方向。
这套办法 2013 年由 Google 提出,就叫 Word2Vec。它第一次把「词的意思」彻底变成了可计算的数字, 也为后面所有语言模型铺好了地基。
一个意外的惊喜:向量运算有意义
Word2Vec 训练完之后,研究人员发现了一件让所有人兴奋的事:
这不是人为设计进去的,而是纯粹从大量文本里自然浮现出来的。 模型在训练过程中发现:「国王」出现的地方「女王」不出现,反过来也一样; 而「国王」和「男人」的关系,与「女王」和「女人」的关系在空间上是相同的方向和距离。
注意这里的「−」和「+」不是比喻——就是第 2 课的向量加减,逐个维度地减、逐个维度地加。 只不过现在每个向量都背着一个词的意思,于是一次普通的向量运算, 竟然在「语义」上也讲得通:减掉「男人」这个方向、再加上「女人」这个方向,落点恰好在「女王」附近。 学过的运算没变,变的是它作用的对象有了含义。
类似的关系还有很多:「北京−中国+法国 ≈ 巴黎」、「跑−跑步+游泳 ≈ 游」、 「快乐−快乐(名词)+悲伤 ≈ 悲伤」…… 词向量把语言的语义关系编码成了空间方向。
每个词只有一个向量。「我去银行取钱」和「我坐在河岸边」里的「银行」意思完全不同, 但词向量只能给「银行」一个固定的数字——它记住的是「银行」这个词的平均意思, 无法根据上下文动态调整。 要解决这个问题,需要每次都根据上下文重新计算词的表示——这就是注意力机制要做的事。
总结
词向量把每个词变成一行数字,让意思相近的词,数字也相近。 训练方式极其简单:遮住一个词,让网络猜,猜错了就微调。 副产品是词向量空间里出现了「国王−男人+女人≈女王」这样的语义方向。 局限:每个词只有一个固定向量,无法区分「银行(钱)」和「银行(河岸)」。
这一课你亲手推导了
- 为什么需要词向量:N-gram 把词当符号,「猫」和「小猫」无关;词向量让相似词的数字相近。
- 核心直觉:上下文相似的词,意思相近——「你可以通过一个词交的朋友来了解这个词」。
- 训练技巧:遮住词,猜上下文(或反过来),猜错了微调向量。
- 意外惊喜:向量运算有语义意义,国王−男人+女人≈女王。
- 局限:每词一个固定向量,无法处理一词多义。
学习小测验
做完这一课,来检测一下核心知识点。选出你的答案后点击「提交」,即可看到正确选项与讲解。
神经网络语言模型
有了词向量,现在「猫」和「小猫」的数字很接近——用神经网络预测下一个词,是否能举一反三?