🧠 一、共现矩阵(Co-occurrence Matrix)是什么?
一句话核心定义:
共现矩阵是一个统计"单词与单词一起出现次数"的二维表。
每个单词都用它和其他词共现的次数来表示成一个数值向量。
1️⃣ 为什么要这样做?
我们希望计算机"理解"单词的含义。
但计算机只认识数字,不懂"猫""狗"是什么意思。
于是我们用一个重要假设:
分布式假设(Distributional Hypothesis) :
"一个词的意义由它的上下文决定。"
例如:
- "猫"常与"喵、宠物、狗"一起出现
- "汽车"常与"驾驶、道路、汽油"一起出现
→ 因此,"猫""狗"语义相似,"猫""汽车"语义远。
要让计算机捕捉这种"共现模式",就统计所有词在上下文中共同出现的次数。
📊 二、共现矩阵长什么样?
假设语料:
"猫 喜欢 吃 鱼 。 狗 也 喜欢 吃 鱼。"
我们先提取词汇表:
| 编号 | 单词 |
|---|---|
| 0 | 猫 |
| 1 | 狗 |
| 2 | 喜欢 |
| 3 | 吃 |
| 4 | 鱼 |
| 5 | 也 |
假设"窗口大小 = 2",表示每个词的前后各看 2 个词。
然后我们统计:每个"中心词"与哪些"上下文词"同时出现过。
统计后得到的共现矩阵(举例)
| 中心词\上下文词 | 猫 | 狗 | 喜欢 | 吃 | 鱼 | 也 |
|---|---|---|---|---|---|---|
| 猫 | 0 | 0 | 1 | 1 | 0 | 0 |
| 狗 | 0 | 0 | 1 | 1 | 1 | 1 |
| 喜欢 | 1 | 1 | 0 | 2 | 2 | 1 |
| 吃 | 1 | 1 | 2 | 0 | 2 | 0 |
| 鱼 | 0 | 1 | 2 | 2 | 0 | 0 |
| 也 | 0 | 1 | 1 | 0 | 0 | 0 |
📈 三、如何用它"向量化"单词语义
每一行(或每一列)都可以看作一个单词的数值表示(向量)。
例如:
- "猫" → [0, 0, 1, 1, 0, 0]
- "狗" → [0, 0, 1, 1, 1, 1]
- "喜欢" → [1, 1, 0, 2, 2, 1]
这些向量记录了单词与其他词共现的模式。
如果两个词出现在相似的上下文里,它们的向量就会相似。
👉 这样我们就把语义关系转成了"几何距离"关系。
相似语义 → 向量方向接近
不同语义 → 向量方向远离
⚙️ 四、最基本的实现思路
以下是一个最朴素的算法(Python 伪代码):
python
from collections import defaultdict
def build_cooccurrence_matrix(corpus, window=2):
vocab = list(set(corpus)) # 词表
index = {w: i for i, w in enumerate(vocab)} # 词 -> 索引
matrix = [[0]*len(vocab) for _ in vocab] # 初始化矩阵
for i, word in enumerate(corpus):
start = max(0, i - window)
end = min(len(corpus), i + window + 1)
for j in range(start, end):
if i != j:
context_word = corpus[j]
matrix[index[word]][index[context_word]] += 1
return vocab, matrix
输入语料:
python
corpus = ["猫", "喜欢", "吃", "鱼", "狗", "也", "喜欢", "吃", "鱼"]
输出的矩阵即为共现矩阵。
🧩 五、总结
| 概念 | 内容 |
|---|---|
| 目的 | 把词变成数字向量,用于表达语义相似性 |
| 依据 | 分布式假设:"词的意义由上下文决定" |
| 矩阵含义 | 行列都是词,数值是共现次数 |
| 向量化方式 | 每一行即一个词向量 |
| 语义关系来源 | 相似上下文 → 向量相似 |
| 实现关键点 | 设窗口 → 遍历语料 → 统计共现次数 |
✅ 一句最简总结:
共现矩阵就是:
"记录每个词与其他词在相邻上下文中共同出现次数的表格",
每一行可视为一个"语义向量",
语义相似的词 → 向量相似。