趋近智
一种实践方法是使用一个常用的 Python 库为文本数据生成向量嵌入。然后使用相似度量来比较这些嵌入,以说明如何将数据表示为向量并测量其相似度。
首先,请确保您已安装所需的库。我们将主要使用 sentence-transformers 来生成嵌入,以及 numpy 和 scipy 进行数值运算和相似度计算。如果您计划可视化嵌入(我们随后会演示),您还需要 scikit-learn 进行降维,并使用 plotly 进行绘图。
您可以使用 pip 安装这些库:
pip install sentence-transformers numpy scipy scikit-learn plotly
sentence-transformers 库方便地访问多个预训练模型,这些模型适用于生成高质量的句子和文本嵌入。这些模型通常基于 BERT 等 Transformer 架构,经过微调,可以将语义相似的句子映射到嵌入空间中相邻的向量。
本次练习中,我们将使用 all-MiniLM-L6-v2。它在性能和计算效率之间提供了良好的平衡,使其适合进行试验,而无需占用过多资源。
我们来在 Python 中加载模型:
from sentence_transformers import SentenceTransformer
# 加载预训练的句子嵌入模型
model_name = 'all-MiniLM-L6-v2'
model = SentenceTransformer(model_name)
print(f"Model '{model_name}' loaded successfully.")
# Output: 模型 'all-MiniLM-L6-v2' 加载成功。
现在,我们来定义几个样本句子。请注意,有些句子在语义上相似,而有些则讨论不同的主题。
import numpy as np
sentences = [
"The delivery arrived on time.",
"My package was delivered promptly.",
"Vector databases store numerical representations.",
"How can I optimize database queries?",
"The weather today is sunny and warm."
]
# 为句子生成嵌入
embeddings = model.encode(sentences)
# 检查嵌入矩阵的维度
print(f"Shape of embeddings matrix: {embeddings.shape}")
# Output: 嵌入矩阵的形状: (5, 384)
# 显示第一个嵌入的前5个维度
print(f"First 5 dimensions of the first sentence embedding:\n{embeddings[0, :5]}")
# Output: 第一个句子嵌入的前5个维度:
# [-0.0568201 -0.01949895 0.00780028 0.03499191 -0.0031617 ]
如您所见,model.encode() 方法接受我们的句子列表并返回一个 NumPy 数组。形状 (5, 384) 表示我们有 5 个嵌入(每个句子一个),并且每个嵌入都是一个 384 维的向量,这由 all-MiniLM-L6-v2 模型架构决定。
生成嵌入后,我们现在可以使用之前讨论过的度量标准(例如余弦相似度)来量化句子对之间的语义相似度。请记住,余弦相似度测量两个向量之间夹角的余弦值。值越接近 1 表示相似度越高,0 表示正交(无相似度),而 -1 表示相反的含义(尽管在这些类型的嵌入中不太常见)。
我们可以使用 scipy.spatial.distance.cosine 来计算余弦距离(即 )。然后,我们会将其转换回相似度。
from scipy.spatial.distance import cosine
# 计算成对余弦相似度
num_sentences = len(sentences)
similarity_matrix = np.zeros((num_sentences, num_sentences))
for i in range(num_sentences):
for j in range(num_sentences):
# 余弦距离 = 1 - 余弦相似度
similarity = 1 - cosine(embeddings[i], embeddings[j])
similarity_matrix[i, j] = similarity
# 打印相似度矩阵(为提高可读性已四舍五入)
print("成对余弦相似度矩阵:")
print(np.round(similarity_matrix, 2))
运行这段代码将生成一个类似这样的矩阵:
成对余弦相似度矩阵:
[[ 1. 0.88 -0.04 -0.02 -0.01]
[ 0.88 1. -0.05 -0.02 0.01]
[-0.04 -0.05 1. 0.46 -0.03]
[-0.02 -0.02 0.46 1. -0.01]
[-0.01 0.01 -0.03 -0.01 1. ]]
我们来分析一下相似度矩阵:
这表明了嵌入的能力:数值向量捕获语义含义,并且它们在向量空间中的接近度(通过余弦相似度测量)反映了这种含义。
直接可视化 384 维向量是不可能的。然而,我们可以使用主成分分析 (PCA) 或均匀流形近似与投影 (UMAP) 等降维技术,将这些向量投影到二维或三维空间进行可视化。这有助于建立一种直觉,理解嵌入如何根据含义进行聚类,尽管在降维过程中不可避免地会丢失一些信息。
以下是您如何使用 PCA 降维到二维并使用 Plotly 绘图的方法:
from sklearn.decomposition import PCA
import plotly.graph_objects as go
# 使用 PCA 将维度降至 2D
pca = PCA(n_components=2)
embeddings_2d = pca.fit_transform(embeddings)
# 创建散点图(为保持一致性,使用预先计算的示例坐标)
# 如果您自己运行代码,请将这些坐标替换为 PCA 转换的实际输出。
example_coords = {
"x": [-0.15, -0.18, 0.10, 0.25, -0.02],
"y": [0.08, 0.10, -0.05, -0.12, 0.01]
}
fig = go.Figure(data=go.Scatter(
# x=embeddings_2d[:, 0], # 使用实际 PCA 输出
# y=embeddings_2d[:, 1], # 使用实际 PCA 输出
x=example_coords["x"], # 使用示例值
y=example_coords["y"], # 使用示例值
mode='markers+text',
marker=dict(
size=10,
color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd'], # 示例颜色
opacity=0.8
),
text=[f"'{s[:20]}...'" for s in sentences], # 显示缩短的文本标签
textposition='top center'
))
fig.update_layout(
title='句子嵌入的2D PCA投影',
xaxis_title='主成分 1',
yaxis_title='主成分 2',
width=700,
height=500,
showlegend=False
)
# 显示图表(例如,在 Jupyter Notebook 中或保存为 HTML)
# fig.show()
# 或者生成用于网页嵌入的 JSON
chart_json = fig.to_json()
print("\nPlotly JSON 用于嵌入可视化:")
# 确保 JSON 输出在 ```plotly 块的单行上
print(chart_json.replace("\n", "").replace(" ", ""))
PCA 降维后的句子嵌入二维可视化。点越接近代表句子在原始高维空间中具有越高的语义相似度。请注意,两个关于交付的句子彼此靠近,两个关于数据库的句子也是如此,而关于天气的句子则相对独立。
本次实践练习表明了如何将文本转换为有意义的数值表示(嵌入),以及如何使用向量相似度计算来比较它们。这些生成的向量以及快速查找相似向量的能力构成了我们将在后续章节中在此基础上构建的向量数据库和语义搜索系统的基础。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造