区分人名和公司名称之间的列表

时间:2016-08-02 13:56:34

标签: python nltk

我有一份公司名单,但其中一些公司只是人名。我想从列表中删除这些人,但我很难找到一种方法来识别公司的人名。

通过在线研究,我尝试了两种方法。第一个是使用nltk。我的代码看起来像

y = ['INOVATIA LABORATORIES LLC', 'PRULLAGE PHD JOSEPH B', 'S J SMITH CO INC', 'TEVA PHARMACEUTICALS USA INC', 'KENT NUTRITION GROUP INC', 'JOSEPH D WAGENKNECHT', 'ROBERTSON KEITH', 'LINCARE INC', 'AGCHOICE - BLUE MOUND']

在上面的列表中,我想删除PRULLAGE PHD JOSEPH BJOSEPH D WAGENKNECHTROBERTSON KEITH

z = []
for company in y:
    tokens = nltk.tokenize.word_tokenize(company)
    z.append(nltk.pos_tag(tokens))

这不起作用,因为它将所有内容标记为专有名词。然后我降低了所有内容,并且只使用.title()将每个单词的第一个字母大写,但是由于类似的原因,这也失败了。

我尝试的另一种方法是使用Human Name Parser模块,但这也不起作用,因为它将公司名称标记为此人的名字和姓氏。

有没有办法可以区分上面列出的人名和公司名称?

3 个答案:

答案 0 :(得分:1)

据我了解,您需要区分公司和人名。我猜您列表中的公司以 LLC INC 结尾或包含 - (连字符),因此我制作了一组这些单词company_set{'LLC', 'INC', '-'},然后通过基本函数split()将其拆分为令牌。如果company_set和分裂的令牌的交集有任何共同点,那么它就不会是空集,因此公司消息会被打印出来,否则就是人的消息。以下是代码:

y = ['INOVATIA LABORATORIES LLC', 'PRULLAGE PHD JOSEPH B', 'S J SMITH CO INC', 'TEVA PHARMACEUTICALS USA INC', 'KENT NUTRITION GROUP INC', 'JOSEPH D WAGENKNECHT', 'ROBERTSON KEITH', 'LINCARE INC', 'AGCHOICE - BLUE MOUND']
company_set = {'LLC', 'INC', '-'}
for item in y:
    tokens = set(item.split())
    if company_set.intersection(tokens) !=  set():
        print "{} is a company".format(item)
    else:
        print "{} is a human".format(item)

输出如下:

INOVATIA LABORATORIES LLC is a company
PRULLAGE PHD JOSEPH B is a human
S J SMITH CO INC is a company
TEVA PHARMACEUTICALS USA INC is a company
KENT NUTRITION GROUP INC is a company
JOSEPH D WAGENKNECHT is a human
ROBERTSON KEITH is a human
LINCARE INC is a company
AGCHOICE - BLUE MOUND is a company

答案 1 :(得分:1)

测试公司名称指标的列表元素。对于您的列表,这是INC,LLC和连字符(可能是一个人姓名的一部分)。或公司名称的一部分(实验室,制药,解决方案......)。可能还有其他标准(音节,语音)。 否则,您需要一个名称或公司字典来测试。

y = ['INOVATIA LABORATORIES LLC', 'PRULLAGE PHD JOSEPH B', 'S J SMITH CO INC', 'TEVA PHARMACEUTICALS USA INC', 'KENT NUTRITION GROUP INC', 'JOSEPH D WAGENKNECHT', 'ROBERTSON KEITH', 'LINCARE INC', 'AGCHOICE - BLUE MOUND']
f = ["INC", "LLC", "-"]
c = []
for n in y:
  for t in f:
    if t in n:
      c.append(n)
print( "\n".join(c) )

给出

> t
INOVATIA LABORATORIES LLC
S J SMITH CO INC
TEVA PHARMACEUTICALS USA INC
KENT NUTRITION GROUP INC
LINCARE INC
AGCHOICE - BLUE MOUND

答案 2 :(得分:1)

我不相信你可以完全以编程方式完成这项工作,因此需要进行一些手动操作。但是,您可以使用itertools.groupby

让事情变得更轻松

正如一些评论所指出的,公司可能包含某些关键字,因此我们可以创建一个使用这些关键字的列表:

key_words = ["INC", "LLC", "CO", "GROUP"]

从这里开始,我们可以根据项目是否包含其中一个关键词来对列表进行排序(这是分组所必需的):

y.sort(key=lambda name: any(key_word in name for key_word in key_words))    

在您的示例中,这将列出

['PRULLAGE PHD JOSEPH B', 'JOSEPH D WAGENKNECHT', 'ROBERTSON KEITH', 'AGCHOICE - BLUE MOUND', 'INOVATIA LABORATORIES LLC', 'S J SMITH CO INC', 'TEVA PHARMACEUTICALS USA INC', 'KENT NUTRITION GROUP INC', 'LINCARE INC']

从这里开始,我们可以将可能的事物分组为不是公司(那些不包含任何关键词的公司)和绝对公司的事物(那些包含关键词的公司):

import itertools
I = itertools.groupby(y, lambda name: any(key_word in name for key_word in key_words))

所以我们现在有两组:

for i in I:
    print i[0], list(i[1])
False ['PRULLAGE PHD JOSEPH B', 'JOSEPH D WAGENKNECHT', 'ROBERTSON KEITH', 'AGCHOICE - BLUE MOUND']
True ['INOVATIA LABORATORIES LLC', 'S J SMITH CO INC', 'TEVA PHARMACEUTICALS USA INC', 'KENT NUTRITION GROUP INC', 'LINCARE INC']

然后,您可以手动对虚假组进行排序并删除公司,或者应用其他类似的过滤方法来进一步改进匹配。要应用的其他一些过滤器:

  • 包含"MR", "MS", "MRS", "PHD", "DR"的任何内容很可能是一个人
  • "multiple_letters<space>single_letter<space>multiple_letters"形式的单词可能是名称,您可以使用re
  • 进行匹配