[英]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>
。 如您所知,這可以用多種方式表示,例如,
我想從商務艙的亞特蘭大去紐約,2014年7月25日。
我想通過商務艙旅行,於7月25日從紐約前往亞特蘭大。
我有一個夢想,我將有一天登上飛機,公務艙旅行,下榻紐約,消息來源在亞特蘭大,最好是7月25日。
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-dateutil或this來代替正則表達式。
如果缺少部分,例如年份或月份。 我們可以使用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.