当前位置:   article > 正文

使用 ElasticSearch 作为知识库,存储向量及相似性搜索_elasticsearch cosinesimilarity(1)_elasticsearch searchsimilar

elasticsearch searchsimilar
            "search\_analyzer": "ik\_smart"
        }
    }
}
  • 1
  • 2
  • 3
  • 4

}


其中 `dims` 为向量的长度。


![在这里插入图片描述](https://img-blog.csdnimg.cn/887d8efe896b4f479b64a32f47621faf.png)


查看创建的索引:



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

GET http://127.0.0.1:9200/medical_index


![在这里插入图片描述](https://img-blog.csdnimg.cn/76d5aa759abf40b8b6c4517759a4142d.png)


#### 数据存入 ElasticSearch


引入 `ElasticSearch` 依赖库:



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

pip install elasticsearch -i https://pypi.tuna.tsinghua.edu.cn/simple



  • 1
  • 2

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torch
import pandas as pd

def embeddings_doc(doc, tokenizer, model, max_length=300):
encoded_dict = tokenizer.encode_plus(
doc,
add_special_tokens=True,
max_length=max_length,
padding=‘max_length’,
truncation=True,
return_attention_mask=True,
return_tensors=‘pt’
)
input_id = encoded_dict[‘input_ids’]
attention_mask = encoded_dict[‘attention_mask’]

# 前向传播
with torch.no_grad():
    outputs = model(input_id, attention_mask=attention_mask)

# 提取最后一层的CLS向量作为文本表示
last_hidden_state = outputs.last_hidden_state
cls_embeddings = last_hidden_state[:, 0, :]
return cls_embeddings[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

def add_doc(index_name, id, embedding_ask, ask, answer, es):
body = {
“ask_vector”: embedding_ask.tolist(),
“ask”: ask,
“answer”: answer
}
result = es.create(index=index_name, id=id, doc_type=“_doc”, body=body)
return result

def main():
# 模型下载的地址
model_name = ‘D:\AIGC\model\chinese-roberta-wwm-ext-large’
# ES 信息
es_host = “http://127.0.0.1”
es_port = 9200
es_user = “elastic”
es_password = “elastic”
index_name = “medical_index”

# 数据地址
path = "D:\\AIGC\\dataset\\Chinese-medical-dialogue-data\\Chinese-medical-dialogue-data\\Data\_数据\\IM\_内科\\内科5000-33000.csv"

# 分词器和模型
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)

# ES 连接
es = Elasticsearch(
    [es_host],
    port=es_port,
    http_auth=(es_user, es_password)
)

# 读取数据写入ES
data = pd.read_csv(path, encoding='ANSI')
for index, row in data.iterrows():
    # 写入前 5000 条进行测试
    if index >= 500:
        break
    ask = row["ask"]
    answer = row["answer"]
    # 文本转向量
    embedding_ask = embeddings_doc(ask, tokenizer, model)
    result = add_doc(index_name, index, embedding_ask, ask, answer, es)
    print(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

if name == ‘__main__’:
main()


![在这里插入图片描述](https://img-blog.csdnimg.cn/6ee3311515b542968821db957c671ec0.png)


### 五、相似性搜索


#### 1. 余弦相似度算法:cosineSimilarity



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torch

def embeddings_doc(doc, tokenizer, model, max_length=300):
encoded_dict = tokenizer.encode_plus(
doc,
add_special_tokens=True,
max_length=max_length,
padding=‘max_length’,
truncation=True,
return_attention_mask=True,
return_tensors=‘pt’
)
input_id = encoded_dict[‘input_ids’]
attention_mask = encoded_dict[‘attention_mask’]

# 前向传播
with torch.no_grad():
    outputs = model(input_id, attention_mask=attention_mask)

# 提取最后一层的CLS向量作为文本表示
last_hidden_state = outputs.last_hidden_state
cls_embeddings = last_hidden_state[:, 0, :]
return cls_embeddings[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

def search_similar(index_name, query_text, tokenizer, model, es, top_k=3):
query_embedding = embeddings_doc(query_text, tokenizer, model)
print(query_embedding.tolist())
query = {
“query”: {
“script_score”: {
“query”: {“match_all”: {}},
“script”: {
“source”: “cosineSimilarity(params.queryVector, ‘ask_vector’) + 1.0”,
“lang”: “painless”,
“params”: {
“queryVector”: query_embedding.tolist()
}
}
}
},
“size”: top_k
}
res = es.search(index=index_name, body=query)
hits = res[‘hits’][‘hits’]
similar_documents = []
for hit in hits:
similar_documents.append(hit[‘_source’])
return similar_documents

def main():
# 模型下载的地址
model_name = ‘D:\AIGC\model\chinese-roberta-wwm-ext-large’
# ES 信息
es_host = “http://127.0.0.1”
es_port = 9200
es_user = “elastic”
es_password = “elastic”
index_name = “medical_index”

# 分词器和模型
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)

# ES 连接
es = Elasticsearch(
    [es_host],
    port=es_port,
    http_auth=(es_user, es_password)
)

query_text = "我有高血压可以拿党参泡水喝吗"

similar_documents = search_similar(index_name, query_text, tokenizer, model, es)
for item in similar_documents:
    print("================================")
    print('ask:', item['ask'])
    print('answer:', item['answer'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

if name == ‘__main__’:
main()


打印日志如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/119586d313414361b44cd1ecd50f8794.png)



> 
> ================================  
>  ask: 我有高血压这两天女婿来的时候给我拿了些党参泡水喝,您好高血压可以吃党参吗?  
>  answer: 高血压病人可以口服党参的。党参有降血脂,降血压的作用,可以彻底消除血液中的垃圾,从而对冠心病以及心血管疾病的患者都有一定的稳定预防工作作用,因此平时口服党参能远离三高的危害。另外党参除了益气养血,降低中枢神经作用,调整消化系统功能,健脾补肺的功能。感谢您的进行咨询,期望我的解释对你有所帮助。  
>  ================================  
>  ask: 我准备过两天去看我叔叔,顺便带些人参,但是他有高血压,您好人参高血压可以吃吗?  
>  answer: 人参有一定的调压作用,主要用来气虚体虚的患者,如果有气血不足,气短乏力,神经衰弱,神经衰弱健忘等不适症状的话,可以适当口服人参调养身体,但是对于高血压的病人,如果长期食用人参的话,可能会对血压引发一定影响,所以,比较好到医院中医科实施辨证论治调治,看如何适合食用人参。  
>  ================================  
>  ask: 我妈妈有点高血压,比较近我朋友送了我一些丹参片,我想知道高血压能吃丹参片吗?  
>  answer: 丹参片具备活血化瘀打通血管的作用可以致使血液粘稠度减低,所以就容易致使血管内血液供应便好防止出现血液粘稠,致使血压下降,所以对降血压是有一定帮助的,高血压患者是经常使用丹参片实施治疗的。可以预防,因为血液粘稠引来的冠心病心绞痛以及外周血管脑水肿症状。
> 
> 
> 


#### 2. 点积算法:dotProduct


计算给定查询向量和文档向量之间的点积度量。



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torch

def embeddings_doc(doc, tokenizer, model, max_length=300):
encoded_dict = tokenizer.encode_plus(
doc,
add_special_tokens=True,
max_length=max_length,
padding=‘max_length’,
truncation=True,
return_attention_mask=True,
return_tensors=‘pt’
)
input_id = encoded_dict[‘input_ids’]
attention_mask = encoded_dict[‘attention_mask’]

# 前向传播
with torch.no_grad():
    outputs = model(input_id, attention_mask=attention_mask)

# 提取最后一层的CLS向量作为文本表示
last_hidden_state = outputs.last_hidden_state
cls_embeddings = last_hidden_state[:, 0, :]
return cls_embeddings[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

def search_similar(index_name, query_text, tokenizer, model, es, top_k=3):
query_embedding = embeddings_doc(query_text, tokenizer, model)
print(query_embedding.tolist())
query = {
“query”: {
“script_score”: {
“query”: {“match_all”: {}},
“script”: {
“source”: “dotProduct(params.queryVector, ‘ask_vector’)+1.0”,
“lang”: “painless”,
“params”: {
“queryVector”: query_embedding.tolist()
}
}
}
},
“size”: top_k
}
res = es.search(index=index_name, body=query)
hits = res[‘hits’][‘hits’]
similar_documents = []
for hit in hits:
similar_documents.append(hit[‘_source’])
return similar_documents

def main():
# 模型下载的地址
model_name = ‘D:\AIGC\model\chinese-roberta-wwm-ext-large’
# ES 信息
es_host = “http://127.0.0.1”
es_port = 9200
es_user = “elastic”
es_password = “elastic”
index_name = “medical_index”

# 分词器和模型
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)

# ES 连接
es = Elasticsearch(
    [es_host],
    port=es_port,
    http_auth=(es_user, es_password)
)

query_text = "我有高血压可以拿党参泡水喝吗"

similar_documents = search_similar(index_name, query_text, tokenizer, model, es)
for item in similar_documents:
    print("================================")
    print('ask:', item['ask'])
    print('answer:', item['answer'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

if name == ‘__main__’:
main()


![在这里插入图片描述](https://img-blog.csdnimg.cn/fcb5a0658cb34767a4f654de562f7d8d.png)



> 
> ================================  
>  ask: 我有高血压这两天女婿来的时候给我拿了些党参泡水喝,您好高血压可以吃党参吗?  
>  answer: 高血压病人可以口服党参的。党参有降血脂,降血压的作用,可以彻底消除血液中的垃圾,从而对冠心病以及心血管疾病的患者都有一定的稳定预防工作作用,因此平时口服党参能远离三高的危害。另外党参除了益气养血,降低中枢神经作用,调整消化系统功能,健脾补肺的功能。感谢您的进行咨询,期望我的解释对你有所帮助。  
>  ================================  
>  ask: 我准备过两天去看我叔叔,顺便带些人参,但是他有高血压,您好人参高血压可以吃吗?  
>  answer: 人参有一定的调压作用,主要用来气虚体虚的患者,如果有气血不足,气短乏力,神经衰弱,神经衰弱健忘等不适症状的话,可以适当口服人参调养身体,但是对于高血压的病人,如果长期食用人参的话,可能会对血压引发一定影响,所以,比较好到医院中医科实施辨证论治调治,看如何适合食用人参。  
>  ================================  
>  ask: 我妈妈有点高血压,比较近我朋友送了我一些丹参片,我想知道高血压能吃丹参片吗?  
>  answer: 丹参片具备活血化瘀打通血管的作用可以致使血液粘稠度减低,所以就容易致使血管内血液供应便好防止出现血液粘稠,致使血压下降,所以对降血压是有一定帮助的,高血压患者是经常使用丹参片实施治疗的。可以预防,因为血液粘稠引来的冠心病心绞痛以及外周血管脑水肿症状。
> 
> 
> 


#### 3. L1曼哈顿距离:l1norm


计算给定查询向量和文档向量之间的L1距离。



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torch

def embeddings_doc(doc, tokenizer, model, max_length=300):
encoded_dict = tokenizer.encode_plus(
doc,
add_special_tokens=True,
max_length=max_length,
padding=‘max_length’,
truncation=True,
return_attention_mask=True,
return_tensors=‘pt’
)
input_id = encoded_dict[‘input_ids’]
attention_mask = encoded_dict[‘attention_mask’]

# 前向传播
with torch.no_grad():
    outputs = model(input_id, attention_mask=attention_mask)

# 提取最后一层的CLS向量作为文本表示
last_hidden_state = outputs.last_hidden_state
cls_embeddings = last_hidden_state[:, 0, :]
return cls_embeddings[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

def search_similar(index_name, query_text, tokenizer, model, es, top_k=3):
query_embedding = embeddings_doc(query_text, tokenizer, model)
print(query_embedding.tolist())
query = {
“query”: {
“script_score”: {
“query”: {“match_all”: {}},
“script”: {
“source”: “1 / (1 + l1norm(params.queryVector, doc[‘ask_vector’]))”,
“lang”: “painless”,
“params”: {
“queryVector”: query_embedding.tolist()
}
}
}
},
“size”: top_k
}
res = es.search(index=index_name, body=query)
hits = res[‘hits’][‘hits’]
similar_documents = []
for hit in hits:
similar_documents.append(hit[‘_source’])
return similar_documents

def main():
# 模型下载的地址
model_name = ‘D:\AIGC\model\chinese-roberta-wwm-ext-large’
# ES 信息
es_host = “http://127.0.0.1”
es_port = 9200
es_user = “elastic”
es_password = “elastic”
index_name = “medical_index”

# 分词器和模型
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)

# ES 连接
es = Elasticsearch(
    [es_host],
    port=es_port,
    http_auth=(es_user, es_password)
)

query_text = "我有高血压可以拿党参泡水喝吗"

similar_documents = search_similar(index_name, query_text, tokenizer, model, es)
for item in similar_documents:
    print("================================")
    print('ask:', item['ask'])
    print('answer:', item['answer'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

if name == ‘__main__’:
main()


![在这里插入图片描述](https://img-blog.csdnimg.cn/ab5bf0797da9468aa6ab136313ddd0f7.png)



> 
> ================================  
>  ask: 我有高血压这两天女婿来的时候给我拿了些党参泡水喝,您好高血压可以吃党参吗?  
>  answer: 高血压病人可以口服党参的。党参有降血脂,降血压的作用,可以彻底消除血液中的垃圾,从而对冠心病以及心血管疾病的患者都有一定的稳定预防工作作用,因此平时口服党参能远离三高的危害。另外党参除了益气养血,降低中枢神经作用,调整消化系统功能,健脾补肺的功能。感谢您的进行咨询,期望我的解释对你有所帮助。  
>  ================================  
>  ask: 我准备过两天去看我叔叔,顺便带些人参,但是他有高血压,您好人参高血压可以吃吗?  
>  answer: 人参有一定的调压作用,主要用来气虚体虚的患者,如果有气血不足,气短乏力,神经衰弱,神经衰弱健忘等不适症状的话,可以适当口服人参调养身体,但是对于高血压的病人,如果长期食用人参的话,可能会对血压引发一定影响,所以,比较好到医院中医科实施辨证论治调治,看如何适合食用人参。  
>  ================================  
>  ask: 我妈妈有点高血压,比较近我朋友送了我一些丹参片,我想知道高血压能吃丹参片吗?  
>  answer: 丹参片具备活血化瘀打通血管的作用可以致使血液粘稠度减低,所以就容易致使血管内血液供应便好防止出现血液粘稠,致使血压下降,所以对降血压是有一定帮助的,高血压患者是经常使用丹参片实施治疗的。可以预防,因为血液粘稠引来的冠心病心绞痛以及外周血管脑水肿症状。
> 
> 
> 


#### 4. l2 欧几里得距离:l2norm


计算给定查询向量和文档向量之间的欧几里德距离。



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torch

def embeddings_doc(doc, tokenizer, model, max_length=300):
encoded_dict = tokenizer.encode_plus(
doc,
add_special_tokens=True,
max_length=max_length,
padding=‘max_length’,
truncation=True,
return_attention_mask=True,
return_tensors=‘pt’
)
input_id = encoded_dict[‘input_ids’]
attention_mask = encoded_dict[‘attention_mask’]

# 前向传播
with torch.no_grad():
    outputs = model(input_id, attention_mask=attention_mask)

# 提取最后一层的CLS向量作为文本表示
last_hidden_state = outputs.last_hidden_state
cls_embeddings = last_hidden_state[:, 0, :]
return cls_embeddings[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

def search_similar(index_name, query_text, tokenizer, model, es, top_k=3):
query_embedding = embeddings_doc(query_text, tokenizer, model)
print(query_embedding.tolist())
query = {
“query”: {
“script_score”: {
“query”: {“match_all”: {}},
“script”: {
“source”: “1 / (1 + l2norm(params.queryVector, doc[‘ask_vector’]))”,
“lang”: “painless”,
“params”: {
“queryVector”: query_embedding.tolist()
}
}
}
},
“size”: top_k
}
res = es.search(index=index_name, body=query)
hits = res[‘hits’][‘hits’]
similar_documents = []
for hit in hits:
similar_documents.append(hit[‘_source’])

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数大数据工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)
img

小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-YCqzJU9j-1712880249409)]
[外链图片转存中…(img-YBBiuODW-1712880249409)]
[外链图片转存中…(img-S7GTP7gg-1712880249409)]
[外链图片转存中…(img-Xa05156e-1712880249410)]
[外链图片转存中…(img-xNrlmMGt-1712880249410)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)
[外链图片转存中…(img-uvmLoTpn-1712880249410)]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/931767
推荐阅读
相关标签
  

闽ICP备14008679号