如何从原始文本中解析名称

时间:2014-08-03 06:23:24

标签: python nlp linguistics

我想知道是否有人知道任何好的库或从原始文本解析名称的方法。

例如,让我们说我已经将这些作为例子:(注意有时它们是大写元组,有时则不是)

James Vaynerchuck and the rest of the group will be meeting at 1PM. 
Sally Johnson, Jim White and brad burton. 
Mark angleman Happiness, Productivity & blocks. Mark & Evan at 4pm.

我的第一个想法是加载某种词性标记器(如Pythons NLTK),标记所有单词。然后只删除名词,然后将名词与已知单词数据库(即文字字典)进行比较,如果它们不在字典中,则假设它们是名称。

其他想法是深入研究机器学习,但这可能超出了我在这里需要的范围。

您可以指出的任何想法,建议或图书馆都会非常有帮助。

谢谢!

2 个答案:

答案 0 :(得分:2)

我不知道为什么你认为你需要NLTK只是为了排除字典词;一个简单的字典(你可能已安装在/usr/share/dict/words之类的地方,或者你可以从网上下载一个)就是你所需要的:

with open('/usr/share/dict/words') as f:
    dictwords = {word.strip() for word in f}
with open(mypath) as f:
    names = [word for line in f for word in line.rstrip().split()
             if word.lower() not in dictwords]

您的words列表可能包含名称,但如果是,则会将它们包含为大写,因此:

    dictwords = {word.strip() for word in f if word.islower()}

或者,如果您想将专有名称列入白名单而不是将字典单词列入黑名单:

with open('/usr/share/dict/propernames') as f:
    namewords = {word.strip() for word in f}
with open(mypath) as f:
    names = [word for line in f for word in line.rstrip().split()
             if word.title() in namewords]

但这确实无法奏效。从你的例子中看“吉姆怀特”。他的姓氏显然会出现在任何字典中,他的名字将在很多中(作为“jimmy”的简短版本,作为阿拉伯字母“jīm”的常见罗马字母等)。 “马克”也是一个常见的字典词。反过来说,“Will”是一个非常常见的名字,即使你想把它当作一个词,“幸福”是一个不常见的名字,但至少有一些人拥有它。

因此,为了使这项工作尽可能轻松,您可能希望结合多种启发式方法。首先,不是一个词总是一个名字或永远不是一个名字,每个单词都有可能被用作某个相关语料库中的名字 - 白色可能是一个名字,占13.7%,Mark 41.3%,Jim 99.1% ,幸福0.1%等等。接下来,如果它不是句子中的第一个单词,但是大写,那么它更有可能成为一个名字(还有多少?我不知道,你需要测试和调整对于你的特定输入),如果它是小写的,它不太可能是一个名字。你可以引入更多的上下文 - 例如,你有很多全名,所以如果某个东西是一个可能的名字而且它出现在一个普通姓氏的旁边,那么它更可能是一个名字。你甚至可以尝试解析语法(如果你保留一些句子就可以了;他们只是不会从语法规则中得到任何输入),所以如果两个相邻的单词只作为一个句子的一部分,那么如果第二个单词是一个动词,它们可能不是名字和姓,即使在同一个第二个单词可能是其他语境中的名词(和名字)。等等。

答案 1 :(得分:0)

我发现这个库对于解析名称非常有用:Python Name Parser

它还可以处理格式为Lastname,Firstname的名称。