【问题标题】:Differentiate a list between human names and company names区分人名和公司名之间的列表
【发布时间】:2016-08-03 00:25:21
【问题描述】:

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

通过在线研究,我尝试了两种方法。第一个是使用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 模块,但这也不起作用,因为它将公司名称标记为个人的名字和姓氏。

有什么方法可以区分上面的人名和公司名吗?

【问题讨论】:

  • 这是一个列表吗?如果是这样,您缺少一些逗号,并且您的引号不合时宜
  • 听起来更像是一个机器学习问题。您如何期望 NLTK 知道“公司”的定义?您必须告诉它(INC、LLC、CO、GROUP)都是关键字
  • 我的错,我把它列在了正确的列表中。
  • 这永远不会 100% 处理随机数据。有些公司名称与人名无法区分。例如,我最近从一家名为“Tori Richards”的公司购买了一件衬衫。给定名称“Alice Marina”,是姓氏为“Marina”的“Alice”人的名字,还是提供存放您的船的地方的名为“Alice Marina”的企业?
  • 3 年后,这些答案都没有一点意义?好吧,我发现它们很有用,所以我给了它们一个。

标签: python nltk


【解决方案1】:

我不相信您可以完全以编程方式完成此操作,因此需要进行一些手动操作。不过,您可以使用itertools.groupby 让事情变得更简单

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

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 进行匹配

【讨论】:

  • 排序功能在线出错TypeError: must use keyword argument for key function
  • 通过添加key = lambda 修复了错误,但在这种情况下,排序功能似乎没有排序。它会创建一组 key_words 进行排序,但不会为每个组创建一个大组。
  • @Jstuff,修正了错字。不确定我是否理解您的问题,您所说的“可能排序”是什么意思。当我运行代码时,我得到答案中显示的输出
  • 确实,除非使用机器学习方法,否则这似乎是一种足够强大的启发式方法,尤其是在您不需要真正精确的输出时。
【解决方案2】:

据我了解,您需要区分公司名称和人名。我猜您列表中的公司以 LLCINC 或包含 -(连字符)结尾,因此我做了一组这些词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

【讨论】:

  • if item.endswith(' LLC') or item.endswith(' INC'):
  • 如果你有一个姓氏“Inc”的人,这将失败。不寻常,但并非不可能。
  • 有趣的方法,但并不是我所有的公司都会以 LLC、INC 等结尾。我有很多公司。
  • 我重新回答了你的问题。
  • 一般来说,我们还应该添加数字和符号 [除了 .和 ,] 因为它们不能出现在名称中
【解决方案3】:

测试公司名称指标的列表元素。对于您的列表,这是 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多