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

news2024/9/23 17:18:46

目录

任务

代码

结果说明


任务

使用 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, BertModel


class TextEmbedder():
    def __init__(self, model_name="../bert-base-chinese"):
        # self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 自己电脑跑不起来 gpu
        self.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 embeddings

    def save_embeddings_to_memmap(self, sentences, output_file, dtype=np.float32):
        embeddings = self.embed_sentences(sentences)
        shape = embeddings.shape
        embeddings_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 faiss


def search_top4_similarities(index_path, data):
    index = faiss.IndexFlatL2(768)  # 假设BERT输出维度是768
    embeddings_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 results


def 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.coloradmin.cn/o/1440517.html

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

相关文章

Mac使用AccessClient打开Linux堡垒机跳转闪退问题解决

登录公司的服务器需要使用到堡垒机,但是mac使用AccessClient登录会出现问题 最基础的AccessClient配置 AccessClient启动需要设置目录权限,可以直接设置为 权限 777 chmod 777 /Applications/AccessClient.app注: 如果不是这个路径,可以打开终端,将访达中…

uniapp设置不显示顶部返回按钮

一、pages文件中,在相应的页面中设置 "titleNView": {"autoBackButton": false} 二、对应的页面文件设置隐藏元素 document.querySelector(.uni-page-head-hd).style.display none

Tomcat组件架构与数据流

一、背景与简介 Tomcat我们都知道是一个开源的、实现了大部分Java EE、Servlet、JSP规范的Servlet容器, 允许我们将实现了Serlvet接口的Web程序war包进行部署运行。 但是你有对Tomcat做过细致的学习么? 我相信大部分同学和我一样,之前也是只会进行简单使用&#x…

RisingWave 中文用户文档上线,阅读更高效!

为满足广大中文社区用户、开发者及流处理技术爱好者的需求,RisingWave 用户文档中文社区版今天上线了! 中文版文档的推出,旨在为广大用户提供更便捷、高效的阅读体验,帮助大家深入理解并有效使用 RisingWave,发挥其更…

Python:流程控制

4.1 顺序结构 在任何编程语言中最常见的程序结构就是顺序结构。顺序结构就是程序从上到下一行行地执行,中间没有任何判断和跳转。 如果Python程序的多行代码之间没有任何流程控制,则程序总是从上往下依次执行,排在前面的代码先执行&#xf…

1897_野火FreeRTOS教程阅读笔记_链表

1897_野火FreeRTOS教程阅读笔记_链表 全部学习汇总: g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 之前我自己通过直接啃代码的方式对FreeRTOS也算是有了一点理解了,这次趁着些许闲暇翻看一下野火的FreeRTOS教程。一者算是一种复习;二者可能对自…

【数据结构】二叉树的顺序结构及链式结构

目录 1.树的概念及结构 1.1树的概念 1.2树的相关概念 ​编辑 1.3树的表示 1.4树在实际中的运用(表示文件系统的目录树结构) 2.二叉树概念及结构 2.1二叉树的概念 2.2现实中的二叉树 ​编辑 2.3特殊的二叉树 2.4二叉树的性质 2.5二叉树的存储结…

手把手教你设计接口自动化测试用例:提取接口信息并分析

随着市场需求的变化,大部分企业在招聘测试人员时,都会提出接口自动化测试的相关要求,为什么会这样呢? 目前,软件构架基本上都是前后端分离的,软件的主要功能由服务端提供。从整个软件测试市场来看&#xf…

政安晨:快速学会~机器学习的Pandas数据技能(三)(重命名与合并)

使用机器学习处理数据的第一步就得先理解它,咱们现在就帮助它们一起理解起来。 (本篇文章这次换一套数据集,数据文件可以在文章头部下载,并保存至您的虚拟环境的目录中) 不知道如何搭建环境的小伙伴请看我机器学习笔…

超九成飘红,银行成开年唯一逆势上涨板块

2024年开年以来,A股银行板块表现令人瞩目。 Choice数据显示,按照申万(2021,仅A股)分类,2024年开年以来,银行板块是唯一一个逆势上涨板块,平均涨幅为6.53%。 年内银行股近乎全线上涨…

【C语言期末】商品管理系统

本文资源:https://download.csdn.net/download/weixin_47040861/88820155 1.题目要求 商品管理系统 商品信息包括:包括编号、类别、名称、价格、折扣比例、生产时间 、存货数量等要求:1、信息首先保存在文件中,然后打开文件进行…

GPT4技术报告介绍

GPT4_Technical_Report_zh 我们创建了 GPT-4,这是 OpenAI 努力扩展深度学习的最新里程碑。GPT-4 是一个大型多模态模型(接受图像和文本输入,发出文本输出),虽然在许多现实世界场景中的能力不如人类,但在各…

Netty的序列化之MessagePack

目录 引入MessagePack依赖 实体类 服务端代码 客户端代码 执行结果 引入MessagePack依赖 <dependency><groupId>org.msgpack</groupId><artifactId>msgpack</artifactId><version>0.6.12</version></dependency> 实体类…

Stable Diffusion 模型下载:GhostMix(幽灵混合)

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 GhostMix 是绝对让你惊艳的模型&#xff0c;也是自己认为现在最强的2.5D模型。我认为模型的更新应该是基于现有的画面整体不大变的前提下&#xff0c;提高模型的成…

springboot167基于springboot的医院后台管理系统的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

大数据术语系列(1)——COW和MOR,我如何使用chatgpt通俗易懂地理解了hudi这两种表类型

从传统数据库到大数据的转变&#xff0c;首当其冲的是各种术语的理解。 所以我与chatgpt发生了一系列对话&#xff0c;以便于我能快速理解这些术语。 我先把汇总的结果放在前边&#xff0c;后边会一步步地来说明我是如何获取这些信息的。前边我也发过一些关于chatgpt提示词相…

图像处理入门:OpenCV的基础用法解析

图像处理入门&#xff1a;OpenCV的基础用法解析 引言OpenCV的初步了解深入理解OpenCV&#xff1a;计算机视觉的开源解决方案什么是OpenCV&#xff1f;OpenCV的主要功能1. 图像处理2. 图像分析3. 结构分析和形状描述4. 动态分析5. 三维重建6. 机器学习7. 目标检测 OpenCV的应用场…

Go 语言中如何大小端字节序?int 转 byte 是如何进行的?

嗨&#xff0c;大家好&#xff01;我是波罗学。 本文是系列文章 Go 技巧第十五篇&#xff0c;系列文章查看&#xff1a;Go 语言技巧。 我们先看这样一个问题&#xff1a;“Go 语言中&#xff0c;将 byte 转换为 int 时是否涉及字节序&#xff08;endianness&#xff09;&#x…

Verilog刷题笔记26

题目&#xff1a; Build a combinational circuit with 100 inputs, in[99:0]. There are 3 outputs: out_and: output of a 100-input AND gate. out_or: output of a 100-input OR gate. out_xor: output of a 100-input XOR gate. 解题&#xff1a; module top_module( …

springboot157基于springboot的线上辅导班系统的开发与设计

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…