所以现在我有一个非常简单的程序,它将获取一个句子,并在给定的书中找到语义最相似的句子,并打印出该句子以及接下来的几个句子。
import spacy
nlp = spacy.load('en_core_web_lg')
#load alice in wonderland
from gutenberg.acquire import load_etext
from gutenberg.cleanup import strip_headers
text = strip_headers(load_etext(11)).strip()
alice = nlp(text)
sentences = list(alice.sents)
mysent = nlp(unicode("example sentence, could be whatever"))
best_match = None
best_similarity_value = 0
for sent in sentences:
similarity = sent.similarity(mysent)
if similarity > best_similarity_value:
best_similarity_value = similarity
best_match = sent
print sentences[sentences.index(best_match):sentences.index(best_match)+10]
我想通过告诉 SpaCy 在执行此过程时忽略停用词来获得更好的结果,但我不知道执行此操作的最佳方法。就像我可以创建一个新的空白列表并将每个不是停用词的单词附加到列表中
for sentence in sentences:
for word in sentence:
if word.is_stop == 'False':
newlist.append(word)
但我必须使它比上面的代码更复杂,因为我必须保持原始句子列表的完整性(因为如果我想稍后打印出完整的句子,索引必须相同)。另外,如果我这样做,我将必须通过 SpaCy 运行这个新的列表列表才能使用 .similarity 方法。
我觉得必须有更好的方法来解决这个问题,并且我非常感谢任何指导。即使没有比将每个不间断单词附加到新列表更好的方法,我也会感谢您在创建列表列表方面的任何帮助,以便索引与原始“句子”变量相同。
非常感谢!
您需要做的是覆盖 spaCy 计算相似度的方式。
对于相似度计算,spaCy 首先通过对每个标记(token.vector 属性)的向量进行平均来计算每个文档的向量,然后通过执行以下操作来执行余弦相似度:
return np.dot(vector1, vector2) / (np.linalg.norm(vector1) * np.linalg.norm(vector2))
您必须对此进行一些调整,并且不要考虑停用词向量。
以下代码应该适合您:
import spacy
from spacy.lang.en import STOP_WORDS
import numpy as np
nlp = spacy.load('en_core_web_lg')
doc1 = nlp("This is a sentence")
doc2 = nlp("This is a baby")
def compute_similarity(doc1, doc2):
vector1 = np.zeros(300)
vector2 = np.zeros(300)
for token in doc1:
if (token.text not in STOP_WORDS):
vector1 = vector1 + token.vector
vector1 = np.divide(vector1, len(doc1))
for token in doc2:
if (token.text not in STOP_WORDS):
vector2 = vector2 + token.vector
vector2 = np.divide(vector2, len(doc2))
return np.dot(vector1, vector2) / (np.linalg.norm(vector1) * np.linalg.norm(vector2))
print(compute_similarity(doc1, doc2)))
希望能帮助到你!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)