bert+np.memap+faiss文本相似度匹配 topN

目录

任务

代码

结果说明


任务

使用 bert-base-chinese 预训练模型将文本数据向量化后,使用 np.memap 进行保存,再使用 faiss 进行相似度匹配出每个文本与它最相似的 topN

此篇文章使用了地址数据,目的是为了跑通这个流程,数据可以自己构建

模型下载:bert预训练模型下载-CSDN博客

np.memap :

是NumPy库中的一种内存映射文件(Memory-Mapped File)对象,它允许你将硬盘上的大文件以类似数组的方式访问和操作,而不需要一次性将整个文件加载到内存中。

当你创建一个numpy.memmap对象时,实际上是创建了一个与磁盘文件对应的虚拟数组。当读取或修改这个数组中的元素时,NumPy会自动在需要的时候从磁盘上读取或写入相应的数据块。这样做的好处在于:

  1. 节省内存:对于超过系统可用内存的大文件,可以通过内存映射文件进行处理。
  2. 高效性:由于操作系统对内存映射文件的支持,频繁的小规模I/O操作可以得到优化。

在NLP领域,内存映射文件常用于存储大量的文本向量化结果,如BERT嵌入向量等

faiss:

是由Facebook AI Research团队开发的一款开源库,专注于大规模相似性搜索和聚类问题。它特别适用于稠密向量的高效索引和检索,为高维向量空间中的近似最近邻(Approximate Nearest Neighbor, ANN)搜索提供了强大的支持。

主要特点:

  1. 高性能:Faiss在CPU和GPU上都具有出色的性能表现,能够处理十亿级别的向量数据集,并且提供了一系列优化过的索引结构和算法以适应不同的应用场景。

  2. 多种索引方法:包括基于树的索引、量化索引(如IVF、PQ等)、层次化索引以及基于图的索引方法,这些索引方式允许在精度与速度之间进行权衡。

  3. 内存和磁盘持久化:支持将索引保存到磁盘并在需要时加载,这对于大型或持久化应用至关重要。

  4. 多平台兼容:Faiss由C++编写,但提供了Python接口,同时也支持其他语言的绑定。

  5. 灵活的应用场景:广泛应用于图像搜索、推荐系统、信息检索、文本分类和聚类等多个领域,其中涉及的向量通常是通过深度学习模型生成的嵌入向量。

  6. 易于使用:API设计简洁明了,开发者可以快速地构建高效的相似度搜索系统。

代码

先对文本数据进行向量化,串行的,to_vector.py

import torch
import numpy as np
import pandas as pd
import time
from transformers import BertTokenizer, BertModelclass TextEmbedder():def __init__(self, model_name="../bert-base-chinese"):# self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 自己电脑跑不起来 gpuself.device = torch.device("cpu")self.tokenizer = BertTokenizer.from_pretrained(model_name)self.model = BertModel.from_pretrained(model_name).to(self.device)def embed_sentences(self, sentences):inputs = self.tokenizer(sentences, padding=True, truncation=True, return_tensors='pt').to(self.device)with torch.no_grad():embeddings = self.model(**inputs).last_hidden_state[:, 0, :].cpu().numpy()return embeddingsdef save_embeddings_to_memmap(self, sentences, output_file, dtype=np.float32):embeddings = self.embed_sentences(sentences)shape = embeddings.shapeembeddings_memmap = np.memmap(output_file, dtype=dtype, mode='w+', shape=shape)embeddings_memmap[:] = embeddings[:]del embeddings_memmap  # 关闭并确保数据已写入磁盘def read_data():data = pd.read_excel('../data/data.xlsx')return data['address'].to_list()def main():# text_data = ["这是第一个句子", "这是第二个句子", "这是第三个句子"]text_data = read_data()embedder = TextEmbedder()# 设置输出文件路径output_filepath = '../output/123sentence_embeddings.npy'# 将文本数据向量化并保存到内存映射文件embedder.save_embeddings_to_memmap(text_data, output_filepath)if __name__ == "__main__":start = time.time()main()end = time.time()print(end - start)

再向量化后会生成一个保存的向量文件,使用向量文件找出每个文本与它最相似的 topN,find_topN.py

import pandas as pd
import numpy as np
import faissdef search_top4_similarities(index_path, data):index = faiss.IndexFlatL2(768)  # 假设BERT输出维度是768embeddings_memmap = np.memmap(index_path, dtype=np.float32, mode='r')# 确保embeddings_memmap是二维数组,如有需要转换if len(embeddings_memmap.shape) == 1:embeddings_memmap = embeddings_memmap.reshape(-1, 768)index.add(embeddings_memmap)results = []for i, text_emb in enumerate(embeddings_memmap):D, I = index.search(np.expand_dims(text_emb, axis=0), 5)  # 查找前5个最近邻# top4_ids_with_similarity = {data.iloc[I[0][j]]['store_id']: D[0][j] for j in range(1, 5)}  # 获取对应的ID和距离(这里我们直接使用距离作为相似度的替代)similarities = 1 - D[0] / (2 * np.sqrt((text_emb**2).sum()))  # 转换为余弦相似度(范围在-1到1之间,这里取正值)top4_ids_with_similarity = {data.iloc[I[0][j]]['store_id']: similarities[j] for j in range(1, 5)}  # 获取对应的ID和余弦相似度results.append((data.iloc[i]['store_id'], top4_ids_with_similarity))return resultsdef main_search():data = pd.read_excel('../data/data.xlsx')similarities = search_top4_similarities('../output/sentence_embeddings.npy', data)# 输出结果similar_df = pd.DataFrame(similarities, columns=['id', 'top4'])similar_df.to_csv('../output/similarities.csv', index=False)# 执行搜索并保存结果
main_search()

结果说明

输出格式有两列如下:

id top4 id {id1:相似度, id2:相似度, id3:相似度, id4:相似度}

以上代码流程跑通目的达到了,以后有更长的文本内容就可以使用了

这里去核对结果,发现效果并不是很好,可能原因地理数据还是太短了,分词效果可能不一样

  1. BERT模型的局限性:尽管BERT是一个强大的预训练语言模型,但它在处理地址这类具有地理信息和特定结构的数据时可能不是最佳选择。因为BERT是在大量自然语言文本上预训练的,对于地址这种格式化的数据,它可能无法捕捉到地名之间精确的地理位置关系。

  2. 相似度计算方法:在上面的示例代码中,我们使用的是欧氏距离作为相似度的代理,对于文本向量而言,这可能不是最佳的选择,尤其是在BERT这样的Transformer模型输出的嵌入空间中,余弦相似度通常更适用于衡量文本向量间的相似性。

  3. 数据预处理:地址标准化是关键步骤,如果地址没有经过充分的预处理(如去掉无关词、统一行政区划名称等),那么即使是相似的地址也可能得到不同的向量化表示。

  4. 索引构建和搜索参数:Faiss库提供了多种索引方式,针对不同规模的数据集和检索需求,需要选择合适的索引结构以及设置合理的搜索参数以优化相似度搜索效果。

要改善结果相关性,可以尝试以下改进措施:

  • 使用专门为地址设计或调整过的NLP模型。
  • 在将地址输入BERT之前,确保对地址进行了标准化处理。
  • 使用余弦相似度代替欧氏距离来衡量两个向量的相似性。
  • 如果数据量允许,考虑使用更高级的索引结构,例如IVF或者HNSW,并调整其参数以获得更好的召回率和精度。

另外,对于地址匹配问题,有时候专门的地址解析和匹配算法会比通用的NLP模型更为有效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/673182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TP框架 之think-auth权限认证

一、安装think-auth composer require 5ini99/think-auth二、数据表 -- ---------------------------- -- think_auth_rule,规则表, -- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常…

SpringBoot:web开发

web开发demo:点击查看 LearnSpringBoot05Web 点击查看更多的SpringBoot教程 技术摘要 webjarsBootstrap模板引擎thymeleaf嵌入式Servlet容器注册web三大组件 一、webjars webjars官网 简介 简介翻译 WebJars 是打包到 JAR(Java Archive)…

ACK One Argo工作流:实现动态 Fan-out/Fan-in 任务编排

作者:庄宇 什么是 Fan-out Fan-in 在工作流编排过程中,为了加快大任务处理的效率,可以使用 Fan-out Fan-in 任务编排,将大任务分解成小任务,然后并行运行小任务,最后聚合结果。 由上图,可以使…

在 Docker 中启动 ROS2 里的 rivz2 和 rqt 出现错误的解决方法

1. 出现错误: 运行 ros2 run rivz2 rivz2 ,报错如下 : No protocol specified qt.qpa.xcb: could not connect to display :1 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was f…

Java Swing实现简易版项目代码统计

尝试用AI生成日常方便使用的代码程序 用文心一言生成的可用代码 (1)提示1 假如你是一个java程序员,请用java swing创建一个JFrame,显示一个JTextField显示路径,Jtextfield右侧添加一个JButton,下面添加一个JTextArea&#xff0c…

文档协作技术——Operational Transformations简单了解

OT是支持协作软件系统的一种广泛使用的技术。 OT通常使用副本文档储存,每个客户端都拥有对文档的副本。客户端在本地副本以无锁非堵塞方式操作,并将改变传递到其他客户端。当客户端收到其他客户端传播的改变之后,通过转换应用更改&#xff0…

【前端web入门第四天】03 显示模式+综合案例热词与banner效果

文章目录: 1. 显示模式 1.1 块级元素,行内元素,行内块元素 1.2 转换显示模式 综合案例 综合案例一 热词综合案例二 banner效果 1. 显示模式 什么是显示模式 标签(元素)的显示方式 标签的作用是什么? 布局网页的时候,根据标签的显示模式选择合适的标签摆放内容。…

揭秘备忘录模式:打造灵活高效的状态管理解决方案

备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不暴露对象内部状态的情况下捕获和恢复对象的内部状态。这种模式主要用于实现撤销操作。 在 Java 中,备忘录模式通常包括以下三个角色: 发起人(O…

vue3:25—其他API

目录 1、shallowRef和shallowReactive 2、readonly与shallowReadonly readonly shallowReadonly 3、toRaw和markRaw toRaw markRaw 4、customRef 1、shallowRef和shallowReactive shallowRef 1.作用:创建一个响应式数据,但只对顶层属性进行响应式处理。2…

Windows 安装 MySQL 最新最简教程

Windows 安装 MySQL 最新最简教程 官网地址 https://dev.mysql.com/downloads/mysql/下载 MySQL zip 文件 配置 MySQL1、解压文件 2、进入 bin 目录 搜索栏输入 cmd 回车进入命令行 C:\Users\zhong\Desktop\MySQL\mysql-8.3.0-winx64\mysql-8.3.0-winx64\bin 注意这里是你自己…

JUnit实践教程——Java的单元测试框架

前言 大家好,我是chowley,最近在学单元测试框架——JUnit,写个博客记录一下! 在软件开发中,单元测试是确保代码质量和稳定性的重要手段之一。JUnit作为Java领域最流行的单元测试框架,为开发人员提供了简单…

(2)(2.14) SPL Satellite Telemetry

文章目录 前言 1 本地 Wi-Fi(费用:30 美元以上,范围:室内) 2 蜂窝电话(费用:100 美元以上,范围:蜂窝电话覆盖区域) 3 手机卫星(费用&#xff…

IT行业顶级证书:助力职业生涯的制胜法宝

IT行业顶级证书:助力职业生涯的制胜法宝 在IT行业,拥有一系列高含金量的证书是事关职业生涯发展的关键。这些证书不仅是技能的象征,更是在激烈的市场竞争中脱颖而出的法宝。让我们一起揭晓在中国IT行业中,哪些证书是最具含金量的…

仰暮计划|“​爷爷说这些话的时候眼睛都红着,他那变形的脊柱和瘸拐的双腿都证明他曾为这个家付出了血汗拼尽了全力”

赴一场拾光之旅,集往年回忆碎片 爷爷生于1952年,今年已有七十一了,是河南焦作沁阳北金村的一位地道农民,劳苦一生,如今终于得以颐养天年。许是早年经历过于难忘,爷爷如今与我讲起仍是记忆犹新,…

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】 一、 产品简介二、 漏洞概述三、 影响范围四、 复现环境五、 漏洞复现手动复现小龙验证Goby验证 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工…

uniapp 本地存储的方式

1. uniapp 本地存储的方式 在uniapp开发中,本地存储是一个常见的需求。本地存储可以帮助我们在客户端保存和管理数据,以便在应用程序中进行持久化存储。本文将介绍uniapp中本地存储的几种方式,以及相关的代码示例。 1.1. 介绍 在移动应用开发…

瑞_力扣LeetCode_二叉树相关题

文章目录 说明题目 144. 二叉树的前序遍历题解 题目 94. 二叉树的中序遍历题解 题目 145. 二叉树的后序遍历题解 题目 105. 从前序与中序遍历序列构造二叉树题解 题目 106. 从中序与后序遍历序列构造二叉树题解 🙊 前言:本文章为瑞_系列专栏之《刷题》的…

【深度学习】Softmax实现手写数字识别

实训1:Softmax实现手写数字识别 相关知识点: numpy科学计算包,如向量化操作,广播机制等 1 任务目标 1.1 简介 本次案例中,你需要用python实现Softmax回归方法,用于MNIST手写数字数据集分类任务。你需要完成前向计算…

python将Word页面纸张方向设置为横向

通过python-docx的章节属性,就可以更改纸张方向、纸张尺寸。 import docx from docx.enum.section import WD_ORIENT from docx.shared import Cmdocument docx.Document() section document.sections[0]# 设置纸张大小为A4大小 section.page_width Cm(21) sect…

2023年全国职业院校技能大赛软件测试赛题第3套

2023年全国职业院校技能大赛 软件测试赛题第3套 赛项名称: 软件测试 英文名称: Software Testing 赛项编号: GZ034 归属产业: 电子与信息大类 …