Python 大规模字符串比较
我试图在一个大的字符串集中找到相似的字符串对。我有大约1亿个字符串,字符串相似性是以编辑距离来衡量的。例如,“这是一个句子”和“这也是一个句子”是相似的 计算两个字符串之间的相似性是不实际的,因此会产生100M x 100M的计算结果。我正在考虑一种分而治之的策略,首先将字符串分组为“大致相似”的子集,然后计算子集内的每个字符串对。例如,假设我有以下5个字符串Python 大规模字符串比较,python,string-comparison,large-data,Python,String Comparison,Large Data,我试图在一个大的字符串集中找到相似的字符串对。我有大约1亿个字符串,字符串相似性是以编辑距离来衡量的。例如,“这是一个句子”和“这也是一个句子”是相似的 计算两个字符串之间的相似性是不实际的,因此会产生100M x 100M的计算结果。我正在考虑一种分而治之的策略,首先将字符串分组为“大致相似”的子集,然后计算子集内的每个字符串对。例如,假设我有以下5个字符串 str1 = "this is a sentence" str2 = "this is also a sentence" str3 =
str1 = "this is a sentence"
str2 = "this is also a sentence"
str3 = "Mary loves elephants"
str4 = "Mary loves an elephant"
str5 = "Mark loves elephants"
我希望有一个子集[str1,str2]和另一个子集[str3,str4,str5]。然后我将比较str1和str2,看看它们是否相似。我还将比较str3、str4和str5,以找到类似的一对。计算总量将从C^2_5=10减少到C^2_2+C^2_3=4
分割需要快速,因此不需要精确。子集可以重叠。如果偶尔一个字符串的相似对不包括在同一个子集中,这是可以接受的,-那么我将扫描一个接近的子集中
我试图找到一个保留顺序的散列方法来粗略地将字符串映射到整数(冲突并不重要),并根据具有接近整数的候选字符串检查每个字符串。但我没有找到这样的算法
我正在使用Python,如果解决方案只适用于另一种编程语言,我愿意尝试
非常感谢。您可以在排序时使用Levenshtein距离作为关键函数
import requests
import Levenshtein as L
def download_moby_dick():
moby_dick_url = 'https://www.gutenberg.org/files/2701/2701-0.txt'
return requests.get(moby_dick_url).text
def sentences_in_book(book):
sentences = (s for s in re.split(r'[.;?!]\s|\r\n\r\n', moby_dick))
sentences = (re.sub('\s+', ' ', s).strip() for s in sentences)
sentences = (s for s in sentences if len(s) > 10)
return list(sentences)
sentences = sentences_in_book(download_moby_dick())
# sort by length
sentences.sort(key=len)
# median length sentence
target = sentences[len(sentences)//2]
# sort by levenshtein distance to target
def keyfunc(sentence):
return L.distance(target, sentence)
sentences.sort(key=keyfunc)
这将给出一个大致的顺序,将相似的句子组合在一起。为了加快速度,您可能需要进一步分解任务。例如,只使用每个单词中的一些字母来缩写输入句子,只搜索长度大致相同的句子,等等。听起来与我曾经遇到的求职面试任务非常相似。@goodvibration您能回忆一些解决方案吗?我面临的任务是整合两个科学出版物库,每个库包含约1亿学术论文标题。我计划除以出版年限,比较论文标题,希望进一步减少计算量。如果python不够快,可以尝试使用postgresql。它内置了对levenshtein和trigram搜索的支持。结合索引,它应该比纯python解决方案快得多。有一些python适配器和ORM用于使用带有python代码的postgresql。谢谢。这是一个很好的分割方法,将字符串映射为整数,以确保相似的字符串是相近的。对于非常大的字符串列表的初始排序,可能有其他算法比Levenshtein更快,可能会以精度为代价。您可能希望对该包中可用的算法进行基准测试。