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, 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模型更为有效。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DoWhy:Python 中的因果推断库

DoWhy:Python 中的因果推断库 DoWhy 是一个强大的 Python 库,用于因果推断和因果推断分析。本文将介绍 DoWhy 的基本概念、主要功能和使用方法,帮助读者了解如何利用该库进行因果推断,并解决因果关系的相关问题。 什么是DoWhy&…

AI-数学-高中-24-三角函数一般形式的各参数含义

原作者视频:三角函数】12三角函数一般形式的各参数含义(易)_哔哩哔哩_bilibili 1.函数中的A标识符:表示曲线中间平衡位置的振幅,值域为正负A:[-A,A]。 2.函数中的B标识符:决定曲线纵向上下平移…

python实现中国剩余定理

中国剩余定理又称孙子定理,是数论中一个重要定理。最早可见于我国的数学著作《孙子算经》卷下“物不知数”问题,原文如下: 有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即…

一步步建立一个C#项目(连续读取S7-1200PLC数据)

这篇博客作为C#的基础系列,和大家分享如何一步步建立一个C#项目完成对S7-1200PLC数据的连续读取。首先创建一个窗体应用。 1、窗体应用 2、配置存储位置 3、选择框架 拖拽一个Button,可以选择视图菜单---工具箱 4、工具箱 拖拽Lable控件和TextBook控件 5、拖拽控件 接下来…

Linux文件和目录管理

目录基础 Linux操作系统以目录的方式来组织和管理系统中的所有文件。所谓的目录,就是将所有文件的说明信息采用树状结构组织起来。每个目录节点之下会有文件和子目录。 所有一切都从 ‘根’ 开始,用 ‘/’ 代表, 并且延伸到子目录。 bin:B…

《MySQL 简易速速上手小册》第2章:数据库设计最佳实践(2024 最新版)

文章目录 2.1 规划高效的数据库架构2.1.1 基础知识2.1.2 重点案例2.1.3 拓展案例 2.2 数据类型和表设计2.2.1 基础知识2.2.2 重点案例2.2.3 拓展案例 2.3 索引设计原则2.3.1 基础知识2.3.2 重点案例2.3.3 拓展案例 2.1 规划高效的数据库架构 在开启我们的数据库设计之旅之前&a…

240207-3步设置VSCode插件Inline-Bookmarks自定义颜色及名称

Step 1: 插件安装 Step 2: 配置文件 "inline-bookmarks.expert.custom.styles": {"default": {"gutterIconColor": "#157EFB","overviewRulerColor": "rgba(21, 126, 251, 0.7)","light": {"fontW…

【C++从0到王者】第四十二站:类型转换

文章目录 一、 C语言中的类型转换1. C语言中的类型转换2.一个常见的坑 二、为什么C需要四种类型转换三、C强制类型转换1.static_cast2.reinterpret_cast3.const_cast4.dynamic_cast 四、RTTI 一、 C语言中的类型转换 1. C语言中的类型转换 在C语言中,如果赋值运算符…

MOS管防反接电路设计

电子元件大都是使用直流工作,电源线反接就有可能就会烧坏,那电路如何防反接?首当其冲我们想到的就是二极管了,运用其单向导通特性可有效防止电源反接而损坏电路,但是随之而来的问题是二极管存在PN节电压,通…

【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(下)

目录 1 -> 再谈构造函数1.1 -> 构造函数体赋值1.2 -> 初始化列表1.3 -> explicit关键字 2 -> static成员2.1 -> 概念2.2 -> 特性 3 -> 友元3.1 -> 友元函数3.2 -> 友元类 4 -> 内部类5 -> 匿名对象6 -> 拷贝对象时的一些编译器优化 1 -…

Three.js学习7:dat.GUI 参数控制

每个学 Three.js 的都被安利了 dat.GUI 吧? 我也不例外! 今天就来了学习下 dat.GUI,并记录下来自己的学习成果。 一、什么是 dat.GUI? dat.GUI 是一个轻量级的图形用户界面库(GUI 组件),使用这个库可以…

进程状态 | 僵尸进程 | 孤儿进程 | 前台后台进程 | 守护进程

文章目录 1.进程的三种基本状态2.Linux中进程状态查看2.1.进程检测脚本2.2.各种状态查看 3.孤儿进程4.前台、后台、守护进程 1.进程的三种基本状态 进程的在系统当中是走走停停的,「运行 - 暂停 - 运行」的活动规律;进程在活动期间的三种状态&#xff1…

还得是它!GPT4.0和MJ都搞定了!SD也快了!

之前给大家分享过一个国内的AI镜像平台——葫芦AI,目前接入了Midjourney和DALL3、GPT4.0和文心一言4.0。 前几天夜里1点多这个葫芦AI台平‬升级了GPT4接口和资料库,立试马‬用了‬一下,很‬不错。接口‬能力和官‬方差‬不多。后面能把Gpts和…

新增C++max函数的使用

在 C 中&#xff0c;max函数是标准库中的一个函数&#xff0c;用于返回两个或多个元素中的最大值。max函数的声明如下&#xff1a; cpp #include <algorithm>template<class T> const T& max(const T& a, const T& b);这个函数接受两个同类型的参数a…

部署一个在线OCR工具

效果 安装 1.拉取镜像 # 从 dockerhub pull docker pull mmmz/trwebocr:latest 2.运行容器 # 运行镜像 docker run -itd --rm -p 10058:8089 --name trwebocr mmmz/trwebocr:latest 使用 打开浏览器输入 http://192.168.168.110:10058/ 愉快滴使用吧

【开源】基于JAVA+Vue+SpringBoot的贫困地区人口信息管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 人口信息管理模块2.2 精准扶贫管理模块2.3 特殊群体管理模块2.4 案件信息管理模块2.5 物资补助模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 人口表3.2.2 扶贫表3.2.3 特殊群体表3.2.4 案件表3.2.5 物资补助表 四…

肯尼斯·里科《C和指针》第12章 使用结构和指针(2)双链表

12.3 双链表 单链表的替代方案就是双链表。在一个双链表中&#xff0c;每个节点都包含两个指针——指向前一个节点的指针和指向后一个节点的指针。这可以使我们以任何方向遍历双链表&#xff0c;甚至可以随意在双链表中访问。下面的图展示了一个双链表。 下面是节点类型的声明&…

为什么大模型需要向量数据库?

AIGC 时代万物都可以向量化&#xff0c;向量化是 LLM 大模型以及 Agent 应用的基础。 比如&#xff1a;爆火的 Google 大模型 Gemini 1.0 原生支持的多模态&#xff0c;在预训练的时候就是把文本、图片、音频、视频等多模态先进行 token 化&#xff0c;然后构建一维的“语言”…

Powershell Install 一键部署Openssl+certificate证书创建

前言 Openssl 是一个方便的实用程序,用于创建自签名证书。您可以在所有操作系统(如 Windows、MAC 和 Linux 版本)上使用 OpenSSL。 Windows openssl 下载 前提条件 开启wmi,配置网卡,参考 自签名证书 创建我们自己的根 CA 证书和 CA 私钥(我们自己充当 CA)创建服务器…

数据结构第九天(堆排序)

目录 前言 概述 源码&#xff1a; 主函数&#xff1a; 运行结果&#xff1a; 其他 前言 哈哈&#xff0c;这个堆排序算法很久之前就已经敲过一遍了&#xff0c;时间一久&#xff0c;思路有点淡忘。今天重新看过一遍之后&#xff0c;又亲自撸代码&#xff0c;幸运的是&am…