在计算语言学中,这被称为“Named Entity Recognition”,它是从文本中识别组织、人员和位置等事物的过程。
这里的挑战是 nltk 中的默认 NE 分块器是在 ACE corpus 上训练的最大熵分块器。它尚未经过训练以识别日期和时间,因此您需要对其进行调整并找到一种检测时间的方法。
有一些包可以帮助提取命名实体,Stanford NER(命名实体识别器)是最流行的命名实体识别工具之一,由 Java 实现。但是你可以通过下载包来使用它,并通过提供斯坦福NER接口的NLTK进行交互。
您可以下载Stanford Named Entity Recognizer version 3.4
在哪里可以找到 stanford-ner.jar 和分类器模型“all.3class.dissim.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(“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.([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-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)
最后一件事是,您可以使用此dataset 提取机场,并验证所提及位置的正确性,以防您回答可用性(有些地方没有机场)。
对于类,你可以通过查看句子中的“经济类”、“商务类”等词来验证(你可以选择in或正则表达式)。
有关本主题的更多详细信息,请查看:NTLK - Extracting Information from Text