簡體   English   中英

Python NLTK解釋固定的句子模式並將其標記化

[英]Python NLTK interpret a fixed pattern of sentence and tokenize it

我有一個應用,其中NLTK需要解釋人類發出的語音,並從中找到有意義的部分。 需要解釋的句子的形式from <somewhere>, to <somewhere> on <some_date>, <class_of_travel,like AC_CHAIR_CAR> 如您所知,這可以用多種方式表示,例如,

  1. 我想從商務艙的亞特蘭大去紐約,2014年7月25日。

  2. 我想通過商務艙旅行,於7月25日從紐約前往亞特蘭大。

  3. 我有一個夢想,我將有一天登上飛機,公務艙旅行,下榻紐約,消息來源在亞特蘭大,最好是7月25日。

  4. 7月25日,亞特蘭大飛往紐約的商務艙。

你明白了。 我要提取的信息很少-來源,目的地,類別,日期。 有些可能會丟失,必須加以識別或適當假設。 就像發現源丟失一樣,請進行識別。 或者,如果缺少年份,則將其計入當前年份。 一直以來,都忽略了無用的信息(就像我崇拜馬丁·路德一樣, 我有一個夢dream以求的部分)。

有什么辦法可以在NLTK中實現? 我知道有可用的標記器,並且有一些訓練標記器的方法,但是我對此沒有足夠的知識。 是否可以或多或少地覆蓋所有可能表示這樣一個句子的情況,並提取類似的信息? 如果是這樣,一點指導將不勝感激。

此問題稱為“命名實體識別”(或簡稱為“ ner”)。 谷歌搜索這些短語將使您指向許多庫,在線api,針對特定數據類型的巧妙經驗法則等。

http://nlp.stanford.edu:8080/ner/上查看演示NER系統

檢測日期和時間的引用可能是其中最基於啟發式的解決方案的情況。

如果您要處理的文本域非常有限,那么設置手動策划的實體列表可能會很有幫助。
例如,僅列出具有商業機場的所有城市的所有機場代碼/名稱的列表,並嘗試將這些名稱與任何輸入文本進行精確的字符串匹配。

在計算語言學中,這稱為“ 命名實體識別 ”,它是從文本中識別組織,人員和位置之類的過程。

這里的挑戰是nltk中的默認NE塊器是在ACE語料庫上訓練的最大熵塊器。 它沒有經過訓練可以識別日期和時間,因此您需要對其進行調整並找到一種檢測時間的方法。

有一些軟件包可以幫助提取命名實體,Stanford NER(命名實體識別器)是最流行的命名實體識別工具之一,由Java實現。 但是,您可以通過下載軟件包並通過提供Stanford NER接口的NLTK進行交互來使用它。

您可以下載斯坦福命名實體識別器3.4版 ,在其中找到stanford-ner.jar和分類器模型“ all.3class.distsim.crf.ser.gz”

from nltk.tag.stanford import NERTagger
def stanfordNERExtractor(sentence):
    st =  NERTagger('/usr/share/stanford-ner/classifiers/all.3class.distsim.crf.ser.gz',
               '/usr/share/stanford-ner/stanford-ner.jar')
    return st.tag(sentence.split()) 

stanfordNERExtractedLines = stanfordNERExtractor("New York")
print stanfordNERExtractedLines #[('New-York', 'LOCATION')]

您也可以使用NTLK,您可以在官方文檔中找到更多詳細信息,請查閱Gavin的要旨

def extract_entities(text):
    for sent in nltk.sent_tokenize(text):
        for chunk in nltk.ne_chunk(nltk.pos_tag(nltk.word_tokenize(sent))):
            if hasattr(chunk, 'node'):
                print chunk.node, ' '.join(c[0] for c in chunk.leaves())

extract_entities("to play to Atlanta")

#Output: [('to', 'TO'),('play', 'VB'),('to', 'TO'),('play', 'NN')],
  • 我們如何識別目的地? 在區分位置之后,您可能會遇到識別空格分隔的單詞,或者區分來源和區別的問題。

最好編寫一個正則表達式模式來標識源和目標。 您可能在獲取諸如"to get"類的其他字詞時遇到問題,但是您已確定要從st.tag進行驗證的位置列表(“ LOCATION”),或者如果您使用的是NTLK,則可以驗證其是否為動詞(“ VB” /“ NN”)。 您還可以通過使用NLTK的UnigramTagger()和BigramTagger()來獲取可能被標識為位置的“ FROM”和“ TO”之后的名稱來檢查可能性

 import re text= "I want to go to New York from Atlanta, business class, on 25th July." destination= re.findall(r'.to.([AZ][a-zA-Z]+?[\\s-]*[AZ]*[a-zA-Z]*)',text) source= re.findall(r'.from.([AZ][a-zA-Z]+?[\\s-]*[AZ]*[a-zA-Z]*)',text) print source,destination 
  • 我們如何確定時間/日期?

如上所述,這是我們可能面臨的問題之一,但是我們可以使用正則表達式,如本線程中所述

print re.findall(
    r"""(?ix)             # case-insensitive, verbose regex
    \b                    # match a word boundary
    (?:                   # match the following three times:
     (?:                  # either
      \d+                 # a number,
      (?:\.|st|nd|rd|th)* # followed by a dot, st, nd, rd, or th (optional)
      |                   # or a month name
      (?:(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*)
     )
     [\s./-]*             # followed by a date separator or whitespace (optional)
    ){3}                  # do this three times
    \b """, 
    text)

輸出:

25th July 2014.

我們也可以使用python-dateutilthis來代替正則表達式。

如果缺少部分,例如年份或月份。 我們可以使用parsedatetime包對其進行調整。

查看此快速示例(您可以根據不同情況進行調整)

>>> import parsedatetime
>>> p = parsedatetime.Calendar()
>>> print p.parse("25th this month")
(time.struct_time(tm_year=2014, tm_mon=11, tm_mday=10, tm_hour=1, tm_min=5, tm_sec=31, tm_wday=0, tm_yday=314, tm_isdst=0), 0)
>>> print p.parse("25th July")
((2015, 7, 25, 1, 5, 50, 0, 314, 0), 1)
>>> print p.parse("25th July 2014")
((2014, 7, 25, 1, 6, 3, 0, 314, 0), 1)

最后一件事是,您可以使用此數據集提取機場端口,並驗證所提到位置的正確性,以防您在有空時(某些地方沒有機場端口)進行回答。

對於班級,您可以通過查看句子中的“經濟艙”,“商務艙”兩個詞來進行驗證(您可以在in表達式或正則表達式之間in選擇)。

有關本主題的更多詳細信息,請檢查: NTLK-從文本中提取信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM