首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python匹配新闻数据中的公司名称

使用Python匹配新闻数据中的公司名称
EN

Stack Overflow用户
提问于 2016-09-25 04:22:07
回答 3查看 1.5K关注 0票数 1

我有一个新闻数据集,其中包含近10,000条过去3年的新闻。我还有一份在纽约证券交易所注册的公司名单(公司名称)。现在我想检查列表中的公司名称列表是否出现在新闻数据集中。示例:

代码语言:javascript
复制
company Name: 'E.I. du Pont de Nemours and Company'
News: 'Monsanto and DuPont settle major disputes with broad patent-licensing deal, with DuPont agreeing to pay at least $1.75 billion over 10 years for rights to technology for herbicide-resistant soybeans.'

现在,如果新闻中包含确切的公司名称,我可以找到包含公司名称的新闻,但从上面的示例可以看出情况并非如此。我还尝试了另一种方法,即我在公司的全名中采用了完整的名称,即在上面的示例中,'Pont‘是一个单词,当调用该公司名称时,它绝对应该是文本的一部分。所以它在大多数情况下都是有效的,但是在下面的例子中出现了问题:

代码语言:javascript
复制
Company Name: Ennis, Inc.
News: L D`ennis` Kozlowski, former chief executive convicted of looting nearly $100 million from Tyco International, has emerged into far more modest life after serving six-and-a-half year sentence and probation; Kozlowski, who became ultimate symbol of corporate greed in era that included scandals at Enron and WorldCom, describes his personal transformation and more humble pleasures that have replaced his once high-flying lifestyle.

现在你可以在文本中看到EnnisDennis匹配,所以它给出了不相关的新闻结果。

有人能告诉我做这件事的正确方法吗?谢谢。

EN

回答 3

Stack Overflow用户

发布于 2016-09-25 04:29:53

使用带有boundaries的正则表达式进行精确匹配,无论您选择全名还是部分您认为唯一的部分由您决定,但使用单词边界D'ennis'将不会与Ennis匹配:

代码语言:javascript
复制
companies = ["name1", "name2",...]
companies_re = re.compile(r"|".join([r"\b{}\b".format(name) for name in companies]))

根据每个新闻项目的匹配数,您可能希望使用companies_re.search(artice)companies_re.find_all(article)。另外,对于不区分大小写的匹配,传递re.I进行编译。

如果您要检查的唯一行也始终是以公司company Name:开头的行,则可以缩小搜索范围:

代码语言:javascript
复制
for line in all_lines:
  if line.startswith("company Name:"):
      name = companies_re.search(line) 
      if name:
         ...
      break
票数 1
EN

Stack Overflow用户

发布于 2017-01-17 01:07:10

听起来你需要Aho-Corasick算法。这里有一个又好又快的python实现:https://pypi.python.org/pypi/pyahocorasick/

它只做精确匹配,所以你需要同时索引"Du pont“和"Dupont",例如。但这并不难,您可以使用维基数据来帮助您查找别名:例如,查看Dupont's entry的别名:它包括"Dupont“和"Du pont”。

好的,让我们假设您有公司名称及其别名的列表:

代码语言:javascript
复制
import ahocorasick
A = ahocorasick.Automaton()

companies = ["google", "apple", "tesla", "dupont", "du pont"]
for idx, key in enumerate(companies):
    A.add_word(key, idx)

接下来,创建自动机(有关算法的详细信息,请参阅上面的链接):

代码语言:javascript
复制
A.make_automaton()

太棒了!现在,您可以简单地在一些文本中搜索所有公司:

代码语言:javascript
复制
your_text = """
I love my Apple iPhone. Do you know what a Googleplex is?
I ate some apples this morning.
"""

for end_index, idx in A.iter(your_text.lower()):
    print(end_index, companies[idx])

这是输出:

代码语言:javascript
复制
15 apple
49 google
74 apple

数字对应于文本中公司名称最后一个字符的索引。

很简单,对吧?而且非常快,这种算法被GNU grep的一些变体使用。

保存/加载自动机

如果有很多公司名称,创建自动机可能需要一些时间,所以您可能只需要创建一次,将其保存到磁盘(使用pickle),然后在每次需要时加载它:

代码语言:javascript
复制
# create_company_automaton.py
# ... create the automaton (see above)
import pickle
pickle.dump(A, open('company_automaton.pickle', 'wb'))

在将使用该自动机的程序中,首先加载该自动机:

代码语言:javascript
复制
# use_company_automaton.py
import ahocorasick
import pickle
A = pickle.load(open("company_automaton.pickle", "rb"))
# ... use the automaton

希望这能有所帮助!:)

Bonus details

如果你想在“苹果发布新的iPhone”中使用“苹果”,而不是在“我今天早上吃了一个苹果”中使用“苹果”,那么你将会有一段艰难的时间。但这是可行的:例如,你可以收集一组包含单词“苹果”和关于公司的文章,以及一组与公司无关的文章,然后找出更有可能与公司相关的单词(或n-gram)(例如"iPhone")。不幸的是,对于每个名称不明确的公司,您都需要这样做。

票数 1
EN

Stack Overflow用户

发布于 2016-09-25 04:26:12

你可以试试

代码语言:javascript
复制
  difflib.get_close_matches

公司的全称。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39680624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档