如何使用 BERT 找到与向量最接近的单词

2024-01-31

我正在尝试使用 BERT 获取给定单词嵌入的文本表示(或最接近的单词)。基本上我试图获得与 gensim 类似的功能:

>>> your_word_vector = array([-0.00449447, -0.00310097, 0.02421786, ...], dtype=float32)
>>> model.most_similar(positive=[your_word_vector], topn=1))

到目前为止,我已经能够使用生成上下文词嵌入bert 即服务 https://github.com/hanxiao/bert-as-service#getting-elmo-like-contextual-word-embedding但无法弄清楚如何获得与此嵌入最接近的单词。我已经使用了预训练的bert模型(uncased_L-12_H-768_A-12)并且没有进行任何微调。


TL;DR

金特里奇的回答 https://stackoverflow.com/a/59874553/6498293我实现了一个上下文感知的最近邻搜索器。完整的代码可以在我的Github要点 https://gist.github.com/avidale/c6b19687d333655da483421880441950

它需要一个类似 BERT 的模型(我使用bert 嵌入 https://pypi.org/project/bert-embedding/)和一个句子语料库(我从here https://wortschatz.uni-leipzig.de/en/download/),处理每个句子,并将上下文标记嵌入存储在可有效搜索的数据结构中(我使用KDTree https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html,但请随意选择 FAISS 或 HNSW 或其他)。

Examples

模型构建如下:

# preparing the model
storage = ContextNeighborStorage(sentences=all_sentences, model=bert)
storage.process_sentences()
storage.build_search_index()

然后可以查询上下文中最相似的单词,例如

# querying the model
distances, neighbors, contexts = storage.query(
    query_sent='It is a power bank.', query_word='bank', k=5)

在此示例中,最近的邻居将是单词“bank“在句子中”最后,还有第二个版本的 Duo,配备 2000mAH 电源bank,翻转动力世界。".

但是,如果我们在另一个上下文中查找同一个单词,例如

distances, neighbors, contexts = storage.query(
    query_sent='It is an investment bank.', query_word='bank', k=5)

那么最近的邻居将在句子中“The bank2017 年 12 月 31 日的财务数据也被授予 5 星高级 Bauer 评级。"

如果我们不想检索单词“bank”或其派生词,我们可以将它们过滤掉

distances, neighbors, contexts = storage.query(
     query_sent='It is an investment bank.', query_word='bank', k=5, filter_same_word=True)

那么最近的邻居将是单词“finance“在句子中”卡哈尔是德勤英国副主席兼咨询公司主席Finance从 2014 年开始负责业务(之前从 2005 年开始领导该业务)。".

在NER中的应用

这种方法最酷的应用之一是可解释的命名实体识别。我们可以用 IOB 标记的示例填充搜索索引,然后使用检索到的示例来推断查询词的正确标签。

例如,“的最近邻居贝索斯宣布推出两日送达服务,AmazonPrime 的全球订户数量已超过 1 亿。" is "扩展的第三方集成包括AmazonAlexa、Google Assistant 和 IFTTT。".

但对于 ”大西洋有足够的波浪和潮汐能来承载大部分Amazon的沉积物出海,因此河流并没有形成真正的三角洲“最近的邻居是”而且,今年我们的故事是从Brazil的伊瓜苏瀑布到亚特兰大的养鸡场".

因此,如果这些邻居被标记,我们可以推断在第一个上下文中“亚马逊”是一个组织,但在第二个上下文中它是一个位置。

The code

这是完成这项工作的类:

import numpy as np
from sklearn.neighbors import KDTree
from tqdm.auto import tqdm


class ContextNeighborStorage:
    def __init__(self, sentences, model):
        self.sentences = sentences
        self.model = model

    def process_sentences(self):
        result = self.model(self.sentences)

        self.sentence_ids = []
        self.token_ids = []
        self.all_tokens = []
        all_embeddings = []
        for i, (toks, embs) in enumerate(tqdm(result)):
            for j, (tok, emb) in enumerate(zip(toks, embs)):
                self.sentence_ids.append(i)
                self.token_ids.append(j)
                self.all_tokens.append(tok)
                all_embeddings.append(emb)
        all_embeddings = np.stack(all_embeddings)
        # we normalize embeddings, so that euclidian distance is equivalent to cosine distance
        self.normed_embeddings = (all_embeddings.T / (all_embeddings**2).sum(axis=1) ** 0.5).T

    def build_search_index(self):
        # this takes some time
        self.indexer = KDTree(self.normed_embeddings)

    def query(self, query_sent, query_word, k=10, filter_same_word=False):
        toks, embs = self.model([query_sent])[0]

        found = False
        for tok, emb in zip(toks, embs):
            if tok == query_word:
                found = True
                break
        if not found:
            raise ValueError('The query word {} is not a single token in sentence {}'.format(query_word, toks))
        emb = emb / sum(emb**2)**0.5

        if filter_same_word:
            initial_k = max(k, 100)
        else:
            initial_k = k
        di, idx = self.indexer.query(emb.reshape(1, -1), k=initial_k)
        distances = []
        neighbors = []
        contexts = []
        for i, index in enumerate(idx.ravel()):
            token = self.all_tokens[index]
            if filter_same_word and (query_word in token or token in query_word):
                continue
            distances.append(di.ravel()[i])
            neighbors.append(token)
            contexts.append(self.sentences[self.sentence_ids[index]])
            if len(distances) == k:
                break
        return distances, neighbors, contexts
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 BERT 找到与向量最接近的单词 的相关文章

  • 使用 NLTK python 对使用示例数据或 Web 服务的句子进行情感分析?

    我正在着手一个用于情感分析的 NLP 项目 我已经成功安装了Python的NLTK 看起来是一个很棒的软件 但是 我无法理解如何使用它来完成我的任务 这是我的任务 我从一长条数据开始 假设来自他们的网络服务的数百条关于英国大选主题的推文 我
  • 我应该如何使用 scikit learn 对以下列表进行矢量化?

    我想用 scikit 进行矢量化学习一个有列表的列表 我转到有训练文本的路径 我阅读了它们 然后我得到如下内容 corpus this is spam SPAM this is ham HAM this is nothing NOTHING
  • Python 3 和 NLTK 与 WordNet 2.1 - 这可能吗?

    我将 Python 3 和 NLTK 3 0 0 与 WordNet 3 0 结合使用 我想用该数据 semval2007 https github com alvations pywsd tree master pywsd data se
  • word2vec gensim 多种语言

    这个问题完全超出了我的想象 我正在使用 gensim 训练 Word2Vec 模型 我提供了多种语言的数据 即英语和印地语 当我试图找到最接近 人 的词时 我得到的是 model wv most similar positive man O
  • 如何使用 python 中的 spacy 库将句子转换为问题 [请参阅下面的我的代码进行更正]

    我需要使用 python 中的 spacy 将任何句子转换为问题 我下面的代码太长了 我需要做更多的工作才能将任何句子完成为问题格式 现在在这段代码中我根据以下条件制定条件是形式 需要形式 有形式 做形式通过检查过去时和现在时 输入 尼娜拉
  • IOB 准确度和精密度之间的差异

    我正在使用命名实体识别和分块器对 NLTK 进行一些工作 我使用重新训练了分类器nltk chunk named entity py为此 我采取了以下措施 ChunkParse score IOB Accuracy 96 5 Precisi
  • scikit加权f1分数计算及使用

    我有一个关于weightedsklearn metrics f1 score 中的平均值 sklearn metrics f1 score y true y pred labels None pos label 1 average weig
  • Spacy 中的自定义句子分割

    I want spaCy使用我提供的句子分割边界而不是它自己的处理 例如 get sentences Bob meets Alice SentBoundary They play together gt Bob meets Alice Th
  • 语音识别中如何处理同音词?

    对于那些不熟悉什么是同音字 https en wikipedia org wiki Homophone是的 我提供以下示例 我们的 是 嗨和高 到 太 二 在使用时语音API https developer apple com docume
  • 如何训练斯坦福 NLP 情感分析工具

    地狱大家 我正在使用斯坦福核心 NLP 包 我的目标是对推文直播进行情感分析 按原样使用情感分析工具对文本 态度 的分析非常差 许多积极因素被标记为中性 许多消极因素被评为积极 我已经在文本文件中获取了超过一百万条推文 但我不知道如何实际获
  • python中的语音识别持续时间设置问题

    我有一个 Wav 格式的音频文件 我想转录 我的代码是 import speech recognition as sr harvard sr AudioFile speech file wav with harvard as source
  • SpaCy 模型“en_core_web_sm”的词汇量大小

    我尝试在 SpaCy 小模型中查看词汇量 model name en core web sm nlpp spacy load model name len list nlpp vocab strings 只给了我 1185 个单词 我也在同
  • ANEW 字典可以用于 Quanteda 中的情感分析吗?

    我正在尝试找到一种方法来实施英语单词情感规范 荷兰语 以便使用 Quanteda 进行纵向情感分析 我最终想要的是每年的 平均情绪 以显示任何纵向趋势 在数据集中 所有单词均由 64 名编码员按照 7 分李克特量表在四个类别上进行评分 这提
  • 如何对德语文本进行词形还原?

    我有一篇德语文本 我想对其应用词形还原 如果不可能进行词形还原 那么我也可以接受词干提取 Data 这是我的德语文本 mails Hallo Ich spielte am fr hen Morgen und ging dann zu ein
  • 快速NLTK解析成语法树

    我正在尝试将数百个句子解析为语法树 我需要快速完成 问题是如果我使用 NLTK 那么我需要定义一个语法 而我不知道我只知道它会是英语 我尝试使用this https github com emilmont pyStatParser统计解析器
  • 无效参数:indices[0,0] = -4 不在 [0, 40405) 中

    我有一个模型可以处理一些数据 我在数据集中添加了一些标记化的单词数据 为简洁起见有些被截断 vocab size len tokenizer word index 1 comment texts df comment text values
  • SpaCy 中的自定义句子边界检测

    我正在尝试在 spaCy 中编写一个自定义句子分段器 它将整个文档作为单个句子返回 我编写了一个自定义管道组件 它使用以下代码来执行此操作here https github com explosion spaCy issues 1850 但
  • 如何在Python中使用多处理来加速循环执行

    我有两个清单 列表 A 包含 500 个单词 列表 B 包含 10000 个单词 我正在尝试为列表 A 找到与 B 相关的相似单词 我正在使用 Spacy 的相似函数 我面临的问题是计算需要很长时间 我是多处理使用的新手 因此请求帮助 如何
  • 缩短文本并仅保留重要句子

    德国网站 nandoo net 提供了缩短新闻文章的可能性 如果使用滑块更改百分比值 文本会发生变化并且某些句子会被遗漏 您可以在这里看到它的实际效果 http www nandoo net read article 299925 http
  • 如何提取句子中的主语及其各自的从属短语?

    我正在尝试在句子中进行主题提取 以便我能够根据主题获得情感 我在用nltk在 python2 7 中用于此目的 以下面的句子为例 Donald Trump is the worst president of USA but Hillary

随机推荐

  • 给定一个双调数组和数组中的元素 x,在 2log(n) 时间内找到 x 的索引

    首先 这个问题的双调数组被定义为对于某些索引K在长度数组中N where 0 lt K lt N 10到K是单调递增的整数序列 K到N 1是单调递减的整数序列 例子 1 3 4 6 9 14 11 7 2 4 9 它从 1 单调增加到 14
  • 如何查找 MySQL 表中的所有大写字符串?

    我最初认为这是微不足道的 然后认为 二进制 可以做到这一点 我现在不确定 Name John MARY Kin TED 我只想查询 MARY 和 TED 它们都是大写的 我该如何查询这个 如果您的排序规则不区分大小写 那么您需要使用BINA
  • Love2d和Lua中的继承

    我有一个包含这组值和函数的类 require class entity class new function entity new self x 100 self y 100 self width 32 self height 32 sel
  • 表单提交和Ajax同时使用onsubmit?

    如果之前有人问过这个问题 我很抱歉 但我需要通过表单提交和单击提交时触发的 ajax 调用来发送表单数据 原因是因为用户被重定向 并且我想预先将 det 表单数据存储到我的数据库中 所以我尝试使用表单 onsubmit 和 fire 提交表
  • ASP.NET 中

    我有一个在 asp net 框架上使用 SVG 坐标的网页 通过尝试错误 如果我取出大部分标签 我不会收到错误 但如果所有标签都在我收到以下错误 Compiler Error Message CS8095 Length of String
  • Asp.Net - 检测到页面上没有 javascript? (已更名标题)

    我有一个页面 在 TabContainer 中显示其所有内容 但如果浏览器上禁用了 javascript 它只会显示一个空白页面 我可以添加一个
  • 当 sed 在 mingw 中就地编辑时权限被拒绝

    我正在使用 mingw sed i s a b test txt sed preserving permissions for sed003480 Permission denied 我可以触摸 rm当前目录中的文件 这是由 Windows
  • ios 7 UiView 框架问题

    我在 iOS6 和 iOS7 中运行相同的应用程序 其中有导航栏 它在 iOS6 上运行良好 但在 iOS7 中 所有视图都有点向上 就像根本没有考虑导航栏一样 我尝试更改模拟指标选项中的顶栏属性 但它不起作用 在 iOS6 中 它从导航栏
  • 在 POST/batches 请求中使用现有的 SparkSession

    我正在尝试使用Livy远程提交多个Spark jobs 假设我想执行以下操作spark submit远程任务 包含所有选项 spark submit class com company drivers JumboBatchPipelineD
  • Serilog - 无法根据属性记录到多个文件

    您好 我正在尝试使用以下命令在一个文件中记录一些消息 在另一个文件中记录其他消息Serilog 我尝试过以下配置 Log Logger new LoggerConfiguration WriteTo Map type audit name
  • ndb async 是否保证在应用程序请求完成后执行?

    我正在使用 ndb 编写一个分析模型 该模型根据应用程序请求记录一些数据 每个请求通过ndb put async调用一个ndb请求来记录数据 而客户端不关心结果 本质上 我不希望应用程序请求等待保存统计数据以进行分析 然而 我对官方文档的解
  • Android设置壁纸出错了

    所以我很久以前就在开发壁纸更换器并发布了它 一段时间后 我开始收到壁纸尺寸调整不正确的评论 我还尝试了不同尺寸的鸸鹋 它们是正确的 我正确地缩放位图等 但不知何故 android倾向于将壁纸重新缩放得更大 有办法避免吗 我的代码 Displ
  • 与 VB.NET 中的 Array() 等效吗?

    在 VB6 中你可以这样做 Dim a As Variant a Array 1 2 3 你能在 VB NET 中使用特定类型做类似的事情吗 Dim a As Integer a Array 1 2 3 Dim a As Integer N
  • 命名空间“std”中没有名为“unary_function”的模板;您的意思是“__unary_function”吗?

    刚刚将我的 Xcode 升级到 15 0 突然它开始在 RCT Folly 中出现以下错误 No template named unary function in namespace std did you mean unary funct
  • 在运行时转储 gcov 数据

    我正在使用 gcov 收集我正在从事的 C 项目的代码覆盖率数据 据我所知 一旦程序完成后退出 gcov 就会转储代码覆盖率数据 如何收集长时间运行的进程的 gcov 数据 比如说 我的程序是一个操作系统的内核 该操作系统在永不关闭的服务器
  • iOS:Xcode 中的 ImageMagick 编译器警告

    我在 iOS 项目中使用 ImageMagick 但是该库已经过时 因为以前的开发人员使用了源代码 我使用的是 Xcode 6 3 2 我想使用 Cocoapods 将 ImageMagick 集成到项目中 而不是复制源文件 然而 当我将
  • SDL_ttf找不到“SDL.h”,但main.cpp可以

    我正在编写一个 make 文件来编译一个非常简单的 SDL2 程序 到目前为止 它编译 SDL2 得很好 现在我正在编译扩展框架 SDL2 image 和 SDL ttf 看起来MAKE正确地找到了SDL ttf h 但是SDL ttf h
  • 使用 GSON 将 JSON 转换为 Java 对象时如何覆盖 Java 映射?

    我有一个 JSON 字符串 如下所示 status status date 01 10 2019 alerts labels field1 value1 field2 value2 field3 value3 field100 value1
  • Sphinx Note Block 在代码块下的列表中?

    我有一个问题 如果我想将注释块放在代码块下的列表中 它就会包含在代码块中 如果我取消缩进 列表编号会在注释后重新开始 所以基本上 我需要的是 Fixed list example First do spam Then do eggs som
  • 如何使用 BERT 找到与向量最接近的单词

    我正在尝试使用 BERT 获取给定单词嵌入的文本表示 或最接近的单词 基本上我试图获得与 gensim 类似的功能 gt gt gt your word vector array 0 00449447 0 00310097 0 024217