向量模型大比拼,如何获取关联性 / ai #20
在本地知识库的构建中,其中重要的一环是对文本的向量计算,然后存入数据库备查。在这种知识库的项目中除了知识文本的重要性之外,向量计算几乎占据了绝大多数的比重,可以说:成败在此计算。
现在比较流行的有三个向量计算库:OpenAIEmbeddings、shibing624/text2vec-base-chinese和GanymedeNil/text2vec-large-chinese。接下来就实际测试下看看。
环境准备
python 3.10, 其它包:
pip install langchain chromadb openai tiktoken sentence-transformers python-dotenv
OpenAIEmbeddings
示例代码:
from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import TextLoader
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from dotenv import dotenv_values
env_vars = dotenv_values('.env')
# 加载和实例化数据库
persist_directory = './chroma'
collection = 'testcc'
embedding = OpenAIEmbeddings(
model="text-embedding-ada-002",
openai_api_key=env_vars['OPENAI_API_KEY']
)
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embedding, collection_name=collection)
# 文本分割
text_splitter = CharacterTextSplitter(chunk_size=400, chunk_overlap=0)
# chunk_size=400表示每次读取或写入数据时,数据的大小为400个字节, 约300~400个汉字
def saveToVectorDB(file):
try:
loader = TextLoader(file, encoding='gbk') #中文必须带 encoding='gbk'
documents = loader.load()
docs = text_splitter.split_documents(documents)
ids = vectordb.add_documents(documents=docs)
print(126, "saveDb ok", ids)
return "ok", 200
except Exception as e:
print(444, "saveDb error", e)
return "error", 500
# 查询相似度的文本
def queryVectorDB(ask):
s = vectordb.similarity_search_with_score(query=ask, k=3)
if len(s) == 0:
return ""
else:
if s[0][1] < 0.385:
return s[0][0].page_content
else:
return ""
往数据库中存入初始数据,就可以开始测试了。注意,这里用到了similarity_search_with_score这个函数。得到的数据如下:
[(Document(page_content='要选择优质菌种,配方更加科学......', metadata={'source': './uploads/yishejun.txt'}), 0.2091393032277543), (Document(page_content='益生菌是一类......', metadata={'source': './uploads/yishejun.txt'}), 0.29793976485387913), (Document(page_content='我们肠道所需要的有.....', metadata={'source': './uploads/yishejun.txt'}), 0.2995214947747933)]
每条数据都有一个得分,0.2091393032277543这就是问题和知识库文本相关的得分。越低表示越相关。这里就可以得到一组数据:
相关:
0.209
0.153
0.152
0.297
0.253
0.228
不相关:
0.453
0.476
0.475
0.479
可以看到,相关和不相关这两者之间有明显的界限。我们可以划出一个得分以区别相关性,我取得的0.385,效果还是可以。
shibing624/text2vec-base-chinese
还是上面同样的代码,只有向量函数换成:embedding = HuggingFaceEmbeddings(model_name='shibing624/text2vec-base-chinese') 即可。如果是第一次使用,程序会自动从HuggingFace上下载相关的模型,在本地完成计算。
用同样的文本去做计算测试,得到以下的分值:
相关:
288.64
190.68
221.10
153.35
201.33
308.08
不相关:
448.54
411.06
392.82
虽然在分界上表现还可以,但是在短文本上的查询很差,很多查不到! 这几乎可以说是它的致命缺点了。
GanymedeNil/text2vec-large-chinese
GanymedeNil/text2vec-large-chinese是在shibing624/text2vec-base-chinese基础上重新训练的模型,表现要更好些。跑分看看:
相关:
753.65
296.06
825.58
900.24
941.84
468.30
473.47
234.78
426.68
941.84
671.29
612.81
646.69
753.60
不相关:
820.72
915.02
910.17
381.96
774.05
864.51
915.02
948.56
784.89
753.06
虽然效果还可以,但是得分真的很迷惑啊,根本分不清是不是相关文本! 做了大量的实测后,也只能放弃,实在无法判断相关性。
做了这么多测试,也只有OpenAIEmbeddings是可行的。看来人家收钱是有道理的。现阶段,开源的向量计算模型还没有发展到可以实用的程度,只能静待下一步。
Leave 向量模型大比拼,如何获取关联性 / ai #20 to:
Read more #cn posts
Best Posts From lemooljiang
We have not curated any of lemooljiang's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.