Embedding
什么是 Embedding?
「Embedding」是指将高维度的数据(例如文字、图片、音频)映射到低维度空间的过程。embedding 向量通常是一个由实数构成的向量,它将输入的数据表示成一个连续的数值空间中的点。
词向量
从字面本身计算语义相关性是不够的。
- 不同字,同义:「快乐」vs.「高兴」
- 同字,不同义:「上马」vs.「马上」
所以我们需要一种方法,能够有效计算词与词之间的关系,词向量(Word Embedding)应运而生。
词向量的基本原理
用一个词上下文窗口表示它自身
词向量的不足
- 同一个词在不同上下文中语义不同:我从「马上」下来 vs. 我「马上」下来
关于词向量,更多内容参考:
基于整个句子,表示句中每个词,那么同时我们也就表示了整个句子
所以,句子、篇章都可以向量化
Sentence Transformer
向量相似度计算
[1]:
import numpy as np
from numpy import dot
from numpy.linalg import norm
from langchain.embeddings import OpenAIEmbeddings
def cos_sim(a, b):
return dot(a, b)/(norm(a)*norm(b))
def l2(a, b):
x = np.asarray(a)-np.asarray(b)
return norm(x)
model = OpenAIEmbeddings(model='text-embedding-ada-002')
query = "国际争端"
documents = [
"联合国就苏丹达尔富尔地区大规模暴力事件发出警告",
"土耳其、芬兰、瑞典与北约代表将继续就瑞典“入约”问题进行谈判",
"日本岐阜市陆上自卫队射击场内发生枪击事件 3人受伤",
"国家游泳中心(水立方):恢复游泳、嬉水乐园等水上项目运营",
"我国首次在空间站开展舱外辐射生物学暴露实验",
]
query_vec = model.embed_query(query)
doc_vecs = model.embed_documents(documents)
print("Cosine distance:") # 越大越相似
print(cos_sim(query_vec, query_vec))
for vec in doc_vecs:
print(cos_sim(query_vec, vec))
print("\nEuclidean distance:") # 越小越相似
print(l2(query_vec, query_vec))
for vec in doc_vecs:
print(l2(query_vec, vec))
[ ]:
Cosine distance: 1.0 0.8226018711360235 0.829977812402014 0.7983723967257063 0.7671380839706725 0.7934757098362577 Euclidean distance: 0.0 0.5956477631351883 0.5831332396596614 0.6350237842385019 0.6824396178847291 0.6426885562443797
基于相似度聚类
[2]:
from langchain.embeddings import OpenAIEmbeddings
from sklearn.cluster import KMeans, DBSCAN
import numpy as np
texts = [
"这个多少钱",
"啥价",
"给我报个价",
"我要红色的",
"不要了",
"算了",
"来红的吧",
"作罢",
"价格介绍一下",
"红的这个给我吧"
]
model = OpenAIEmbeddings(model='text-embedding-ada-002')
X = []
for t in texts:
embedding = model.embed_query(t)
X.append(embedding)
# clusters = KMeans(n_clusters=3, random_state=42, n_init="auto").fit(X)
clusters = DBSCAN(eps=0.55, min_samples=2).fit(X)
for i, t in enumerate(texts):
print("{}\t{}".format(clusters.labels_[i], t))
[ ]:
0 这个多少钱 0 啥价 0 给我报个价 1 我要红色的 -1 不要了 -1 算了 1 来红的吧 -1 作罢 0 价格介绍一下 1 红的这个给我吧
尝试本地部署
[$]:
!pip install sentence_transformers
[3]:
from langchain.embeddings import HuggingFaceBgeEmbeddings
model_name = "BAAI/bge-large-zh-v1.5"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
model = HuggingFaceBgeEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
[4]:
query = "国际争端"
documents = [
"联合国就苏丹达尔富尔地区大规模暴力事件发出警告",
"土耳其、芬兰、瑞典与北约代表将继续就瑞典“入约”问题进行谈判",
"日本岐阜市陆上自卫队射击场内发生枪击事件 3人受伤",
"国家游泳中心(水立方):恢复游泳、嬉水乐园等水上项目运营",
"我国首次在空间站开展舱外辐射生物学暴露实验",
]
query_vec = model.embed_query(query)
doc_vecs = model.embed_documents(documents)
print("Cosine distance:") # 越大越相似
print(cos_sim(query_vec, query_vec))
for vec in doc_vecs:
print(cos_sim(query_vec, vec))
[ ]:
Cosine distance: 1.0 0.39085908636919475 0.31848764875846713 0.28801350328358377 0.2598757213201276 0.2611598107519106
关于向量相似度计算,更多内容参考: