MinHash-LSH:如何解决医学大模型的大规模数据去重?

news2024/10/7 20:33:32

MinHash-LSH 最小哈希 + 局部敏感哈希:如何解决医学大模型的大规模数据去重?

    • 大模型的数据问题
    • MinHash-LSH 最小哈希 + 局部敏感哈希:大规模数据集去重优化
      • Jaccard相似度:用于比较样本集之间的相似性
      • 降维技术 Minhash
      • LSH – 局部敏感哈希
    • MinHash-LSH 多个开源数据集去重

 


大模型的数据问题

问题:训练医学大模型的数据规模真的很大,其中会夹杂很多重复数据。

临床数据:

  • 20 亿条文本数据

教材数据:

  • 1000+ 本指南
  • 7万+ 药品说明书
  • N 个科室疾病培训数据
  • N 本古籍、教材

开源数据:

  • 中文医学命名实体识别CMedEE

  • 中文医学文本实体关系抽取CMedIE

  • 临床术语标准化任务CHIP-CDN

  • 临床试验筛选标准短文本分类CHIP-CTC

  • 平安医疗科技疾病问答迁移学习CHIP-STS

  • 医疗搜索检索词意图分类KUAKE-QIC

  • 医疗搜索查询词—页面标题相关性KUAKE-QTR

  • 医疗搜索查询词—查询词相关性KUAKE-QQR

  • 中文医学命名实体识别CMedEE

  • 中文医学文本实体关系抽取CMedIE

  • 临床术语标准化任务CHIP-CDN

  • 临床试验筛选标准短文本分类CHIP-CTC

  • 平安医疗科技疾病问答迁移学习CHIP-STS

  • 医疗搜索检索词—意图分类KUAKE-QIC

  • 医疗搜索查询词—页面标题相关性KUAKE-QTR

  • 医疗搜索查询词—查询词相关性KUAKE-QQR

  • 医疗搜索查询词—相关性检索KUAKE-IR

  • 阴阳性实体判别CHIP-MDCFNPC

  • 对话实体抽取IMCS-V2-NER

  • 意图标签分类IMCS-V2-DAC

  • 智能诊疗对话症状识别IMCS-V2-SR

  • 诊疗报告生成IMCS-V2-MRG

  • 医疗对话生成MedDG

  • MedDialog-CN https://github.com/UCSD-AI4H/Medical-Dialogue-System

  • IMCS-V2 https://github.com/lemuria-wchen/imcs21

  • CHIP-MDCFNPC https://tianchi.aliyun.com/dataset/95414

  • MedDG https://tianchi.aliyun.com/dataset/95414

  • cMedQA2 https://github.com/zhangsheng93/cMedQA2

  • Toyhom https://github.com/Toyhom/Chinese-medical-dialogue-data

  • michaelwzhu/ChatMed-Consult michaelwzhu/ChatMed-Consult · Hugging Face

  • Huatuo-26M https://github.com/FreedomIntelligence/Huatuo-26M

  • Medical https://huggingface.co/datasets/shibing624/medical

  • 复旦DISC-MedLLM https://github.com/FudanDISC/DISC-MedLLM

  • DoctorGLM https://zhuanlan.zhihu.com/p/657058443

  • MedicalGPT https://zhuanlan.zhihu.com/p/657058443

  • ChatMed:https://zhuanlan.zhihu.com/p/657058443

  • MedQA-ChatGLM:https://zhuanlan.zhihu.com/p/657058443

  • 神农中医药大模型:https://zhuanlan.zhihu.com/p/657058443

  • 70B医学大模型:https://huggingface.co/datasets/epfl-llm/guidelines

  • 澳门理工caregpt:https://github.com/WangRongsheng/CareGPT

MinHash-LSH 最小哈希 + 局部敏感哈希:大规模数据集去重优化

怎么去重呢?

要用到一个炒鸡牛逼的算法:MinHash-LSH

谷歌、亚马逊等公司的许多核心功能都是 MinHash-LSH 实现的。

  • 解法:MinHash-LSH
  • 问题特征:能在大数据中,寻找特征向量相似又不完全相同的情况下,找出尽可能近的样本。
  • 应用场景:亚马逊根据相似度最高的买家的购买历史找到新的商品推荐、谷歌搜索字词与 Google 的索引互联网之间执行相似性搜索、Spotify根据用户音乐风格,寻找匹配的相似度

当有 30 亿级别的集合需要比较时,使用传统的全对全比较方法(即比较任意两个集合是否相似)将变得非常耗时,这种方法的时间复杂度是 O(n^2),随着集合数量的增加,所需的计算时间呈平方级增长。

在很多实际情况下,绝大多数的集合对之间都不相似,这意味着全对全比较中的大部分计算实际上是无用功。

如果能有一种方法能够快速地将可能相似的集合对筛选出来,只对这些潜在相似的集合对进行详细的相似度计算,那么就可以大幅度降低计算成本。

MinHash 和局部敏感哈希(LSH)就是这样一种解决方案:

  • MinHash 是一种哈希技术,可以用来有效地估计集合之间的Jaccard相似度

  • LSH 是用来将那些相似度高的集合哈希到相同的桶中的技术。

只有被哈希到同一个桶中的集合对才需要进行相似度比较,大大减少了比较的数量,从而降低了算法的整体时间复杂度。

时间复杂度从 平方量级 降低到 接近线性复杂度。

MinHash-LSH 的设计逻辑:

  • 一般的hash,原内容发生微小变化后,hash值的变化是无法预估的。
  • 字符串改一个字母后,整个字符串md5变得完全不一样,图片改一个像素后hash值也变得完全不一样。
  • 局部敏感hash的改进在于,原内容发生微小变化后,其hash值也只发生微小变化。
  • 从而满足原内容相近hash值也相近的良好性质。
  • 这种性质的好处在于,可以在hash空间进行近邻检索。

怎么实现这种逻辑呢?

  • 从对内容敏感的信息,变成,对位置敏感的哈希
  • 这种哈希算法,得到的哈希值(或者说指纹),在向量空间中的位置是“敏感”的
  • 两个指纹在向量空间中的相对位置是有意义的,近就是真的近,远就是真的远
  • 而不是如md5一样,在向量空间中的远近和实际含义的远近无关系

Jaccard相似度:用于比较样本集之间的相似性

Jaccard相似度的定义是两个集合交集大小与并集大小之比。

具体来说,如果有两个集合A和B,那么ta们之间的 Jaccard 相似度:

  • [ J ( A , B ) = ∣ A ∩ B ∣ ∣ A ∪ B ∣ ] [ J(A, B) = \frac{|A \cap B|}{|A \cup B|} ] [J(A,B)=ABAB]

∣ A ∩ B ∣ |A ∩ B| AB 表示集合A和集合B的交集中元素的数量。

∣ A ∪ B ∣ |A ∪ B| AB 表示集合A和集合B的并集中元素的数量。

举个列子,集合X = {a,b,c},Y = {q,a,b}。

那 Jac(X,Y) = 2 / 3 = 0.67。

X 和 Y 有 67% 的元素相同。

Jaccard相似度的值范围在0到1之间:

  • 0 表示没有共同元素,即两个集合完全不相似
  • 1 表示两个集合完全相同
  • 在0到1之间的值表示集合之间的部分相似性

Jaccard相似度越高,表示两个集合的相似度越大。

在数据处理中,我们可以使用 jieba 分词库,把一句话分词成各个元素后,计算相似度。

query1 = ["ta喜欢的水果有?"]                          # 分词前
query1 = ['ta', '喜欢', '的', '水果', '有', '?']      # 分词后

query2 = ["ta喜欢的坚果有?"]                          # 分词前
query2 = ['ta', '喜欢', '的', '坚果', '有', '?']      # 分词后

降维技术 Minhash

直接计算数据之间的相似度(Jaccard相似度)会非常耗时,每个集合里面的元素,俩俩比较。

如果大部分集合对之间的相似度都很低,进行俩俩比较会做很多无用功。

传统的方法需要对两个集合的每个元素进行一对一的比较,以确定ta们的相似性。

MinHash 算法通过为每个集合生成一个固定长度的标签(哈希函数产生签名),来代表集合的特征。

  • 原本复杂的集合相似性比较,简化为标签(MinHash值)的比较
  • 比较签名的成本,远低于比较完整的集合

这些签名保留了集合间相似度的信息,还能保持原始数据的相似性。

  • 如果两个集合很相似,Minhash 值也会很相似

但单个 MinHash 值可能无法准确地反映两个集合的相似性,可能是一个偶然的匹配。

在实际应用中,我们会使用数百或数千个哈希函数来增加估计的准确性。

如果大多数哈希函数产生的MinHash值都相同,我们可以有更高的信心认为两个集合是相似的。

  • 解法:MinHash
  • 问题特征:在高维空间中估计稀疏数据集合的相似性,特别是当直接计算成对相似度不可行时。如需要快速而精确地估计大型数据集中集合之间的Jaccard相似度。
  • 应用场景:文本处理中比较文档相似性,如新闻聚类、查重系统;生物信息学中比较基因组序列;推荐系统中评估用户间或物品间的相似性。

这里是为了应用,具体数学公式、概率证明,请猛击《原始论文》。

LSH – 局部敏感哈希

LSH 函数旨在将相似的值放入相同的存储桶中。

LSH 的核心思想是将相似的数据点映射到相同的“桶”(buckets)中,而不相似的点映射到不同的桶中。

这样,当需要找到一个数据点的最近邻时,可以仅在相同桶中的点之间进行搜索,而不是在整个数据集中搜索,大大降低了计算量。

LSH 是基于哈希的技术,其特点是保持局部相似性:相似的输入在哈希后应该产生相似或相同的哈希值。

与传统哈希函数不同,LSH 的目的不是为了避免冲突,而是为了让冲突更可能发生在相似的项之间。

LSH 的具体实现方式有很多,最常见的包括:

  1. MinHash LSH:适用于度量集合相似性(如Jaccard相似性)的LSH。MinHash 将每个集合转换成一个固定长度的签名,该签名是由多个最小哈希值组成的向量,这些最小哈希值由集合中的元素通过多个哈希函数计算得到。

  2. SimHash LSH:用于处理高维特征向量的文本或其他数据的相似性。SimHash 通过哈希函数将特征向量转换为一个固定长度的位串,这样,相似的数据点会产生相似的位串。

  3. Euclidean LSH:适用于欧几里得空间中的数据点。它使用超平面将空间划分成不同的区域,并将落在同一区域内的点映射到同一个桶中。

LSH 算法的详细步骤如下:

  1. 选择适合的 LSH 家族:根据数据的性质和相似性度量选择合适的 LSH 函数。

  2. 定义哈希表和哈希函数:创建多个哈希表,并为每个哈希表定义一个或多个 LSH 函数。

  3. 哈希和存储数据点:使用定义的哈希函数将数据点映射到各自的桶中。

  4. 查询过程:在查询最近邻时,首先计算查询点的哈希值,然后只在对应桶中的点集合中进行搜索,这样可以快速缩小搜寻范围。

LSH 的效率和精度受到哈希函数个数、哈希表数量和桶的大小等参数的影响。

在应用中,这些参数需要根据具体应用进行调整以达到最佳效果。

由于 LSH 是一种概率算法,允许少量的误报(false positives)和漏报(false negatives),但在实际应用中,这通常是可接受的,特别是在处理大规模数据集时,ta提供了显著的速度优势。

  • 解法:LSH(局部敏感哈希)
  • 问题特征:当数据量很大,使得对所有可能的数据对进行比较变得不可行时,需要一种方法能够高效地查找和查询近似最近邻
  • 应用场景:大规模图像或视频检索系统,寻找视觉上相似的内容;文本或文章数据库中寻找相似文档;音频或声音样本匹配;大型数据库中的快速相似项查找

MinHash-LSH 多个开源数据集去重

配置环境包:

pip install jieba datasketch  

MinHash-LSH 代码:

import jieba
import re  # 假设这里应该导入 re 而不是 ro
from datasketch import MinHash, MinHashLSH

query = "想人想得厉害的时候,也是淡淡的。像饿了很多日的旅人闻到炊烟,但知道不是自家的。"

sentences = ["想人想得厉害的时候,也是轻轻的。像漂泊很多日的旅人闻到炊烟,但知道不是返乡的。",
             "梦中梦见心上人,也是轻轻的。像漂泊良久的游子见到归帆,却明白并非返乡的。"]

regex = re.compile(",|。")

def split_word(sentence):
    global regex
    return [word for word in jieba.lcut(re.sub(regex, '', sentence)) if word.strip()]

query_lcut = split_word(query)
sentences_lcut = [split_word(sentence) for sentence in sentences]
print(query_lcut)
print(sentences_lcut)

'''
print(query_lcut):
['想人', '想', '得', '厉害', '的', '时候', '也', '是', '淡淡的', '像', '饿', '了', '很多', '日', '的', '旅人', '闻到', '炊烟', '但', '知道', '不是', '自家', '的']
[]

print(sentences_lcut):[
['想人', '想', '得', '厉害', '的', '时候', '也', '是', '轻轻', '的', '像', '漂泊', '很多', '日', '的', '旅人', '闻到', '炊烟', '但', '知道', '不是', '返乡', '的']
['梦中', '梦见', '心上人', ',', '也', '是', '轻轻', '的', '像', '漂泊', '良久', '的', '游子', '见到', '归帆', '却', '明白', '并非', '返乡', '的']
'''

threshold = 0.5   # 相似度 > 0.5
num_perm = 128
lsh = MinHashLSH(threshold=threshold, num_perm=num_perm)
for idx, sentence_lcut in enumerate(sentences_lcut):
    minhash = MinHash(num_perm=num_perm)
    minhash.update_batch([word.encode('utf-8') for word in sentence_lcut])
    lsh.insert("minhash_sentence_{}".format(idx+1), minhash)

print(list(lsh.keys))
# 输出:['minhash_sentence_1', 'minhash_sentence_2']

minhash_query = MinHash(num_perm=num_perm)
minhash_query.update_batch([word.encode('utf-8') for word in query_lcut])
simi_result = lsh.query(minhash_query)
print("Jaccard相似度 > {} 的句子有:{}".format(threshold, simi_result))
# 输出:Jaccard相似度 > 0.5 的句子有:['minhash_sentence_1']  
 
 
# 删除 minhash_sentence_1,从 LSH 中移除查询到的结果,需要对 simi_result 进行遍历
for key in simi_result:
    lsh.remove(key)

print(list(lsh.keys))
# 输出:['minhash_sentence_2']

去重多个开源文件所有数据:

import jieba
import re
from datasketch import MinHash, MinHashLSH

# 此函数用于分词
def split_word(sentence):
    regex = re.compile(",|。|?|!")
    return [word for word in jieba.lcut(re.sub(regex, '', sentence)) if word.strip()]

# 配置参数
threshold = 0.5   # 相似度阈值
num_perm = 128    # MinHash的排列次数

# 初始化LSH对象
lsh = MinHashLSH(threshold=threshold, num_perm=num_perm)

# 假设你有一个函数来获取多个开源文件下所有问答对
# def get_qa_pairs():
#     # 这里应该包含读取文件并返回所有问答回答的代码
#     return qa_pairs

# 读取所有问答回答对
qa_pairs = get_qa_pairs()

# 为每个问答回答创建MinHash并加入LSH
for idx, qa_pair in enumerate(qa_pairs):
    q, a = qa_pair                                   # 假设qa_pair是一个包含问题和答案的元组
    combined_text = q + " " + a                      # 可以根据需要将问题和答案合并或分别处理
    words = split_word(combined_text)
    minhash = MinHash(num_perm=num_perm)
    for word in words:
        minhash.update(word.encode('utf-8'))
    lsh.insert("qa_pair_{}".format(idx), minhash)

# 查询并去重
unique_qa_pairs = []
for idx, qa_pair in enumerate(qa_pairs):
    q, a = qa_pair
    combined_text = q + " " + a
    words = split_word(combined_text)
    minhash = MinHash(num_perm=num_perm)
    for word in words:
        minhash.update(word.encode('utf-8'))
    # 查询相似问答回答
    result = lsh.query(minhash)
    # 如果只有自己或没有其他相似项,则视为唯一
    if len(result) <= 1 or (len(result) == 2 and "qa_pair_{}".format(idx) in result):
        unique_qa_pairs.append(qa_pair)
        # 将此问答回答标记为唯一,可选步骤
        lsh.remove("qa_pair_{}".format(idx))

# 输出去重后的问答对
print(unique_qa_pairs)

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

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

相关文章

SCC-Tarjan算法,强连通分量算法,从dfs到Tarjan详解

文章目录 前言定义强连通强连通分量 Tarjan算法原理及实现概念引入搜索树有向边的分类强连通分量的根时间戳追溯值 算法原理从深搜到TarjanTarjan算法流程Tarjan算法代码实现 OJ练习&#xff1a; 前言 强连通分量是图论中的一个重要概念&#xff0c;它在许多领域都有广泛的应用…

Qt之使用QListView加载相册(富文本ToolTip)

一.效果 二.实现 #include "mainwindow.h" #include "ui_mainwindow.h"#include <QStandardItemModel> #include <QFont>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);QFont…

SourceTree 免登录跳过初始设置

用于Windows和Mac的免费Git客户端。 Sourcetree简化了如何与Git存储库进行交互&#xff0c;这样您就可以集中精力编写代码。通过Sourcetree的简单Git GUI可视化和管理存储库。 SourceTree 安装之后需要使用账号登陆以授权&#xff0c;以前是可以不登陆的&#xff0c;但是现在是…

基于ssm办公自动化管理系统论文

摘 要 随着计算机应用的普及、成熟&#xff0c;越来越多公司开始采用网上信息管理系统&#xff0c;网上信息管理系统的运行可以有效的提高企业管理效率。因此&#xff0c;为满足企业办公管理方面的需求&#xff0c;开发了办公自动化管理系统。 本文重点阐述了办公自动化管理系…

c语言:输出1~100的数据以10×10格式

一、题目 以10*10的格式&#xff0c;输出1-100。 如图&#xff1a; 二、思路分析 此题的难点&#xff1a; 1、1-9的要向前空一格&#xff1b; 2、100要向前进一格 三、代码截图【带注释】 四、源代码【带注释】 #include <stdio.h> int main() { //分成三个部分&am…

Axure的交互与情形,事件,动作

交互样式 交互样式是指当用户与原型进行交互时&#xff0c;元素所呈现出的视觉效果。在Axure中&#xff0c;可以通过设置交互样式来调整元素在交互过程中的外观&#xff0c;例如改变颜色、大小、位置等。 交互事件 交互事件是指在用户与原型进行交互时触发的动作。在Axure中&…

计算机图形学头歌合集(题集附解)

目录 CG1-v1.0-点和直线的绘制 第1关&#xff1a;OpenGL点的绘制 第2关&#xff1a;OpenGL简单图形绘制 第3关&#xff1a;OpenGL直线绘制 第4关&#xff1a;0<1直线绘制-dda算法<> 第5关&#xff1a;0<1直线绘制-中点算法<> 第6关&#xff1a;一般直线绘…

使用Log4j与log4j2配置mybatisplus打印sql日志

环境&#xff1a;项目非完全spring项目&#xff0c;没有spring的配置文件。执行sql时老是不打印sql语句。因此进行修改&#xff0c;过程比较坎坷&#xff0c;记录一下。 我尝试使用log4j和log4j2进行配置 最终把这两种全部配置记录上 Log4j配置 如果项目用的是log4j需要进行配置…

nodejs配置express服务器,运行自动打开浏览器

查看专栏目录 Network 灰鸽宝典专栏主要关注服务器的配置&#xff0c;前后端开发环境的配置&#xff0c;编辑器的配置&#xff0c;网络服务的配置&#xff0c;网络命令的应用与配置&#xff0c;windows常见问题的解决等。 文章目录 设置方法&#xff1a;1&#xff0c;安装nodej…

全国软件供应链安全产教融合共同体成立大会在武汉成功举办

为深入学习贯彻党的二十大精神&#xff0c;落实《关于深化现代职业教育体系建设改革的意见》等要求&#xff0c;探索职业教育产教融合创新发展新生态&#xff0c;培养软件供应链安全人才体系&#xff0c;推动教育链、人才链、产业链、创新链的协同发展&#xff0c;12月16日 &am…

Spring 6(二)【IOC原理】

前言 IOC 是Spring的两大核心概念之一&#xff0c;它是一种思想&#xff0c;需要极其熟练的掌握。 今日摘录&#xff1a; 低能无聊的人太多。说他们勤勉&#xff0c;不过是因困为不会合理分配时间&#xff1b;说他们积极&#xff0c;不过是逃避其他困难工作而已。即便说工作只…

20个CobaltStrike实战案例 +插件

案例 1&#xff1a;窃取 token&#xff0c;访问域控或者本地管理员 前提&#xff1a;1.cs 上线的主机要管理员权限 注意点&#xff1a;登录失败时一定要先恢复身份 方式一&#xff1a; Ps #查看进程 steal_token 2020(管理元权限运行的进程号) &#xff0c; shell dir \\dc\c…

UE5:Lumen 框架

1.Lumen渲染流程框架 2.Lumen基本概念 2.1 LumenCard & LumenMeshCards LumenMeshCards&#xff1a;一组带有方向性的模型简化代理&#xff0c;视模型复杂度不同可能包含6个及以上数量的LumenCard&#xff1b;用来提供光照采样的位置和方向。 2.2 LumenCardPage & Lu…

设备制造CRM:一文看懂设备制造行业CRM的作用和优势

设备制造行业客户需求多样化、服务链路长&#xff0c;企业在关注APS、EMS等工业软件之余还要以客户为中心&#xff0c;做好客户服务。设备制造行业CRM管理系统是企业管理客户关系的利器&#xff0c;设备制造行业CRM的作用有哪些&#xff1f;一文带您看懂。 设备制造行业需要解…

kitex快速入门

简介 kitex是字节跳动开源的一款基于 Go语言的rpc框架。 官网 github仓库 gitee地址 安装与使用 kitex具有一键生成的功能&#xff0c;能够一键生成rpc架构&#xff0c;使开发者只关注于逻辑的开发即可。自动生成的源码只需要简单的配置就可使用&#xff0c;十分方便。 安…

能在电脑同时控制苹果和安卓的软件,找到了!

开门见山&#xff0c;既能远程控制安卓手机又能控制iPhone或iPad的软件是AirDroid Cast。 AirDroid Cast是一款专业、强大且易于使用的投屏&控制工具。不仅可以将安卓手机&#xff08;安卓7.0及以上版本&#xff09;、iPhone、iPad的屏幕画面投射到电脑上&#xff0c;还支持…

RED影视级R3D文件变0字节加chkdsk恢复案例

随着千兆网络普及小型存储也开始越来越多&#xff0c;特别是在专业级影视领域&#xff0c;存储数据要的就是快速和稳定&#xff0c;所以小存储很适合专业级影视这个行业。下面我们来看一个36T的小存储恢复R3D文件的案例。 故障存储: 36T&#xff0c;Exfat文件系统 故障现象:…

【C++初阶】八、初识模板(泛型编程、函数模板、类模板)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【C初阶】七、内存管理 &#xff08;C/C内存分布、C内存管理方式、operator new / delete 函数、定位new表达式&#xff09; -CSDN博客 目录 一 . 泛型编程 二 . 函数模板 函数模板…

【C语言】数组(一维)详解,手把手教你,保姆级!!!

目录 数组的概念 数组的创建 数组的初始化 数组的类型 数组使用下标 数组的打印 数组的输入 数组的储存 总结 数组的概念 数组是⼀组相同类型元素的集合&#xff1b; 从这个概念中我们有3点拓展&#xff1a; 1&#xff0c;数组中存放的是1个或者多个数据&#xff0c;但…

【Linux】进程周边005之环境变量

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.环境变量是什么&#xff1…