2016-08-02 69 views
1

我有一个公司名单,但其中一些公司只是人名。我想从名单中排除这些人,但我无法找到一种方法来识别公司的人名。区分人名和公司名称之间的清单

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

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

+2

是,清单?如果是这样,你错过了一些逗号,并且你的报价出了点怪异 – depperm

+2

听起来更像是一个机器学习问题。你如何期待NLTK知道“公司”的定义?你必须告诉它(INC,LLC,CO,GROUP)都是关键字 –

+0

我的错我把它列为一个正确的列表。 – Jstuff

回答

0

就我所知,你需要区分公司和人名。我猜的公司名单及任何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 
+1

'if item.endswith('LLC')or item.endswith('INC'):' – erip

+1

此外,'AGCHOICE - BLUE MOUND是一个人'似乎是错误的。 – erip

+0

如果你有一个姓“Inc”的人,这会失败。不寻常的,但不是不可能的。 –

0

检验公司名称的指标列表元素。对于你的名单,这是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 
0

我不相信你可以做到这一点完全编程,所以会需要一些手动操作。然而,你可以使事情变得更容易一些与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
+0

中出现错误与排序函数一致的错误TypeError:必须使用关键字函数的关键字参数 – Jstuff

+0

通过添加'key = lambda'修正了错误,但排序函数似乎并没有可能在这种情况下排序。它创建'key_words'组进行排序,但不会为每个组创建一个大组。 – Jstuff

+0

@Jstuff,修正了错字。不知道我理解你的问题,但是,你的意思是“排序可能”。当我运行代码时,我得到的结果显示在回答中 – wnnmaw