OpenAI Embeddings API:获取嵌入向量、计算余弦相似度及距离函数选择
文本嵌入向量的余弦距离计算与距离函数选择
一、简易Python余弦距离计算代码
下面是直接可用的代码,包含调用OpenAI API生成嵌入、计算余弦距离的完整逻辑:
import openai import numpy as np # 替换成你的OpenAI API密钥 openai.api_key = "your-api-key-here" def generate_embedding(text, model="text-embedding-ada-002"): # 调用API生成文本嵌入向量 embedding_response = openai.Embedding.create(input=text, model=model) return embedding_response['data'][0]['embedding'] def calc_cosine_distance(vec_a, vec_b): # 余弦距离 = 1 - 余弦相似度,值越小表示语义越相似 dot_product = np.dot(vec_a, vec_b) norm_a = np.linalg.norm(vec_a) norm_b = np.linalg.norm(vec_b) cosine_similarity = dot_product / (norm_a * norm_b) return 1 - cosine_similarity # 示例运行 if __name__ == "__main__": text_x = "请输入第一个文本" text_y = "请输入第二个文本" emb_x = generate_embedding(text_x) emb_y = generate_embedding(text_y) distance = calc_cosine_distance(emb_x, emb_y) print(f"两个文本的余弦距离:{distance:.4f}")
二、欧氏距离能否更精准评估文本相似度?
答案是不能,原因如下:
- 余弦距离聚焦于向量的方向一致性,完全忽略向量长度差异。文本嵌入的长度往往和文本字数、词频相关,但语义相似的文本,嵌入向量的方向会高度重合,这正是我们需要的语义相似度核心指标。
- 欧氏距离是向量空间的直线距离,受向量长度影响极大。比如“猫爱吃鱼”和“胖嘟嘟的小猫特别爱吃新鲜的草鱼”,语义几乎一致,但后者的嵌入向量更长,欧氏距离会明显偏大,无法准确反映语义相似度。
数据库优先用余弦距离,不仅因为计算简便,更因为它贴合文本语义相似度的评估需求。
三、其他适合的距离函数
- 点积(Dot Product):当嵌入向量做过归一化处理时,点积结果等价于余弦相似度,计算效率比余弦距离更高,很多向量数据库(如pgvector)都支持点积查询。
- 曼哈顿距离:计算各维度绝对值差的总和,对异常值的鲁棒性比欧氏距离强,但同样受向量长度影响,语义相似度场景下表现不如余弦距离。
- 加权余弦距离:如果需要给某些关键维度(比如特定关键词对应的向量维度)更高权重,可以自定义加权逻辑,适合有特定业务需求的场景。
内容的提问来源于stack exchange,提问作者xrd
相关产品推荐
相关产品推荐

