1. 背景:为什么要用向量?
我们人类聊天用文字,计算机可不认识“你好”“喜欢”“苹果”这些字,它只能理解数字。
但问题是: “苹果”和“橘子”意思相近,怎么让计算机也明白?
如果我们能把“苹果”和“橘子”都转成一组数字(向量),而且相近,就能让计算机搞懂语义上的“相似”。
以前的办法:One-Hot 编码(简单但傻)
比如词库: 苹果、橘子、香蕉、车
单词 | 向量 |
---|---|
苹果 | [1,0,0,0] |
橘子 | [0,1,0,0] |
香蕉 | [0,0,1,0] |
车 | [0,0,0,1] |
缺点:
- 词和词没关系
- 向量超稀疏,维度爆炸
2. 词向量(Word Embedding):给词赋予语义空间
Word2Vec、GloVe、FastText 这类方法,把每个词映射成一个低维向量。比如:
单词 | 向量 (简化) |
---|---|
苹果 | [0.21, 0.65, 0.33] |
橘子 | [0.20, 0.66, 0.30] |
车 | [0.05, 0.10, 0.85] |
效果:
“苹果”和“橘子”向量距离很近,和“车”距离远。
可视化:
| o 苹果
| o 橘子
|
| o 车
|
+————————
3. 语义嵌入(Semantic Embedding):给句子/段落赋予语义空间
词向量解决了单词问题,但我们平时说的是句子. 比如:
- “我喜欢足球。”
- “踢球是我的爱好。”
虽然词不一样,但意思差不多。
语义嵌入:就是把整句话变成向量,意思相近的向量靠近
。
用法:
- Sentence-BERT
- Universal Sentence Encoder
- Text Embedding Models
4. 多个例子秒懂
例子1:单词相似度
用 spaCy 实现:
import spacy
nlp = spacy.load("en_core_web_md")
word1 = nlp("apple")
word2 = nlp("orange")
word3 = nlp("car")
print(word1.similarity(word2)) # 比较相似度
print(word1.similarity(word3))
输出:
0.68
0.14
说明“苹果”和“橘子”更相近。
例子2:句子相似度
用 SentenceTransformer:
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer('all-MiniLM-L6-v2')
sentences = ["I like football.", "Playing soccer is my hobby."]
embeddings = model.encode(sentences)
similarity = util.cos_sim(embeddings[0], embeddings[1])
print(similarity)
输出:
0.85
表示句子语义非常接近。
例子3:多句聚类 (聚相似的句子)
KMeans 聚类
from sklearn.cluster import KMeans
# 假设已有 sentence embeddings
embeddings = model.encode([
"I love apples.",
"Oranges are great.",
"My car is fast.",
"I drive a vehicle."
])
kmeans = KMeans(n_clusters=2, random_state=0).fit(embeddings)
print(kmeans.labels_)
输出:
[0, 0, 1, 1]
说明前两句是“水果组”,后两句是“汽车组”。
5. 常见典型应用场景
应用方向 | 用法 |
---|---|
文本相似度搜索 | 用嵌入计算语义相似度,找出相关内容 |
智能问答 | 用户提问转向量,与标准问题向量比对,取最相似答案 |
推荐系统 | 文本内容向量化,找相似新闻/视频/商品 |
评论聚类 | 将评论句子嵌入,聚类分析用户观点趋势 |
情感分类 | 嵌入后做情感判别:正面、负面、中性 |
搜索排序 | 查询语义嵌入 vs 内容嵌入,按相似度排序 |
知识图谱实体匹配 | 相似实体短语嵌入距离靠近,辅助实体对齐 |
6. 总结
- 词向量 → 单词的数字表达
- 语义嵌入 → 句子/段落的数字表达
- 相似意思,向量越近
7. 实战推荐工具
工具/库 | 适合场景 |
---|---|
Word2Vec (gensim) | 单词向量 |
spaCy (en_core_web_md) | 简单词向量 + 相似度计算 |
Sentence-BERT | 句子、段落嵌入 |
Universal Sentence Encoder | 通用句子嵌入 |
Hugging Face Transformers | 各类 BERT / LLaMA / 文本嵌入 |
8.经典案例
词向量经典案例
Word2Vec 相似词查询
from gensim.models import Word2Vec
# 加载预训练模型
model = Word2Vec.load("word2vec.model")
# 查询相似词
print(model.wv.most_similar("king"))
向量运算:king - man + woman ≈ queen
result = model.wv.most_similar(positive=["king", "woman"], negative=["man"], topn=1)
print(result)
语义嵌入经典案例
Sentence-BERT 句子相似度
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer('all-MiniLM-L6-v2')
sentences = ["今天天气很好", "阳光明媚的好日子"]
embeddings = model.encode(sentences)
similarity = util.cos_sim(embeddings[0], embeddings[1])
print(similarity)
输出:
tensor([[0.85]])
文本聚类(评论聚类)
spaCy + KMeans 实现评论聚类
import spacy
from sklearn.cluster import KMeans
import numpy as np
nlp = spacy.load("en_core_web_md")
texts = ["good product", "bad quality", "excellent service", "poor response"]
vectors = np.array([nlp(text).vector for text in texts])
kmeans = KMeans(n_clusters=2, random_state=42).fit(vectors)
print(kmeans.labels_)
智能问答系统
句子嵌入匹配标准问法
questions = ["How to reset password?", "Where is my order?", "How to cancel order?"]
user_input = "I forgot my password"
question_embeddings = model.encode(questions)
user_embedding = model.encode(user_input)
similarities = util.cos_sim(user_embedding, question_embeddings)
best_match = questions[similarities.argmax()]
print("匹配问题:", best_match)
推荐系统:基于嵌入的相似推荐
商品、视频、新闻文章嵌入后,计算余弦相似度,推荐相似内容。