是否可以使用自定义命名实体改善spaCy的相似性结果?



我发现spaCy的相似性在比较我的文档方面做得不错,使用开箱即用的"en_core_web_lg"。

我想在某些领域加强关系,并认为向模型添加自定义 NER 标签会有所帮助,但我之前和之后的结果显示没有任何改进,即使我已经能够创建自定义实体的测试集。

现在我想知道,我的理论是完全错误的,还是我只是在我的管道中遗漏了一些东西?

如果我错了,改善结果的最佳方法是什么? 似乎某种自定义标签应该会有所帮助。

以下是我到目前为止测试的示例:

import spacy
from spacy.pipeline import EntityRuler
from spacy.tokens import Doc
from spacy.gold import GoldParse
nlp = spacy.load("en_core_web_lg")
docA = nlp("Add fractions with like denominators.")
docB = nlp("What does one-third plus one-third equal?")
sim_before = docA.similarity(docB)
print(sim_before)

0.5949629181460099

^^ 不太寒酸,但我希望在这个例子中看到接近 0.85 的结果。
因此,我使用实体标尺并添加一些模式来尝试收紧关系:

ruler = EntityRuler(nlp)
patterns = [
{"label": "ADDITION", "pattern": "Add"},
{"label": "ADDITION", "pattern": "plus"},
{"label": "FRACTION", "pattern": "one-third"},
{"label": "FRACTION", "pattern": "fractions"},
{"label": "FRACTION", "pattern": "denominators"},
]
ruler.add_patterns(patterns)
nlp.add_pipe(ruler, before='ner')
print(nlp.pipe_names)

["标记器"、"解析器"、"entity_ruler"、"ner"]

添加GoldParse似乎很重要,所以我添加了以下内容并更新了NER:

doc1 = Doc(nlp.vocab, [u'What', u'does', u'one-third', u'plus', u'one-third', u'equal'])
gold1 = GoldParse(doc1, [u'0', u'0', u'U-FRACTION', u'U-ADDITION', u'U-FRACTION', u'O'])
doc2 = Doc(nlp.vocab, [u'Add', u'fractions', u'with', u'like', u'denominators'])
gold2 = GoldParse(doc2, [u'U-ADDITION', u'U-FRACTION', u'O', u'O', u'U-FRACTION'])
ner = nlp.get_pipe("ner")
losses = {}
optimizer = nlp.begin_training()
ner.update([doc1, doc2], [gold1, gold2], losses=losses, sgd=optimizer)

{'ner': 0.0}

您可以看到我的自定义实体正在工作,但测试结果显示零改进:

test1 = nlp("Add fractions with like denominators.")
test2 = nlp("What does one-third plus one-third equal?")
print([(ent.text, ent.label_) for ent in test1.ents])
print([(ent.text, ent.label_) for ent in test2.ents])
sim = test1.similarity(test2)
print(sim)

[("添加"、"加法"(, ("分数"、"分数"(, ("分母"、"分数"(][("三分之一"、"分数"(, ("加号"、"加法"(, ("三分之一", "分数"(]

0.5949629181460099

任何提示将不胜感激!

Doc.similarity只使用词向量,而不使用任何其他注释。从文档 API:

默认估计值是使用词向量平均值的余弦相似性。

我发现我的解决方案嵌套在本教程中:Python 中的文本分类 使用 spaCy,它使用 SciKit-Learn 的 CountVectorizer 为 spaCy 的文本数据生成 BoW 矩阵。

由于二元分类,我避免了情绪分析教程,因为我需要对多个类别的支持。 诀窍是在 LogisticRegression 线性模型上设置multi_class='auto',并在精度分数和精度召回上使用average='micro',因此我的所有文本数据(如实体(都被利用了:

classifier = LogisticRegression(solver='lbfgs', multi_class='auto')

和。。。

print("Logistic Regression Accuracy:",metrics.accuracy_score(y_test, predicted))
print("Logistic Regression Precision:",metrics.precision_score(y_test, predicted,average='micro'))
print("Logistic Regression Recall:",metrics.recall_score(y_test, predicted,average='micro'))

希望这有助于为某人节省一些时间!

最新更新