一串数字,就是一堆数字?
给数字装上“坐标”,AI 开始“看懂”世界
温度·甜度坐标 | 词向量 | 余弦相似度
向量系列 · 一串数字 = 向量
📦 3 Parts + Conclusion
👉 滑动
PART 01
给数字装坐标
从这是啥到它像啥
PART 02
位置近意思像
词向量怎么学出来
PART 03
量一下距离
相似度这把尺子
PART ///
写在最后
向量即视神经
上一篇,我们给 AI 装上了一层“视网膜”:文字、图片、声音,统统被翻译成了 0 和 1。
但问题来了。AI 手里现在是一堆数字,可它不知道这些数字是什么意思。“20320”和“22909”,哪个跟“你好”有关?一串孤零零的数字,本身什么都不表示。
要让 AI 从“看见”进化到“看懂”,中间还差一层,叫视神经。这层视神经,就是今天的主角:向量。
01
PART
给数字装上“坐标”
FROM WHAT TO HOW ALIKE
先抛一个问题:假设 AI 收到了两串数字,[8, 9] 和 [7, 8]。
它凭什么知道这两串数字“是一伙的”?光看数字本身,是看不出来的。数字和数字之间,哪来的“接近”?
除非,你给数字装上“坐标”。
我们做个思想实验。假设世界上有一套“饮品坐标”,横轴是温度,纵轴是甜度:
冰美式:冰、不甜 → [1, 2];冰拿铁:冰、微甜 → [2, 3];热牛奶:热、微甜 → [9, 4]。

饮品坐标:位置近,就相似
把它们画到图上就一目了然:冰美式和冰拿铁挨得很近,都是“又冰又不怎么甜”的咖啡;热牛奶蹲在另一个角落,又热又带奶味,和咖啡系不搭边。
位置近,就相似。数字还是那几个数字,可一旦规定了“每个数字代表什么”,它们就“站”出了含义。这就是坐标的意义。
我们把这种“一串有坐标意义的数字”起个名字,叫向量(Vector)。通俗地说:向量 = 一串有特定含义的数字。虽然 AI 脑子里的“坐标轴”可能多到我们无法命名,但只要这串数字在空间里的位置离得近,它们的意思就相近。
当然,两个维度远远不够。真实的 AI 世界里,描述一个饮品的词要用很多维度:温度、甜度之外,还有苦度、酸度、气泡感……维度越多,能区分的细节就越多。AI 就是这么干的。Transformer 原始论文里,每个词用 512 维的向量表示;BERT 升级到 768 维;到了 GPT-3,直接干到 12288 维,每个词都是一根一万两千多个数字组成的长向量。
维度越高,能容纳的“关系”就越多。就像我们在交友软件上找人,如果只看“性别”和“年龄”,只能筛选出同龄异性,这太粗糙了;如果加上“爱好”、“收入”、“性格”、“星座”等成千上百个维度,系统就能精确匹配出和你灵魂高度契合的那个人。
💡 一句话记住:数字只是原料,坐标让数字“站”出含义
02
PART
位置越近,意思越像
WORD VECTORS
刚刚的例子只有两个轴:温度、甜度。但上文说了,一个词有成百上千个维度,让人一个个想出来,头都要秃了。所以词向量,根本不是人设计的。
它是 AI 自己,从海量的文章里“学”出来的。它读了无数句“一杯冰美式”“一杯冰拿铁”,发现这俩总出现在同一个点单场景里,于是给它们分到了坐标空间里很近的两个点。
没有人告诉它“冰美式和冰拿铁挨得近”,它是自己“看”出来的。这也是词向量最神奇的地方。
那这个坐标空间长什么样?每个词是一个几百维的向量,人眼看不见,但可以算。
为了证明这一点,我们直接用一个开源中文模型 bge-large-zh-v1.5 来演示一下。下面这段代码,会真实跑出「冰美式 / 冰拿铁 / 热牛奶」三个词的向量,并计算它们两两之间的余弦相似度。结果越接近 1,说明它们在坐标空间里挨得越近。
import numpy as np
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-large-zh-v1.5")
words = ["冰美式", "冰拿铁", "热牛奶"]
vecs = {w: model.encode(w) for w in words}
def cos(a, b):
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
print("向量维度:", len(vecs["冰美式"]))
print("冰美式 vs 冰拿铁:", round(cos(vecs["冰美式"], vecs["冰拿铁"]), 4))
print("冰拿铁 vs 热牛奶:", round(cos(vecs["冰拿铁"], vecs["热牛奶"]), 4))
print("冰美式 vs 热牛奶:", round(cos(vecs["冰美式"], vecs["热牛奶"]), 4))
我跑了一遍,真实输出是这样的:
向量维度: 1024
冰美式 vs 冰拿铁: 0.6117
冰拿铁 vs 热牛奶: 0.4979
冰美式 vs 热牛奶: 0.3714
结果一目了然!“冰美式”和“冰拿铁”的相似度是 0.6117,最接近 1,而“冰美式”和“热牛奶”只有 0.3714,最低。这就说明:含义相近的词,向量距离就近。AI 不再是只存数字,而是知道哪些词是一伙的。
💡 一句话记住:向量里的每个数字是 AI 画下的坐标
03
PART
两个向量有多像?量一下距离
COSINE SIMILARITY
现在我们手里有了一堆向量。“冰美式”和“冰拿铁”很近,“冰美式”和“热牛奶”很远。可问题是,“很近”是多近?总不能光靠“感觉”吧。
这里要用到一把尺子,也就是我们前面提过的余弦相似度(Cosine Similarity)。
名字听着吓人,道理特别朴素。把两个向量看成两条从原点射出的“箭头”,它们之间有一个夹角。夹角越小,两个向量方向越一致,越像;夹角越大,方向越不一样,越不像。余弦相似度,就是把这个夹角变成一个数字。越接近 1 越像,越接近 0 越不像。
还记得饮品坐标吗?冰美式 [1, 2] 和冰拿铁 [2, 3] 指向几乎同一个方向,夹角小,相似度接近 1;冰美式和热牛奶 [9, 4] 方向明显不同,夹角大,相似度就低。

夹角小 = 相似,夹角大 = 不相似
这个“夹角”,用公式一算就出来。公式长这样:
余弦相似度 = (a₁b₁ + a₂b₂) ÷ (√(a₁²+a₂²) × √(b₁²+b₂²))
说人话就是:先把两个向量的对应位相乘、加在一起(分子),再除以两个向量各自的“长度”相乘(分母)。比如冰美式 [1, 2] 和冰拿铁 [2, 3]:分子 = 1×2 + 2×3 = 8,分母 = √(1+4) × √(4+9),一除就出来一个数。公式看着唬人,其实每一步都是小学算术。
现在用二维的饮品向量亲手算一遍,看结果和上面的示意图是不是一致:
import math
冰美式 = [1, 2]
冰拿铁 = [2, 3]
热牛奶 = [9, 4]
def cos(a, b):
dot = sum(x * y for x, y in zip(a, b))
na = math.sqrt(sum(x * x for x in a))
nb = math.sqrt(sum(y * y for y in b))
return dot / (na * nb)
print("冰美式 vs 冰拿铁:", round(cos(冰美式, 冰拿铁), 4))
print("冰美式 vs 热牛奶:", round(cos(冰美式, 热牛奶), 4))
冰美式 vs 冰拿铁: 0.9923
冰美式 vs 热牛奶: 0.7719
结果和示意图完全对得上:冰美式和冰拿铁夹角小,相似度接近 1;冰美式和热牛奶夹角大,相似度明显低。“像不像”终于可以用一个数字说话了。
有了这把“尺子”,AI 能干什么?搜东西:你说“冰咖啡”,它能找出“冰美式”;找同类:它能从一堆词里,自动把“冰美式、冰拿铁、美式”圈到一起;去重、聚类、推荐……背后全是这把尺子。
💡 一句话记住:向量之间能量出“距离”
///
LAST
写在最后:向量 = AI 的“视神经”
FROM RETINA TO OPTIC NERVE
来,把这几步连起来看:
万物 → 0 和 1(视网膜,上一篇)
↓
0 和 1 → 向量坐标(视神经,这一篇)
↓
向量之间 → 能测"像不像"(看懂含义)
第 1 篇,AI 有了“视网膜”:万物变成数字。这一篇,AI 有了“视神经”:数字变成坐标,坐标带来距离,距离带来“含义”。
它第一次“看懂”了:冰美式和冰拿铁是一伙的,冰美式和热牛奶不是。虽然 AI 还是说不出“冰美式是苦的”这种话,但它已经知道谁和谁“更熟”。理解世界,就是这么开始的。
但别急,故事还没完。单看一个向量,只是张“静态的坐标卡”。向量真正的威力,藏在运算里。向量之间还能相加、相减、相乘:加法、数乘让向量“动”起来;点积能算出更精确的“像不像”;矩阵让一堆向量排好队,变成一台“信息加工机”。
下一层,就是向量的运算与矩阵。让 AI 从“看懂”进化到“会算”。我们下篇见 🐼
既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。
THANKS FOR READING
夜雨聆风