word2vec 核心原理:滑动窗口、二分、负采样

#2025/12/28 #ai

目录

记忆口诀

滑动窗口找邻居 🔍  
正例负例出考题 ✅❌  
对比训练学语义 🧠  
相似的词靠一起 🤝  

这就是word2vec的全部秘密!是不是其实很简单?😊

1. 滑动窗口:找“邻居“

类比:朋友圈

句子: "我 爱 吃 烤 鸭"  

滑动窗口 = 你只关注你周围的朋友

窗口大大=2,看"吃"这个词:  

    我  爱  [吃]  烤  鸭  
    ←  ←   中心  →  →  
    
"吃"的邻居是:我、爱、烤、鸭  

核心思想:

  • 经常一起出现的词 = 关系密切
  • 就像你经常和闺蜜一起出现 → 说明你们关系好

2. 二分类任务:训练一个“真假识别器“

类比:考试判断题

给模型出判断题:这两个词是邻居吗?

# 题目1:  
词1: "吃" 
词2: "烤"  
答案: ✅ 对(它们确实相邻)  

# 题目2:  
词1: "吃"  词2: "电脑"  
答案: ❌ 错(它们不相邻)  

为什么要这样训练?

假设只给正确答案:

模型:反正你问什么我都说"是邻居"就能拿满分 😏  

这就是“作弊“!所以必须加入错误答案:

正例(相邻的):吃-烤、 吃 - 鸭、爱-吃  
负例(不相邻的):吃-电脑、吃-飞机、爱-宇宙  

3. 负采样:随机找“错误答案“

类比:考试出错题

问题:从哪里找错误答案(负例)?

答案:随机抽!

词表 = ["我", "爱", "吃", "烤", "鸭",  "电脑", "飞机", "宇宙", ...]  

# 正例  
("吃", "烤") → 标签=1  

# 负例(随机抽5个词)  
("吃", "电脑") → 标签=0  
("吃", "宇宙") → 标签=0  
("吃", "飞机") → 标签=0  

为什么随机就可以?

因为词表很大(几万个词),随机抽到的词:

  • 99.9%的概率和“吃“不是邻居
  • 偶尔抽到“烤“也没关系,少量噪音不影响训练

完整流程示例

句子: "我 爱 吃 烤 鸭"  

# 步骤1:滑动窗口(窗口=2)  
中心词: "吃"  
邻居: ["我", "爱", "烤", "鸭"]  

# 步骤2:生成训练样本  
正例(相邻的):  
  ("吃", "我")   → 1  
  ("吃", "爱")   → 1  
  ("吃", "烤")   → 1  
  ("吃", "鸭")   → 1  

负例(随机抽的):  
  ("吃", "电脑") → 0  
  ("吃", "月亮") → 0  
  ("吃", "跑步") → 0  

# 步骤3:训练神经网络  
输入: ("吃", "烤")  
模型预测: 0.92 (很可能是邻居)  
正确答案: 1  
误差: 0.08  
→ 调整"吃"和"烤"的向量,让它们更接近  

为什么这样训练有用?

魔法时刻:

训练前(随机初始化):

"国王" = [0.12, -0.45, 0.89]   
"女王" = [-0.67, 0.23, -0.11]   
# 完全不相关  

训练后(学到了语义):

"国王" = [0.52, 0.83, 0.21]  
"女王" = [0.48, 0.79, 0.25]  
# 向量很接近!✅  

因为:

  • “国王“的邻居:王子、皇室、城堡…
  • “女王“的邻居:王子、皇室、城堡…
  • 它们的邻居重叠很多向量自动变接近

一句话总结

word2vec = 做大量判断题(这两个词是不是邻居),通过“对“和“错“的对比,让模型学会:经常一起出现的词,向量要接近

三要素:

  1. 🔍 滑动窗口:
    • 找邻居(谁和谁经常一起出现)
  2. ✅❌ 二分类:
    • 出判断题(是邻居=1,不是=0)
  3. 🎲 负采样:
    • 随机抽词当错误答案(省时间)

实际代码感受

# 想象你在训练模型  
for 句子 in 维基百科:  
    for 词 in 句子:  
        # 找邻居(滑动窗口)  
        邻居们 = 获取周围2个词(词)  
        
        # 正例(真实邻居)  
        for 邻居 in 邻居们:  
            训练(词, 邻居, 标签=1)  # 是邻居  
        
        # 负例(随机抽5个)  
        for _ in range(5):  
            随机词 = random.choice(词表)  
            训练(词, 随机词, 标签=0)  # 不是邻居