- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我创建了一个小程序来检查作者是否存在于作者数据库中。我无法找到解决此问题的任何特定模块,因此我使用模块从头开始编写它以进行近似字符串匹配。
该数据库包含大约 6000 位作者,并且格式非常糟糕(许多拼写错误、变体、标题如“博士”等)。查询作者列表通常在 500-1000 之间(我有很多这样的列表),因此速度非常重要。
我的一般策略是尽可能多地修剪和过滤数据库并寻找精确匹配。如果未找到匹配项,我将继续进行近似字符串匹配。
我目前正在使用内置的 difflib.get_close_matches
,它完全符合我的要求 - 但是,它非常慢(几分钟)。因此,我正在寻找其他选择:
我发现的唯一一个是 fuzzy wuzzy,它比 difflib 还要慢。
最佳答案
尝试 fuzzywuzzy使用 native C python-levenshtein已安装库。
我在我的 PC 上运行了一个基准测试,以在有和没有 C-native levenshtein backend 的 ~19k 单词列表中找到 8 个单词的最佳候选者。安装(使用 pip install python_Levenshtein-0.12.0-cp34-none-win_amd64.whl
)我得到了这些时间:
那是 ~x4 快(但没有我预期的那么快)。
结果如下:
0 of 8: Compared 'Lemaire' --> `[('L.', 90), ('Le', 90), ('A', 90), ('Re', 90), ('Em', 90)]`
1 of 8: Compared 'Peil' --> `[('L.', 90), ('E.', 90), ('Pfeil', 89), ('Gampel', 76), ('Jo-pei', 76)]`
2 of 8: Compared 'Singleton' --> `[('Eto', 90), ('Ng', 90), ('Le', 90), ('to', 90), ('On', 90)]`
3 of 8: Compared 'Tagoe' --> `[('Go', 90), ('A', 90), ('T', 90), ('E.', 90), ('Sagoe', 80)]`
4 of 8: Compared 'Jgoun' --> `[('Go', 90), ('Gon', 75), ('Journo', 73), ('Jaguin', 73), ('Gounaris', 72)]`
5 of 8: Compared 'Ben' --> `[('Benfer', 90), ('Bence', 90), ('Ben-Amotz', 90), ('Beniaminov', 90), ('Benczak', 90)]`
6 of 8: Compared 'Porte' --> `[('Porter', 91), ('Portet', 91), ('Porten', 91), ('Po', 90), ('Gould-Porter', 90)]`
7 of 8: Compared 'Nyla' --> `[('L.', 90), ('A', 90), ('Sirichanya', 76), ('Neyland', 73), ('Greenleaf', 67)]`
这是基准测试的 python 代码:
import os
import zipfile
from urllib import request as urlrequest
from fuzzywuzzy import process as fzproc
import time
import random
download_url = 'http://www.outpost9.com/files/wordlists/actor-surname.zip'
zip_name = os.path.basename(download_url)
fname, _ = os.path.splitext(zip_name)
def fuzzy_match(dictionary, search):
nsearch = len(search)
for i, s in enumerate(search):
best = fzproc.extractBests(s, dictionary)
print("%i of %i: Compared '%s' --> `%s`" % (i, nsearch, s, best))
def benchmark_fuzzy_match(wordslist, dict_split_ratio=0.9996):
""" Shuffle and split words-list into `dictionary` and `search-words`. """
rnd = random.Random(0)
rnd.shuffle(wordslist)
nwords = len(wordslist)
ndictionary = int(dict_split_ratio * nwords)
dictionary = wordslist[:ndictionary]
search = wordslist[ndictionary:]
fuzzy_match(dictionary, search)
return ndictionary, (nwords - ndictionary)
def run_benchmark():
if not os.path.exists(zip_name):
urlrequest.urlretrieve(download_url, filename=zip_name)
with zipfile.ZipFile(zip_name, 'r') as zfile:
with zfile.open(fname) as words_file:
blines = words_file.readlines()
wordslist = [line.decode('ascii').strip() for line in blines]
wordslist = wordslist[4:] # Skip header.
t_start = time.time()
ndict, nsearch = benchmark_fuzzy_match(wordslist)
t_finish = time.time()
t_elapsed = t_finish - t_start
ncomparisons = ndict * nsearch
sec_per_search = t_elapsed / ncomparisons
msg = "Compared %s words in %s sec (%s sec/search)."
print(msg % (ncomparisons, t_elapsed, sec_per_search))
if __name__ == '__main__':
run_benchmark()
关于python - 作者姓名的近似字符串匹配 - 模块和策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13980656/
所以我必须用以下方法来近似 Pi:4*(1-1/3+1/5-1/7+1/9-...)。它也应该基于迭代次数。所以函数应该是这样的: >>> piApprox(1) 4.0 >>> piApprox(1
输入:图 G 输出:多个独立集,使得一个节点对所有独立集的成员资格是唯一的。因此,节点与它自己的集合中的任何节点都没有连接。这是一个示例路径。 由于这里需要澄清,因此再次改写: 将给定的图划分为多个集
我已经使用查找表和低阶多项式近似实现了定点 log2 函数,但对整个 32 位定点范围 [-1,+1) 的准确度不太满意。输入格式为 s0.31,输出格式为 s15.16。 我在这里发布这个问题,以便
大多数拥有CS学位的人当然会知道Big O stands for是什么。 它可以帮助我们评估算法的可扩展性。 但是我很好奇,您如何计算或估算算法的复杂性? 最佳答案 我会尽力在这里简单地解释它,但要注
我的目标是近似二项式变量总和的分布。我使用以下纸张The Distribution of a Sum of Binomial Random Variables作者:肯·巴特勒和迈克尔·斯蒂芬斯。 我想
我知道有方法 approximate cubic Bezier curves ( this page 也是一个很好的引用),但是有没有更快的方法来逼近 N 次贝塞尔曲线?还是只能使用下面的概括? 来自
大多数拥有CS学位的人当然会知道Big O stands for是什么。 它有助于我们评估算法的可扩展性。 但是我很好奇,您如何计算或估算算法的复杂性? 最佳答案 我会尽力在这里简单地解释它,但要注意
我是 C++ 和编码本身的初学者,所以请原谅任何词汇错误。我找不到这个具体问题,但在互联网上找到了类似的问题,但我仍然很难获得我需要的结果。 所以我使用莱布尼茨公式来近似 pi,即: pi = 4 ·
有多种方法可以通过显示名称查找联系人。例如这个答案Android - Find a contact by display name 但是我需要找到模糊匹配的联系人。例如如果找不到“Kim”,我需要返回
我一直在尝试使用以下代码使用级数表示来近似 e 以获得尽可能多的精度数字,但无论我计算多少项,精度数字的数量似乎都保持不变。即: 2.718281984329223632812500000000000
大多数拥有CS学位的人当然会知道Big O stands for是什么。 它可以帮助我们评估算法的可扩展性。 但是我很好奇,您如何计算或估算算法的复杂性? 最佳答案 我会尽力在这里简单地解释它,但要注
大多数拥有CS学位的人当然会知道Big O stands for是什么。 它可以帮助我们评估算法的可扩展性。 但是我很好奇,您如何计算或估算算法的复杂性? 最佳答案 我会尽力在这里简单地解释它,但要注
大多数拥有计算机科学学位的人肯定知道什么是Big O stands for。 它有助于我们衡量一个算法的实际效率,如果您知道在what category the problem you are try
大多数拥有计算机科学学位的人肯定知道什么是Big O stands for。 它有助于我们衡量一个算法的实际效率,如果您知道在what category the problem you are try
我做了很多随机的数学程序来帮助我完成作业(合成除法是最有趣的),现在我想反转一个激进的表达式。 例如,在我方便的 TI 计算器中我得到 .2360679775 好吧,我想将该数字转换为等效的无理数表达
我可以通过 CPU 分析器看到,compute_variances() 是我项目的瓶颈。 % cumulative self self total
大多数拥有 CS 学位的人肯定知道什么 Big O stands for . 它帮助我们衡量算法的可扩展性。 但我很好奇,你如何计算或近似算法的复杂性? 最佳答案 我会尽我所能用简单的术语在这里解释它
这是迄今为止我的代码, from math import * def main(): sides = eval(input("Enter the number of sides:"))
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
大多数拥有 CS 学位的人肯定知道什么 Big O stands for . 它帮助我们衡量算法的扩展性。 但我很好奇,你如何计算或近似算法的复杂性? 最佳答案 我会尽我所能用简单的术语在这里解释它,
我是一名优秀的程序员,十分优秀!