面包屑图标 当前位置: 首页
AI资讯
热点详情

孙悟空加红楼梦减西游记一文搞懂向量嵌入

AI热点日报
AI热点日报时间:2026-06-28
热点解读

01 文字是怎么变成向量的 把文字变成向量的方法,最早火起来的是词向量,代表就是 word2vec 模型。思路很直白:先准备一张词汇表,给每个词随机分配一个向量,然后用海量语料训练,不断调整这些向量,让语义相近的词在空间里挨得更近。 具体怎么练?主要有两种玩法。CBOW(Continuous Bag

01.文字是怎么变成向量的

把文字变成向量的方法,最早火起来的是词向量,代表就是 word2vec 模型。思路很直白:先准备一张词汇表,给每个词随机分配一个向量,然后用海量语料训练,不断调整这些向量,让语义相近的词在空间里挨得更近。 具体怎么练?主要有两种玩法。CBOW(Continuous Bag-of-Words)是根据上下文来猜中间那个词是什么;Skip-Gram 则反过来,给你一个词,让你猜它周围的上下文。举个例子,对于“我爱吃冰淇淋”这句话,CBOW 的做法是:已知“我爱”和“冰淇淋”,推测中间那个词。模型可能会算出来,“吃”的概率是90%,“喝”是7%,“玩”是3%。然后根据猜对猜错,用损失函数和反向传播算法,去微调词向量的参数。就这么反复迭代,直到模型对词的理解越来越准。 这过程,其实跟教小孩说话很像。最初的词向量就像刚出生的婴儿,啥也不懂。父母在各种场景下跟孩子说话,时不时考一考:“肚子饿了就要……”孩子说“要吃饭”,答对了。如果答错,比如“吃饭之前要……”,孩子说“要喝汤”,父母就会纠正:“不对,吃饭之前要洗手。”这就是在调整“参数”——只不过教孩子调的是神经元突触,训练模型调的是网络权重。 光说不练假把式,咱们上代码实操一下。先装依赖:
pip install gensim scikit-learn transformers matplotlib
从 gensim 里导入 KeyedVectors 用来处理词向量:
from gensim.models import KeyedVectors
https://github.com/Embedding/Chinese-Word-Vectors/blob/master/README_zh.md 下载一个针对文学作品训练的中文词向量模型 Literature,然后加载它:
# 加载中文词向量模型
word_vectors = KeyedVectors.load_word2vec_format('sgns.literature.word', binary=False)
词向量模型,本质上就是一本词典。普通词典里每个词对应一条解释,这里每个词对应的是一个300维的向量。数字太多,咱们只瞅一眼前4个维度长什么样:
print(f"'孙悟空'的向量的前四个维度:{word_vectors['孙悟空'].tolist()[:4]}")
输出:
'孙悟空'的向量的前四个维度:[-0.09262000024318695, -0.034056998789310455, -0.16306699812412262, -0.05771299824118614]

02.
语义更近,距离更近

回到刚才的问题:“孙悟空”跟“猪八戒”更相关,还是跟“沙僧”更相关?用余弦相似度算一下就知道:
print(f"'孙悟空'和'猪八戒'向量的余弦相似度是:{word_vectors.similarity('孙悟空', '猪八戒'):.2f}")
print(f"'孙悟空'和'沙僧'向量的余弦相似度是:{word_vectors.similarity('孙悟空', '沙僧'):.2f}")
返回:
'孙悟空'和'猪八戒'向量的余弦相似度是:0.60
'孙悟空'和'沙僧'向量的余弦相似度是:0.59
果然,还是跟猪八戒更近一点。不过光比两个不过瘾,干脆看看跟“孙悟空”最相关的几个词是谁:
similar_words = word_vectors.most_similar("孙悟空", topn=4)
print(f"与'孙悟空'最相关的4个词分别是:")
for word, similarity in similar_words:
    print(f"{word}, 余弦相似度为:{similarity:.2f}")
返回:
与'孙悟空'最相关的4个词分别是:
悟空, 余弦相似度为:0.66
唐僧, 余弦相似度为:0.61
美猴王, 余弦相似度为:0.61
猪八戒, 余弦相似度为:0.60
“悟空”和“美猴王”是孙悟空自己,自然相关。为什么“唐僧”和“猪八戒”也挤进来了?这正说明了词向量训练的底层逻辑:在《西游记》的文本中,“唐僧”和“猪八戒”经常出现在“孙悟空”的上下文里——毕竟孙悟空天天救师父、戏耍八戒,语义关联就是这么来的。 既然模型的目标是让语义相近的词在向量空间里挨得近,那我们来考考它:下面几组词,它能不能自动识别出它们分别是一伙的? 第一组:西游记,三国演义,水浒传,红楼梦 第二组:西瓜,苹果,香蕉,梨 第三组:长江,黄河 先拿到它们的向量:
import numpy as np

words = ["西游记", "三国演义", "水浒传", "红楼梦", 
         "西瓜", "苹果", "香蕉", "梨", 
         "长江", "黄河"]
vectors = np.array([word_vectors[word] for word in words])
300维的向量没法直接看,得降维。用PCA(主成分分析)把它们压到2维,就像《三体》里的二向箔,来个降维打击:
from sklearn.decomposition import PCA

pca = PCA(n_components=2)
vectors_pca = pca.fit_transform(vectors)
然后画在平面上:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 1, figsize=(7, 7))
plt.rcParams['font.sans-serif'] = ['SimSong']
plt.rcParams['axes.unicode_minus'] = False

axes.scatter(vectors_pca[:, 0], vectors_pca[:, 1])
for i, word in enumerate(words):
    axes.annotate(word,
                  (vectors_pca[i, 0], vectors_pca[i, 1]),
                  xytext=(2, 2),
                  textcoords='offset points',
                  fontsize=10,
                  fontweight='bold')
axes.set_title('词向量', fontsize=14)
plt.tight_layout()
plt.show()
从图上可以清楚看到,同一组词在二维空间中的确扎堆在一起。 既然能投影到二维,那能不能投到三维?当然可以,而且更酷。你可以在 TensorFlow Embedding Projectorhttps://projector.tensorflow.org/ )上试试,搜索一个词,看看它在三维空间里离谁最近。比如输入 apple,最接近的5个词是 OSmacintoshamigaibmmicrosoft——苹果公司相关的词,而不是水果。

03.

如果孙悟空穿越到红楼梦

孙悟空 + 红楼梦 - 西游记 = ?一文搞懂什么是向量嵌入

开头的脑洞题,现在可以正式开算了。用代码表达就是:
result = word_vectors.most_similar(positive=["孙悟空", "红楼梦"], negative=["西游记"], topn=4)
print(f"孙悟空 + 红楼梦 - 西游记 = {result}")
答案出来了:
孙悟空 + 红楼梦 - 西游记 = [('唐僧', 0.4163001477718353), ('贾宝玉', 0.41606390476226807), ('妙玉', 0.39432790875434875), ('沙和尚', 0.3922004997730255)]
是不是有点意外?答案里居然出现了“唐僧”和“沙和尚”,这两位跟《红楼梦》八竿子打不着。这说明一个很关键的问题:词向量在做数学运算,它并不理解“孙悟空穿越到红楼梦”这个脑洞背后的语义。“唐僧”和“沙和尚”之所以出现,是因为它们跟“孙悟空”语义高度相关;“贾宝玉”和“妙玉”出现,是因为它们跟《红楼梦》关联更紧。模型只是机械地把两边的相关性叠加了一下。 不过,这种测试确实有意思。再加两个好玩的试试:
result = word_vectors.most_similar(positive=["牛奶", "发酵"], topn=1)
print(f"牛奶 + 发酵 = {result[0][0]}")

result = word_vectors.most_similar(positive=["男人", "泰国"], topn=1)
print(f"男人 + 泰国 = {result[0][0]}")
结果:
牛奶 + 发酵 = 变酸
男人 + 泰国 = 女人
前面那个很合理,后面这个嘛……只能说模型从语料中学到了一些刻板印象,但逻辑上确实说得通。

04.

一词多义怎么办 前面说的词向量模型,每个词只有一个固定向量,就像一本字典里每个词只有一条释义。但语言里一词多义太常见了。比如“苹果”,既可以指水果,也可以指那家科技公司。词向量在训练时,两种语义都会考虑进来,结果它的向量就会落在“水果”和“电子产品公司”之间——两边都不靠,像个折中的产物。 怎么解决这个问题?BERT模型(Bidirectional Encoder Representations from Transformers)应运而生。它基于深度神经网络,使用Transformer架构,核心是自注意力机制:处理一个词时,模型会同时看它前后的上下文,并根据上下文动态调整这个词的向量。比如,“苹果”这个词,如果上下文里出现“手机”,模型就会给“手机”多分配一些权重,把“苹果”的向量往“手机”方向拉;如果上下文是“水果”,就往“水果”方向拉。同一个词,在不同句子里的向量可以完全不同。 BERT的预训练有两种方式。第一种叫“掩码语言模型(MLM)”,跟word2vec有点像,随机遮住句子里的某个词,让模型根据上下文去猜,然后跟真实结果对比,调整参数。第二种叫“下一句预测(NSP)”,每次输入两个句子,让模型判断第二句是不是第一句的下一句,同样通过对比进行调整。 纸上谈兵到此为止,咱们动手验证一下。先加载BERT模型,写个函数来获取句子中指定单词的向量:
from transformers import BertTokenizer, BertModel

bert_tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
bert_model = BertModel.from_pretrained('bert-base-chinese')

def get_bert_emb(sentence, word):
    input = bert_tokenizer(sentence, return_tensors='pt')
    output = bert_model(**input)
    last_hidden_states = output.last_hidden_state
    word_tokens = bert_tokenizer.tokenize(sentence)
    word_index = word_tokens.index(word)
    word_emb = last_hidden_states[0, word_index + 1, :]
    return word_emb
然后,分别用BERT和词向量模型,获取两个句子中“开”这个字的向量:
sentence1 = "我今天很开心。"
sentence2 = "我打开了房门。"
word = "开"

bert_emb1 = get_bert_emb(sentence1, word).detach().numpy()
bert_emb2 = get_bert_emb(sentence2, word).detach().numpy()
word_emb = word_vectors[word]
看看区别:
print(f"在句子 '{sentence1}' 中,'{word}'的向量的前四个维度:{bert_emb1[:4]}")
print(f"在句子 '{sentence2}' 中,'{word}'的向量的前四个维度:{bert_emb2[:4]}")
print(f"在词向量模型中, '{word}' 的向量的前四个维度:{word_emb[:4]}")
输出非常直观:
在句子 '我今天很开心。' 中,'开'的向量的前四个维度:[1.4325644  0.05137304 1.6045816  0.01002912]
在句子 '我打开了房门。' 中,'开'的向量的前四个维度:[ 0.9039772  -0.5877741   0.6639165   0.45880783]
在词向量模型中, '开' 的向量的前四个维度:[ 0.260962  0.040874  0.434256 -0.305888]
BERT模型果然根据上下文给出了不同的向量。再算一下余弦相似度,差异就更明显了:
from sklearn.metrics.pairwise import cosine_similarity

bert_similarity = cosine_similarity([bert_emb1], [bert_emb2])[0][0]
print(f"在 '{sentence1}' 和 '{sentence2}' 这两个句子中,两个 '{word}' 的余弦相似度是: {bert_similarity:.2f}")

word_similarity = cosine_similarity([word_emb], [word_emb])[0][0]
print(f"在词向量中, '{word}' 和 '{word}' 的余弦相似度是: {word_similarity:.2f}")
结果:不同句子里的“开”余弦相似度只有0.69,而词向量模型里同一个词的相似度永远是1.0——因为压根没变过。
在 '我今天很开心。' 和 '我打开了房门。' 这两个句子中,两个 '开' 的余弦相似度是: 0.69
在词向量中, '开' 和 '开' 的余弦相似度是: 1.00

05.

怎么获得句子的向量 BERT能拿到单词的向量,那要拿整个句子的向量怎么办?最直接的方法是把句子中所有词向量求平均。但这就像跟一个千万富豪站在一起算平均资产——两个人的平均数也是千万富翁,完全不能反映真实情况。句子语义有重点,必须用专门的句子嵌入模型。 BGE_M3 就是这样一个模型,它直接生成句子级别的嵌入向量,能更好地捕捉上下文信息,尤其支持中文。是骡子是马,拉出来遛遛。我们先写一个用BERT求平均的函数做对比:
import torch

def get_bert_sentence_emb(sentence):
    input = bert_tokenizer(sentence, return_tensors='pt')
    output = bert_model(**input)
    last_hidden_states = output.last_hidden_state
    sentence_emb = torch.mean(last_hidden_states, dim=1).flatten().tolist()
    return sentence_emb
然后安装 pymilvus.model 库,用 BGE_M3 模型:
pip install pymilvus "pymilvus[model]"
from pymilvus.model.hybrid import BGEM3EmbeddingFunction

def get_bgem3_sentence_emb(sentence, model_name='BAAI/bge-m3'):
    bge_m3_ef = BGEM3EmbeddingFunction(
        model_name=model_name,
        device='cpu',
        use_fp16=False
    )
    vectors = bge_m3_ef.encode_documents([sentence])
    return vectors['dense'][0].tolist()
好了,拿三句话来测试:“我喜欢这部电影!”、“这部电影太棒了!”和“我讨厌这部电影。”。前两句语义相近,第三句相反。先看BERT平均向量的结果:
sentence1 = "我喜欢这部电影!"
sentence2 = "这部电影太棒了!"
sentence3 = "我讨厌这部电影。"

bert_sentence_emb1 = get_bert_sentence_emb(sentence1)
bert_sentence_emb2 = get_bert_sentence_emb(sentence2)
bert_sentence_emb3 = get_bert_sentence_emb(sentence3)

print(f"'{sentence1}' 和 '{sentence2}' 的余弦相似度: {cosine_similarity([bert_sentence_emb1], [bert_sentence_emb2])[0][0]:.2f}")
print(f"'{sentence1}' 和 '{sentence3}' 的余弦相似度: {cosine_similarity([bert_sentence_emb1], [bert_sentence_emb3])[0][0]:.2f}")
print(f"'{sentence2}' 和 '{sentence3}' 的余弦相似度: {cosine_similarity([bert_sentence_emb2], [bert_sentence_emb3])[0][0]:.2f}")
输出:
'我喜欢这部电影!' 和 '这部电影太棒了!' 的余弦相似度: 0.93
'我喜欢这部电影!' 和 '我讨厌这部电影。' 的余弦相似度: 0.94
'这部电影太棒了!' 和 '我讨厌这部电影。' 的余弦相似度: 0.89
三句话的相似度都在0.9左右,完全没区分出褒贬——平均操作把情感差异都给抹平了。 再看BGE_M3的表现:
bgem3_sentence_emb1 = get_bgem3_sentence_emb(sentence1)
bgem3_sentence_emb2 = get_bgem3_sentence_emb(sentence2)
bgem3_sentence_emb3 = get_bgem3_sentence_emb(sentence3)

print(f"'{sentence1}' 和 '{sentence2}' 的余弦相似度: {cosine_similarity([bgem3_sentence_emb1], [bgem3_sentence_emb2])[0][0]:.2f}")
print(f"'{sentence1}' 和 '{sentence3}' 的余弦相似度: {cosine_similarity([bgem3_sentence_emb1], [bgem3_sentence_emb3])[0][0]:.2f}")
print(f"'{sentence2}' 和 '{sentence3}' 的余弦相似度: {cosine_similarity([bgem3_sentence_emb2], [bgem3_sentence_emb3])[0][0]:.2f}")
输出:
'我喜欢这部电影!' 和 '这部电影太棒了!' 的余弦相似度: 0.86
'我喜欢这部电影!' 和 '我讨厌这部电影。' 的余弦相似度: 0.65
'这部电影太棒了!' 和 '我讨厌这部电影。' 的余弦相似度: 0.57
前两句(喜欢/太棒了)相似度0.86,明显高于它们与第三句(讨厌)的0.65和0.57。BGE_M3 确实抓住了句子整体的语义,而不是简单拼凑单词。

06.

藏宝图 这篇文章主要是通过代码演示来直观感受向量嵌入的原理和效果。如果你想深入技术细节,下面这些资料值得一读。

词向量模型

word2vec 模型论文:
  • Efficient Estimation of Word Representations in Vector Space (https://arxiv.org/abs/1301.3781)
  • Distributed Representations of Words and Phrases and their Compositionality (https://arxiv.org/abs/1310.4546)

中文词向量模型

  • Chinese-Word-Vectors (https://github.com/Embedding/Chinese-Word-Vectors) 项目提供了上百种预训练的中文词向量,基于不同表征、上下文特征和语料库。
  • 腾讯 AI Lab 中英文词和短语的嵌入语料库
  • word2vec-Chinese (https://github.com/lzhenboy/word2vec-Chinese) 介绍了如何训练中文 Word2Vec 词向量模型。

BERT 模型

BERT 模型论文:
  • BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding (https://arxiv.org/abs/1810.04805)
  • ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT (https://arxiv.org/abs/2004.12832)
BERT 模型的 GitHub:https://github.com/google-research/bert 介绍 ColBERT 模型的博客:Exploring ColBERT: A Token-Level Embedding and Ranking Model for Efficient Similarity Search (https://zilliz.com/learn/explore-colbert-token-level-embedding-and-ranking-model-for-similarity-search)

bge_m3 模型

介绍 bge_m3 模型的博客:Exploring BGE-M3 and Splade: Two Machine Learning Models for Generating Sparse Embeddings (https://zilliz.com/learn/bge-m3-and-splade-two-machine-learning-models-for-generating-sparse-embeddings#BERT-The-Foundation-Model-for-BGE-M3-and-Splade)

注意力模型

注意力模型论文:Attention Is All You Need (https://arxiv.org/abs/1706.03762)

模型库

  • gensim (https://radimrehurek.com/gensim/) 包含了 word2vec 模型和 GloVe 模型。
  • Transformers (https://huggingface.co/transformers/) 是 Hugging Face 的开源库,提供大量预训练的 Transformer 模型(BERT、GPT、T5 等)。
  • Chinese-BERT-wwm (https://github.com/ymcui/Chinese-BERT-wwm) 是哈工大讯飞联合实验室(HFL)发布的中文 BERT 模型。
  • pymilvus.model (https://milvus.io/docs/embeddings.md) 是 PyMilvus 的子包,封装了多种嵌入模型,方便生成向量。

[^1]: 严格来说,“目标词”是“token”而非单词。Token 是组成句子的基本单元,英文可能是一个单词或子词(如“unhappiness”拆成“un”和“happiness”),中文则是字、词或短语。
热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:孙悟空加红楼梦减西游记一文搞懂向量嵌入要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://www.53ai.com/news/RAG/2024121178310.html
ai 人工智能

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-12 19:21
Remaker AI免费去除任意图像水印和文字,几秒内完成

先来看看Remaker AI这款工具。它的定位非常清晰——专注于解决图像处理中的常见难题:水印、文字、多余元素,以及低分辨率图像的修复与放大。无论是设计师、社交媒体运营人员,还是普通用户,只要遇到需要“清理”图片的场景,它都能轻松应对。下面直接了解它的适用人群和实际能力。 需求人群 Remaker

AI热点2026-07-12 19:20
文心大模型:高效智能多功能AI文本生成工具

文心大模型覆盖文化传媒、艺术创作、教育科研、金融保险、医疗健康等需文字与创意的场景,集成文本生成、文生图、智能对话、信息抽取、文本纠错、古诗创作、文案续写等十余种文字处理能力。

AI热点2026-07-12 19:20
Ask AI浏览器 高效人工智能搜索与即时聊天工具

今天我们来聊一款非常实用的浏览器工具——Ask AI Browser。如果你经常在Google上搜索问题,又希望随时与AI对话,或者在浏览各类网站时想直接向AI提问,那么这款工具可能会为你的日常浏览体验带来显著提升。 目标用户群体 简单来说,它主要面向以下几类用户:在Google上搜索问题时,希望无

AI热点2026-07-12 19:19
中国联通个人云盘云存储服务正式上线

说起来,联通云盘这事儿,其实就是中国联通在云存储这条赛道上的一次重要布局。目标很明确:为个人和家庭用户解决海量数据存储的刚需。具体能干啥呢?个人云、家庭云、微信 通讯录 相册备份、多端文件共享……说白了,就是从存储到共享的一条龙服务。 联通云盘官网网页版登录入口网址:https: pan wo c

延伸阅读