- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试将 Fast Word Mover 的距离库与 SpaCy 结合使用,对于 GitHub 中的相同示例
import spacy
import wmd
nlp = spacy.load('en_core_web_md')
nlp.add_pipe(wmd.WMD.SpacySimilarityHook(nlp), last=True)
doc1 = nlp("Politician speaks to the media in Illinois.")
doc2 = nlp("The president greets the press in Chicago.")
print(doc1.similarity(doc2))
结果是:
6.070106029510498
我不知道如何解释它,因为通常距离是标准化的(0 到 1)。在自述文件中,此结果不可用,因此我不确定我的结果是否错误或此测量的比例不同。
最佳答案
一个简短的回答:不要解释它。就像这样使用它:距离越小,句子越相似。对于几乎所有实际应用(例如 KNN),这就足够了。
现在长答案:单词移动距离(阅读 the paper )定义为“不间断”单词的最佳匹配对之间距离的加权平均值。所以如果你想把它归一化为 (0, 1),你需要用这个最好的总和除以它的最坏情况。
问题是在 spacy
中词向量没有标准化(通过打印 [sum(t.vector**2) for t in doc1]
检查)。因此,它们之间的最大距离是无限的。如果你对它们进行规范化,新的 WMD 将不会等同于原始的 WMD(即它会以不同的方式对文本对进行排序)。因此,没有明显的方法可以标准化您演示的原始 spacy-WMD 距离。
现在让我们假设词向量是单位归一化的。如果是这样,那么两个单词之间的最大距离就是一个单位球体的直径(即2)。而很多2的最大加权平均还是2。所以需要将文本之间的距离除以2,使其完全归一化。
您可以通过继承您使用的类,将词向量归一化构建到 WMD 计算中:
import wmd
import numpy
import libwmdrelax
class NormalizedWMDHook(wmd.WMD.SpacySimilarityHook):
def compute_similarity(self, doc1, doc2):
"""
Calculates the similarity between two spaCy documents. Extracts the
nBOW from them and evaluates the WMD.
:return: The calculated similarity.
:rtype: float.
"""
doc1 = self._convert_document(doc1)
doc2 = self._convert_document(doc2)
vocabulary = {
w: i for i, w in enumerate(sorted(set(doc1).union(doc2)))}
w1 = self._generate_weights(doc1, vocabulary)
w2 = self._generate_weights(doc2, vocabulary)
evec = numpy.zeros((len(vocabulary), self.nlp.vocab.vectors_length),
dtype=numpy.float32)
for w, i in vocabulary.items():
v = self.nlp.vocab[w].vector # MODIFIED
evec[i] = v / (sum(v**2)**0.5) # MODIFIED
evec_sqr = (evec * evec).sum(axis=1)
dists = evec_sqr - 2 * evec.dot(evec.T) + evec_sqr[:, numpy.newaxis]
dists[dists < 0] = 0
dists = numpy.sqrt(dists)
return libwmdrelax.emd(w1, w2, dists) / 2 # MODIFIED
现在您可以确定您的距离已正确归一化:
import spacy
nlp = spacy.load('en_core_web_md')
nlp.add_pipe(NormalizedWMDHook(nlp), last=True)
doc1 = nlp("Politician speaks to the media in Illinois.")
doc2 = nlp("The president greets the press in Chicago.")
print(doc1.similarity(doc2))
print(doc1.similarity(doc1))
print(doc1.similarity(nlp("President speaks to the media in Illinois.")))
print(doc1.similarity(nlp("some irrelevant bullshit")))
print(doc1.similarity(nlp("JDL")))
现在的结果是
0.469503253698349
0.0
0.12690649926662445
0.6037049889564514
0.7507566213607788
附言你可以看到,即使在两个非常不相关的文本之间,这个归一化距离也远小于 1。这是因为实际上词向量并没有覆盖整个单位球体——相反,它们中的大部分都聚集在它上面的几个“大陆”上。因此,即使是非常不同的文本之间的距离通常也小于 1。
关于python - Word Mover 距离与 SpaCy 的非标准化结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56822056/
我有一段文本和索引条目,其中一些指示出现在文本中的重要多词表达 (MWE)(例如生物学文本的“海绵骨”)。我想使用这些条目在 spaCy 中构建自定义匹配器,以便我可以识别文本中出现的 MWE。一个附
我想在 Spacy 中使用德语 lemmatizer,但我对结果感到非常惊讶: import spacy nlp = spacy.load("de_dep_news_trf") [token.lemm
要将我的句子拆分为标记,我正在执行以下操作,这很慢 import spacy nlp = spacy.load("en_core_web_lg") text = "This is a test.
我已经使用空间很长一段时间了,我真的很喜欢这种置换 有没有一种方法可以让我们在网页中从我的数据集中提供多个文本,如一个小箭头,以重定向到下一条记录并标记实体。 我使用的代码如下。 def valida
我有变量 trainData它具有以下简化格式。 [ ('Paragraph_A', {"entities": [(15, 26, 'DiseaseClass'), (443, 449, 'Disea
我正在尝试测试在另一台计算机上运行的模型,但是当我尝试将其导入我的笔记本时,出现以下错误:ModuleNotFoundError:没有名为“spacy.pipeline.pipes”的模块; 'spa
我正在尝试测试在另一台计算机上运行的模型,但是当我尝试将其导入我的笔记本时,出现以下错误:ModuleNotFoundError:没有名为“spacy.pipeline.pipes”的模块; 'spa
当处理数百万文档并将它们保存为空间文档以供以后使用(更多处理、可视化、提取特征)时,一种明显的扩展解决方案是并行/分布式处理。这意味着每个并行进程都将拥有自己的 Vocab,这些 Vocab 可能会随
我正在使用 Spacy 大型模型,但它错误地使用与我的领域无关的类别标记实体,例如“艺术作品”可能导致它无法识别本应属于组织的内容。 是否可以限制 NER 仅返回人员、位置和组织? 最佳答案 简答:
我正在像这样使用 SpaCy 创建一个短语匹配器: import spacy from spacy.matcher import PhraseMatcher nlp = spacy.load("en"
我正在尝试使用 spaCy Matcher 工作获得以下简单示例: import en_core_web_sm from spacy.matcher import Matcher nlp = en_c
它没有出现在 pip list zeke$ pip list | grep spacy spacy (1.7.3) 如何获取模型名称? 我试过了,还是不行 echo "spaCy model:" py
我在 "Training an additional entity type" 中有新 NER 类型的训练数据spaCy 文档的部分。 TRAIN_DATA = [ ("Horses are
给定一个 token ,它是具有多个 token 的命名实体的一部分,是否有直接方法来获取该实体的跨度? 例如,考虑这个有两个词命名实体的句子: >>> doc = nlp("This year wa
如何限制 Spacy 使用的 CPU 数量? 我想从大量句子中提取词性和命名实体。由于 RAM 的限制,我首先使用 Python NLTK 将我的文档解析为句子。然后我遍历我的句子并使用 nlp.pi
显然 for doc in nlp.pipe(sequence) 比运行 for el in order: doc = nlp(el) .. 我遇到的问题是我的序列实际上是一个元组序列,其中包含用于将
显然 for doc in nlp.pipe(sequence) 比运行 for el in order: doc = nlp(el) .. 我遇到的问题是我的序列实际上是一个元组序列,其中包含用于将
我已经下载了 spaCy,但每次尝试 nlp = spacy.load("en_core_web_lg") 命令时,我都会收到此错误: OSError:[E050] 找不到模型“en_core_web
到目前为止,我一直在使用 spacy 2.3.1,并为我的自定义语言类(class)训练并保存了几个管道。但是现在使用 spacy 3.0 和 spacy.load('model-path') 我遇到
我安装了 spacy 使用 python3 install spacy 并使用下载了两个英文模型 python3 -m spacy download en 和 python3 -m spacy dow
我是一名优秀的程序员,十分优秀!