Python NLTK解释一个固定的句子模式并对其进行标记

时间:2014-10-30 20:26:14

标签: python nlp speech-recognition nltk

我有一个应用程序,其中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日亚特兰大到纽约,商务舱。

  5. 你明白了。我想要提取的是几个信息 - 源,目的地,类,日期。有些可能缺失,必须予以识别或适当假设。就像发现缺少来源一样,确定一下。或者,如果缺少年份,请将其记录到当前年份。并且一直忽视无用的信息(比如我有一个梦想部分,就像我崇拜马丁路德一样)。

    有什么方法可以在NLTK中实现这个目标吗?我知道有标签可用,并且有培训标签的方法,但我对此没有足够的了解。是否有可能涵盖或多或少所有可能意味着这样一个句子的案例,并提取这样的信息?如果是这样,我们将不胜感激。

2 个答案:

答案 0 :(得分:2)

这个问题被称为“命名实体识别”&#39; (或者只是&#39; ner&#39;)。谷歌搜索这些短语应该指向许多图书馆,在线api,对特定类型的数据的聪明的经验法则等。

http://nlp.stanford.edu:8080/ner/

查看演示NER系统

检测对日期和时间的引用可能是具有最基于启发式的解决方案的情况。

如果您正在使用特定且非常有限的文本域,那么设置手动策划的实体列表可能会非常有用。
例如只需列出所有拥有商业机场的城市的机场代码/名称,并尝试根据任何输入文本对这些名称进行精确的字符串匹配。

答案 1 :(得分:2)

在计算语言学中,这称为“Named Entity Recognition”,它是从文本中识别组织,人员和位置等事物的过程。

这里的挑战是nltk中的默认NE chunker是在ACE corpus上训练的最大熵chunker。它没有经过训练来识别日期和时间,所以你需要调整它并找到一种方法来检测时间。

有一些软件包可以帮助提取命名实体,Stanford NER(命名实体识别器)是最受欢迎的命名实体识别工具之一,由Java实现。但是你可以通过下载软件包来使用它,并通过提供斯坦福NER接口的NLTK进行交互。

您可以下载Stanford Named Entity Recognizer version 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,你可以在official document找到更多详细信息,请查看这个要点from 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验证的位置列表(&#34; LOCATION&#34;),或者如果您使用的是NTLK,可以验证它是否是动词(&#34; VB&#34; /&#34; NN&#34;)。您还可以使用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.([A-Z][a-zA-Z]+?[\s-]*[A-Z]*[a-zA-Z]*)',text)
source= re.findall(r'.from.([A-Z][a-zA-Z]+?[\s-]*[A-Z]*[a-zA-Z]*)',text)

print source,destination
  • 我们如何识别时间/日期?

如上所述,这是我们可以面对的问题之一,但我们可以使用正则表达式,如thread中所述。

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)

最后一点是,您可以使用此dataset来提取机场,并验证所提及位置的正确性,以防您回答可行性(有些地方没有机场)。

对于课程,您可以通过查看&#34;经济课程&#34;,&#34;商务课程&#34;来验证课程。句子中的单词(您可以选择in或正则表达式)。

有关本主题的更多详细信息,请查看:NTLK - Extracting Information from Text