我有一个新闻数据集,其中包含近10,000条过去3年的新闻。我还有一份在纽约证券交易所注册的公司名单(公司名称)。现在我想检查列表中的公司名称列表是否出现在新闻数据集中。示例:
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‘是一个单词,当调用该公司名称时,它绝对应该是文本的一部分。所以它在大多数情况下都是有效的,但是在下面的例子中出现了问题:
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匹配,所以它给出了不相关的新闻结果。
有人能告诉我做这件事的正确方法吗?谢谢。
发布于 2016-09-25 04:29:53
使用带有boundaries的正则表达式进行精确匹配,无论您选择全名还是部分您认为唯一的部分由您决定,但使用单词边界D'ennis'将不会与Ennis匹配:
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:开头的行,则可以缩小搜索范围:
for line in all_lines:
if line.startswith("company Name:"):
name = companies_re.search(line)
if name:
...
break发布于 2017-01-17 01:07:10
听起来你需要Aho-Corasick算法。这里有一个又好又快的python实现:https://pypi.python.org/pypi/pyahocorasick/
它只做精确匹配,所以你需要同时索引"Du pont“和"Dupont",例如。但这并不难,您可以使用维基数据来帮助您查找别名:例如,查看Dupont's entry的别名:它包括"Dupont“和"Du pont”。
好的,让我们假设您有公司名称及其别名的列表:
import ahocorasick
A = ahocorasick.Automaton()
companies = ["google", "apple", "tesla", "dupont", "du pont"]
for idx, key in enumerate(companies):
A.add_word(key, idx)接下来,创建自动机(有关算法的详细信息,请参阅上面的链接):
A.make_automaton()太棒了!现在,您可以简单地在一些文本中搜索所有公司:
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希望这能有所帮助!:)
Bonus details
如果你想在“苹果发布新的iPhone”中使用“苹果”,而不是在“我今天早上吃了一个苹果”中使用“苹果”,那么你将会有一段艰难的时间。但这是可行的:例如,你可以收集一组包含单词“苹果”和关于公司的文章,以及一组与公司无关的文章,然后找出更有可能与公司相关的单词(或n-gram)(例如"iPhone")。不幸的是,对于每个名称不明确的公司,您都需要这样做。
发布于 2016-09-25 04:26:12
你可以试试
difflib.get_close_matches公司的全称。
https://stackoverflow.com/questions/39680624
复制相似问题