2017-06-05 68 views
7

因此,作爲思考實驗的一部分,我在python中編寫了一個函數,它使用spaCy來查找新聞文章的主題,然後將其替換爲選擇的名詞。問題是,它不能很好地工作,我希望可以改進。我不完全理解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」是一個變量,它保存字符串以替換找到的主題。

讓我們用一個例子:

「這應該是電視動畫視頻遊戲節目 - 屏幕誇大其詞」而這裏的是,displaCy故障:https://demos.explosion.ai/displacy/?text=Video%20Games%20that%20Should%20Be%20Animated%20TV%20Shows%20-%20Screen%20Rant&model=en&cpu=1&cph=1

代碼決定的字代替結束了「那「在這個句子中甚至不是一個名詞,但似乎導致了隨機詞選擇回退,因爲它找不到主語,間接賓語或直接賓語。我希望在這個例子中能找到更像「視頻遊戲」的東西。

我應該注意,如果我在displaCy中最後一點出現(它似乎是新聞文章的來源):https://demos.explosion.ai/displacy/?text=Video%20Games%20that%20Should%20Be%20Animated%20TV%20Shows&model=en&cpu=1&cph=1它似乎認爲「that」是主題,這是不正確的。

什麼是更好的解析方法?我應該首先尋找專有名詞嗎?

+0

此嘗試/除了塊看起來不是很pythonic,初始化爲None,然後檢查是什麼錯? –

+0

在句子片段中你不會看到好的結果,你的例句甚至沒有謂詞。 –

+0

Re:try/except塊我基於這個代碼示例找到了如何使用SpaCy的代碼示例。不會有謂詞不好?有沒有比使用SpaCy更好地找到一個句子片段的主題? – SpaceMouse

回答

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))