2017-05-31 50 views
0

我需要從荷蘭文本中提取主體 - 動詞 - 對象三元組。文本由名爲Frog的荷蘭NLP工具進行分析,該工具進行了標記,解析,標記,詞形化......等等。 Frog生成FoLiA XML或製表符分隔的列格式輸出,每個標記一行。由於XML文件存在一些問題,我選擇使用列格式。這個例子代表一個句子。 enter image description here現在我需要提取每句SVO三元組,因此我需要最後一列是依賴關係。所以我需要獲取ROOT元素和屬於ROOT的su和obj1元素。不幸的是,例句中沒有obj1。讓我們假裝它已經。我的想法是首先爲每個句子創建一個帶有列表的嵌套列表。從預處理文本中提取SVO三元組

import csv 
    with open('romanfragment_frogged.tsv','r') as f: 
     reader = csv.reader(f,delimiter='\t') 
     tokens = [] 
     sentences = [] 
     list_of_sents = [] 
     for line in reader: 
      tokens.append(line) 
      #print(tokens) 
      for token in tokens: 
       if token == '1': 
        previous_sentence = list_of_sents 
        sentences.append(previous_sentence) 
     list_of_sents = [] 
     list_of_sents.append(tokens) 
     print(list_of_sents) 

當我打印「令牌」,我得到一個列表中的所有令牌。所以這是正確的,但我仍然試圖創建一個嵌套列表,每個句子有1個列表(標記)。 有人可以幫我解決這個問題嗎?

(PS的第二個問題是,我不知道,該如何繼續,一旦我得到一個嵌套列表)

+1

我認爲,對於初學者來說,輸入格式有些混亂。您鏈接到的工具網站表示輸出是XML。但是,圖像和你在「\ t」上分割的嘗試表明它是一個TSV(製表符分隔的純文本)文件。再說一遍,你聲稱它是一個Word文檔 - 大概是舊的二進制「.doc」版本,這將是所有選項中最糟糕的。請整理出來並更新問題。 – lenz

+0

@lenz正如網站所說,有2個輸出選項'青蛙產生FoLiA XML,或製表符分隔的列格式化輸出,每個令牌一行'。由於XML文件存在一些問題,我選擇使用列格式。但是我保存爲.doc就像你說的那樣,將它保存爲.txt文件更好嗎? – Bambi

+0

好的,我看到了 - 我想你實際上並沒有將它保存爲一個Word文檔,只是用一個文件名以「.doc」結尾。約定是使用「.tsv」或有時使用「.csv」。 – lenz

回答

1

也許這樣的事情可以工作:

def iter_sentences(fn): 
    with open(fn, 'r') as f: 
     reader = csv.reader(f,delimiter='\t') 
     sentence = [] 
     for row in reader: 
      if not row: 
       # Ignore blank lines. 
       continue 
      if row[0] == '1' and sentence: 
       # A new sentence started. 
       yield sentence 
       sentence = [] 
      sentence.append(row) 
     # Last sentence. 
     if sentence: 
      yield sentence 

def iter_triples(fn): 
    for sentence in iter_sentences(fn): 
     # Get all subjects and objects. 
     subjects = [tok for tok in sentence if tok[-1] == 'su'] 
     objects = [tok for tok in sentence if tok[-1] == 'obj1'] 
     # Now try to map them: find pairs with a head in the same position. 
     for obj in objects: 
      for subj in subjects: 
       # row[-2] is the position of the head. 
       if subj[-2] == obj[-2]: 
        # Matching subj-obj pair found. 
        # Now get the verb (the head of both subj and obj). 
        # Its position is given in the second-to-last column. 
        position = int(subj[-2]) 
        # Subtract 1, as the positions start counting at 1. 
        verb = sentence[position-1] 
        yield subj, verb, obj 

for subj, verb, obj in iter_triples('romanfragment_frogged.tsv'): 
    # Only print the surface forms. 
    print(subj[1], verb[1], obj[1]) 

快速的解釋: iter_sentences迭代句子。 每個句子都是一個嵌套列表: 它是一個標記列表,每個標記本身就是一個列表(包含行號,表面形式,引理,POS,依賴關係等)。 iter_triples函數遍歷三元組 。 這些三元組中的每個元素都表示一個標記(即,也是一個列表)。

最後三行代碼只是如何使用iter_triples函數的一個例子。 我不知道你需要從每個三元組中得到多少和哪些信息...

+0

謝謝!但是這個代碼'用於閱讀器中的行: if row [0] =='1'and sentence'給了我一個索引錯誤:列表索引超出範圍 – Bambi

+1

可能是一個空行。您可以在檢查之前添加'if not row:continue',然後空白行將被跳過。 – lenz

+0

確實,問題解決了。我編輯了你的代碼。現在我還有兩個小問題。 1.我不完全理解這條線的工作原理動詞=句子[int(subj [-2]) - 1]。我需要這個來處理不同的文本。 SVO三元組作爲機器學習的一個功能。是否有可能從iter_triples的輸出獲得每個句子的三元組的嵌套列表,但僅限於標記名稱和關係。所以元素2和10每個標記的列表? – Bambi

相關問題