使用spaCy替换"主题"一句话

时间:2017-06-05 18:13:36

标签: python spacy

因此,作为一个思想实验,我在python中编写了一个函数,该函数使用spaCy来查找新闻文章的主题,然后将其替换为选择的名词。问题是,它并没有完全正常工作,我希望它可以改进。我不太了解spaCy,文档有点难以理解。

首先,代码:

doc=nlp(thetitle)
for text in doc:
    #subject would be
    if text.dep_ == "nsubj":
        subject = text.orth_
    #iobj for indirect object
    if text.dep_ == "iobj":
        indirect_object = text.orth_
        #dobj for direct object
    if text.dep_ == "dobj":
        direct_object = text.orth_
try:
    subject
except NameError:
    if not thetitle: #if empty title
        thetitle = "cat"
        subject = "cat"
    else: #if unknown subject
        try: #do we have a direct object?
            direct_object
        except NameError:
            try: #do we have an indirect object?
                indirect_object
            except NameError: #still no??
                subject = random.choice(thetitle.split())
            else:
                subject = indirect_object
        else:
            subject = direct_object
else:
    thecat = "cat" #do nothing here, everything went okay
newtitle = re.sub(r"\b%s\b" % subject, toreplace, thetitle)
if (newtitle == thetitle) : #if no replacement happened due to regex
    newtitle = thetitle.replace(subject, toreplace)
return newtitle
"猫"线条是不做任何事情的填充线。 " thetitle"是一个随机新闻文章标题的变量我从RSS提要中提取。 " toreplace"是保存字符串以替换找到的主题的变量。

让我们举个例子:

"应该是动画电视节目的视频游戏 - 屏幕咆哮"以下是https://demos.explosion.ai/displacy/?text=Video%20Games%20that%20Should%20Be%20Animated%20TV%20Shows%20-%20Screen%20Rant&model=en&cpu=1&cph=1

的置换细分

代码决定替换的单词最终成为"",即使在这句话中也不是名词,但似乎导致随机单词选择回退,因为它无法&找到主题,间接对象或直接对象。我希望它会找到更像“#34;视频游戏"在这个例子中。

我应该注意,如果我在displaCy中取出最后一点(似乎是新闻文章的来源):https://demos.explosion.ai/displacy/?text=Video%20Games%20that%20Should%20Be%20Animated%20TV%20Shows&model=en&cpu=1&cph=1它似乎认为"那"是主题,这是不正确的。

解析此问题的更好方法是什么?我应该先寻找合适的名词吗?

1 个答案:

答案 0 :(得分:1)

不直接回答你的问题,我认为下面的代码更具可读性,因为条件是明确的,当条件有效时发生的事情并没有埋没在远处的else子句中。此代码还处理具有多个对象的情况。

对于您的问题:任何自然语言处理工具都很难找到句子片段的主题(或者可能是主题),它们是用完整的句子训练的。我甚至不确定这些片段在技术上是否有主题(但我不是专家)。你可以尝试训练你自己的模型,但是你必须提供带标签的句子,我不知道句子片段是否已存在这样的事情。

我不完全确定你想要达到的目标,看着常用的名词和代词可能包含你想要替换的词,而第一个出现的词可能是最重要的。

import spacy
import random
import re
from collections import defaultdict

def replace_subj(sentence, nlp):
    doc = nlp(sentence)
    tokens = defaultdict(list)

    for text in doc:
        tokens[text.dep_].append(text.orth_)

    if not sentence:
        return "cat"

    if "nsubj" in tokens:
        subject = tokens["nsubj"][0]
    elif "dobj" in tokens:
        subject = tokens["dobj"][0]
    elif "iobj" in tokens:
        subject = tokens["iobj"][0]
    else:
        subject = random.choice(sentence.split())

    return re.sub(r"\b{}\b".format(subject), "cat", sentence)

if __name__ == "__main__":
    sentence = """Video Games that Should Be Animated TV Shows - Screen Rant"""

    nlp = spacy.load("en")
    print(replace_subj(sentence, nlp))