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

使用Python匹配新闻数据中的公司名称,python,python-3.x,machine-learning,Python,Python 3.x,Machine Learning,我有一个新闻数据集,在过去3年中包含了近10000条新闻。 我还有一份在纽约证券交易所注册的公司名单(公司名称)。现在我想检查列表中的公司名称列表是否出现在新闻数据集中。 例如: 现在,如果确切的公司名称出现在新闻中,我可以发现新闻中包含公司名称,但从上面的示例中可以看出,情况并非如此。 我还尝试了另一种方法,即我在公司全名中使用了完整的名称,即在上面的示例中,当调用该公司名称时,“Pont”是一个单词,它肯定是文本的一部分。因此,它在大多数情况下都有效,但在以下示例中出现了问题: Compan

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

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

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.
现在你可以看到文本中的
Ennis
Dennis
匹配,因此它给出了不相关的新闻结果

有人能告诉我正确的方法吗?谢谢。

你可以试试

  difflib.get_close_matches
使用完整的公司名称。

使用正则表达式进行精确匹配是否选择完整名称或您认为唯一的部分取决于您,但使用单词边界
D'ennis'
将不匹配
ennis

companies = ["name1", "name2",...]
companies_re = re.compile(r"|".join([r"\b{}\b".format(name) for name in companies]))
根据每个新闻项的匹配数量,您可能需要使用
公司搜索(artice)
公司查找所有(文章)
。 同样对于不区分大小写的匹配,传递
re.I
进行编译

如果您要检查的行也总是以公司名称开头的行,则可以缩小搜索范围:

for line in all_lines:
  if line.startswith("company Name:"):
      name = companies_re.search(line) 
      if name:
         ...
      break

听起来你需要算法。这里有一个很好的python快速实现:

它只会进行精确匹配,因此您需要同时索引“杜邦”和“杜邦”。但这并不难,你可以使用Wikidata帮助你找到别名:例如,看看的别名:它包括“杜邦”和“杜邦”

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

import ahocorasick
A = ahocorasick.Automaton()

companies = ["google", "apple", "tesla", "dupont", "du pont"]
for idx, key in enumerate(companies):
    A.add_word(key, idx)
接下来,制作自动机(有关算法的详细信息,请参见上面的链接):

太好了!现在,您只需在一些文本中搜索所有公司:

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])
这是输出:

15 apple
49 google
74 apple
这些数字对应于文本中公司名称最后一个字符的索引

简单,对吗?超快速,这个算法被GNU grep的一些变体使用

保存/加载自动机

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

# create_company_automaton.py
# ... create the automaton (see above)
import pickle
pickle.dump(A, open('company_automaton.pickle', 'wb'))
在将使用此自动机的程序中,首先加载自动机:

# use_company_automaton.py
import ahocorasick
import pickle
A = pickle.load(open("company_automaton.pickle", "rb"))
# ... use the automaton
希望这有帮助!:)

奖金详情

如果你想在“苹果发布一款新iPhone”中匹配“苹果”,而不是在“我今天早上吃了一个苹果”中匹配“苹果”,那么你将很难做到这一点。但这是可行的:例如,你可以收集一组包含“苹果”和关于该公司的文章,以及一组与该公司无关的文章,然后确定在涉及该公司时更可能出现的单词(或n-gram)(例如“iPhone”)。不幸的是,你需要为每个名字模棱两可的公司这样做

# create_company_automaton.py
# ... create the automaton (see above)
import pickle
pickle.dump(A, open('company_automaton.pickle', 'wb'))
# use_company_automaton.py
import ahocorasick
import pickle
A = pickle.load(open("company_automaton.pickle", "rb"))
# ... use the automaton