首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >大数据上使用模糊集的字符串相似度

大数据上使用模糊集的字符串相似度
EN

Code Review用户
提问于 2018-05-03 04:42:34
回答 2查看 9.9K关注 0票数 8

我有一个文件,在该文件中,我将检查特定列中名称中的字符串相似性。我使用模糊令牌排序比算法,因为它是我的用例所需要的。这是代码,有什么方法可以加快速度吗?30000张唱片花了很多时间。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import csv
import itertools
import pandas as pd
from fuzzywuzzy import fuzz

data = pd.read_csv('D:\\Sim_Input.csv')

Dishes = data['Product_Name']

threshold_ratio = 85

with open('D:\\Sim_Score.csv', 'w') as f1:
    writer = csv.writer(f1, delimiter='\t', lineterminator='\n', )
    writer.writerow(['tag4'])
    for str_1, str_2 in itertools.permutations(Dishes, 2):
        list = []
        ratio = (fuzz.token_sort_ratio(str_1, str_2))
        if ratio > threshold_ratio:
            row = (str_1, str_2, ratio)
            list.append(row)
            print(list)
            writer.writerow(list)

我需要一个csv文件的输出与名称的ItemA,ItemB和相似性评分,其中的相似性应该在85以上。

EN

回答 2

Code Review用户

回答已采纳

发布于 2018-05-04 07:31:15

为了避免对每一道菜进行多次处理,您可以使用它只处理一次:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dishes = ["pizza with bacon", "pizza with extra cheese", "vegetarian pizza", "cheese and bacon pizza", "bacon with pizza"]

processedDishes = []

for dish in dishes:
    processedDishes.append(fuzz._process_and_sort(dish, True, True))

for dish1, dish2 in itertools.combinations(enumerate(processedDishes), 2):  
    if fuzz.ratio(dish1[1], dish2[1]) >= 85:
        print(dishes[dish1[0]], dishes[dish2[0]])

然后,可以将其与@scnerd解决方案结合起来,以添加多处理。

如果您知道您的数据都是相同类型的,则可以进一步优化它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dishes = ["pizza with bacon", "pizza with extra cheese", "vegetarian pizza", "cheese and bacon pizza", "bacon with pizza"]

processedDishes = []
matchers = []

for dish in dishes:
    if dish:
        processedDish = fuzz._process_and_sort(dish, True, True)
        processedDishes.append(processedDish)
        matchers.append(fuzz.SequenceMatcher(None, processedDish))


for dish1, dish2 in itertools.combinations(enumerate(processedDishes), 2):
    matcher = matchers[dish1[0]]
    matcher.set_seq2(dish2[1])
    ratio = int(round(100 * matcher.ratio()))

    if ratio >= 85:
        print(dishes[dish1[0]], dishes[dish2[0]])

Update:检查了这些比率是如何计算的,这里有一个更有效的答案,它避免了对之间的大量检查:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dishes = ["pizza with bacon", "pizza with extra cheese", "vegetarian pizza", "cheese and bacon pizza", "bacon with pizza", "a"]


processedDishes = []
matchers = []

for dish in dishes:
    if dish:
        processedDish = fuzz._process_and_sort(dish, True, True)
        processedDishes.append({"processed": processedDish, "dish": dish})


processedDishes.sort(key= lambda x: len(x["processed"]))

for idx, dish in enumerate(processedDishes):
    length = len(dish["processed"])
    matcher = fuzz.SequenceMatcher(None, dish["processed"])
    for idx2 in range(idx + 1, len(processedDishes)):
        dish2 = processedDishes[idx2]
        if 2 * length / (length + len(dish2["processed"])) < 0.85: # upper bound
            break

        matcher.set_seq2(dish2["processed"])

        if matcher.quick_ratio() >= 0.85 and matcher.ratio() >= 0.85: # should also try without quick_ratio() check
            print(dish["dish"], dish2["dish"])
票数 4
EN

Code Review用户

发布于 2018-05-03 09:56:25

第一个算法建议是使用itertools.combinations而不是.permutations,因为您不关心订单。这假定为fuzz.token_sort_ratio(str_1, str_2) == fuzz.token_sort_ratio(str_2, str_1)。有一半的组合,因为有排列,所以这给你一个免费的2x加速比。

这段代码也很容易并行化。在i7 (8个虚拟核,4个物理核)上,您可能会期望这会给您带来4-8x的加速,但这取决于许多因素。要做到这一点,最不麻烦的方法是使用multiprocessing.Pool.map.imap_unordered

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import multiprocessing as mp

def ratio(strings):
    s1, s2 = strings
    return s1, s2, fuzz.token_sort_ratio(s1, s2)

with open('D:\\Sim_Score.csv', 'w') as f1:
    writer = csv.writer(f1, delimiter='\t', lineterminator='\n', )
    writer.writerow(['tag4'])

    with mp.Pool() as pool:
        for s1, s2, r in pool.imap_unordered(ratio, itertools.combinations(Dishes, 2)):
            if r > threshold_ratio:
                writer.writerow([(s1, s2, r)])

总之,我预计这些变化会给你5-10倍的加速,这在很大程度上取决于你可用的核心数量。

作为参考,生成器理解版本可能如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
with mp.Pool() as pool:
    writer.writerows((s1, s2, r)
                     for s1, s2, r in pool.imap_unordered(ratio, itertools.combinations(Dishes, 2))
                     if r > threshold_ratio)

与非理解版本相比,该版本的性能有了一些提高,但几乎没有提高,而IMO更难阅读/维护。

我在测试代码时注意到的另一件小事是,fuzzywuzzy建议安装python-Levenshtein以便更快地运行;当我这样做时,它的运行速度比使用内置SequenceMatcher时慢20倍。当我卸载python-Levenshtein时,它又恢复了速度。这在我看来很奇怪,但这肯定是值得一试的。

最后,如果性能很重要,您可以考虑深入了解fuzz.token_sort_ratio所做的工作,看看是否可以删除一些重复的工作。例如,每次传入每个字符串时,它都会再次对其进行标记化和排序,因此您可能可以对字符串进行预标记/排序,并且只在主循环中运行比率逻辑。快速挖掘告诉我,token_sort_ratio是两个主要步骤:

  1. 使用fuzz._process_and_sort对每个字符串进行预处理
  2. 对已处理的字符串运行fuzz.partial_ratio

目前我无法让这个方法运行得更快,但是如果我能让这个方法运行得很好,我将编辑和更新这个答案。

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

https://codereview.stackexchange.com/questions/193567

复制
相关文章
Python字符串相似度检测
python自带的字符串相似度检测库 difflib query_str = '市公安局' s1 = '广州市邮政局' s2 = '广州市公安局' s3 = '广州市检查院' print(difflib.SequenceMatcher(None, query_str, s1).quick_ratio()) print(difflib.SequenceMatcher(None, query_str, s2).quick_ratio()) print(difflib.SequenceMatcher(No
98k
2019/03/22
2K0
相似度计算——余弦相似度
余弦相似度是利用两个向量之间的夹角的余弦值来衡量两个向量之间的相似度,这个值的范围在-1到1之间。
鳄鱼儿
2024/05/21
5290
相似度计算——余弦相似度
NLP 点滴 :文本相似度 (上)
文章主要讲述了如何通过自然语言处理技术,如词向量、文本分类、情感分析等,来对文本进行相似性分析。同时,文章也介绍了一些具体的应用场景,如搜索引擎、文本分类、情感分析等。
肖力涛
2017/08/22
5.4K1
NLP 点滴 :文本相似度 (上)
计算字符串相似度算法——Levenshtein
Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。
shirayner
2018/09/20
7.4K0
pta集合相似度_结构相似度
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168948.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/22
6700
文本相似度 | 余弦相似度思想
我一直觉得,在数据分析领域,只有文本分析是最“接地气儿”的,“接地气儿”不是指最简单,而是我们普通大众的使用它最多。 我们每天使用互联网,但不一定每个人都炒股,不一定都做行业研究,也不一定都搞科研,因此那些高大上的模型对大部分人来说都是飘忽在天上的,只有文本分析,他的产出结果是直接惠及到几乎全部人。 比如,你总得打字,会使用到输入法的模糊匹配;你总得网购,刷新页面的时候就会看到某宝给你推荐的产品;你总得看新闻,APP会根据你以往的输入给你推荐文章...... 文本分析最基本的可以看正则表达式,我曾经写过S
数说君
2018/04/08
2.8K0
文本相似度 | 余弦相似度思想
php计算字符串相似度similar_text
因为发送邮件要限制发送频率,有一些邮件都是同类型的邮件,只是时间不一样,这样就需要判断发送邮件内容的相似度。网上找了相关方法,发现这个 similar_text 是可以用的,而且很好用,不会有计算不准的情况。有时候不自己试试,真的很容易被网上的言论误导。
猿哥
2019/11/27
1.6K0
Delphi源码:编辑长求字符串相似度
 说明 LD(s,t:WideString):Integer 返回两个字符串的编辑长
全栈程序员站长
2021/06/22
8410
计算相似度
在机器学习中,经常要度量两个对象的相似度,例如k-最近邻算法,即通过度量数据的相似度而进行分类。在无监督学习中,K-Means算法是一种聚类算法,它通过欧几里得距离计算指定的数据点与聚类中心的距离。在推荐系统中,也会用到相似度的计算(当然还有其他方面的度量)。
老齐
2021/03/11
4.3K0
计算相似度
python衡量数据分布的相似度/距离(KL/JS散度)
很多场景需要考虑数据分布的相似度/距离:比如确定一个正态分布是否能够很好的描述一个群体的身高(正态分布生成的样本分布应当与实际的抽样分布接近),或者一个分类算法是否能够很好地区分样本的特征(在两个分类下的数据分布的差异应当比较大)。
blmoistawinde
2019/10/30
9.4K3
余弦相似度与欧氏距离相似度(比较记录)
余弦相似度衡量的是维度间取值方向的一致性,注重维度之间的差异,不注重数值上的差异,而欧氏度量的正是数值上的差异性。
海涛
2020/06/04
3.1K0
使用Faiss进行海量特征的相似度匹配
来源丨https://zhuanlan.zhihu.com/p/210736523
公众号机器学习与AI生成创作
2021/01/08
3.9K0
使用Faiss进行海量特征的相似度匹配
图的度计算和相似度计算
对于一个无向图,节点的度数表示该节点连接的边的数量。可以通过以下公式计算某个节点的度数:
一凡sir
2023/10/29
9050
图的度计算和相似度计算
字符串相似度算法-莱文斯坦距离算法
莱文斯坦距离可以解决字符串相似度的问题。 在莱文斯坦距离中,对每一个字符都有三种操作:删除、添加、替换 例如有s1和s2两个字符串,a和b是与之对应的保存s1和s2全部字符的数组,i/j是数组下标。莱文斯坦距离的含义,是求将a变成b(或者将b变成a),所需要做的最小次数的变换。
py3study
2020/01/06
2.9K0
c#计算2个字符串的相似度
直接来代码 public static float levenshtein(string str1, string str2) { //计算两个字符串的长度。 int len1 = str1.Length; int len2 = str2.Length; //建立上面说的数组,比字符长度大一个空间 int[,] dif = new int[len1 + 1, l
冰封一夏
2019/09/11
1.6K0
文本相似度计算_文本相似度分析算法
一. Simhash 计算文档相似度的算法, 比如用在搜索引擎的爬虫系统中,收录重复的网页是毫无意义的,只会造成存储和计算资源的浪费。有时候我们需要处理类似的文档,比如新闻,很多不同新闻网的新闻内容十分相近,标题略有相似。如此问题,便可以应用Simhash 文档相似度算法,查看两篇文档相似程度,删去相似度高的web文档。
全栈程序员站长
2022/11/15
1.5K0
文本相似度计算_文本相似度分析算法
[文本语义相似] 基于Jaccard相似度
文本相似在问答系统中有很重要的应用,如基于知识的问答系统(Knowledge-based QA),基于文档的问答系统(Documen-based QA),以及基于FAQ的问答系统(Community-QA)等。像 对于问题的内容,需要进行相似度匹配,从而选择出与问题最接近,同时最合理的答案。本节介绍 基于Jaccard相似度。
MachineLP
2020/05/08
1.2K0
句子相似度计算
Word2Vec将词映射为一个词向量,在这个向量空间中,语义相似的词之间距离会比较小,而词移距离(WMD)正是基于word2vec的这一特性开发出来的。 两个文档中的任意两个词所对应的词向量求欧氏距离然后再加权求和
DC童生
2019/07/11
2.5K0
句子相似度计算
ES搜索相似度
比如上面的hello在在doc1出现了1次,会根据出现的次数给个分数,一个term在doc中出现的次数越多,分数就越高
小土豆Yuki
2022/06/24
1.1K0
[文本语义相似] 基于simhash相似度
文本相似在问答系统中有很重要的应用,如基于知识的问答系统(Knowledge-based QA),基于文档的问答系统(Documen-based QA),以及基于FAQ的问答系统(Community-QA)等。像 对于问题的内容,需要进行相似度匹配,从而选择出与问题最接近,同时最合理的答案。本节介绍 基于simhash相似度。
MachineLP
2020/05/08
1.1K0

相似问题

字符串相似度计算

10

在相似度> 90%的列表中搜索字符串

10

实现模糊匹配字符串的Jaro相似度的代码

10

Python中WSD最大相似度的优化

10

基于Jaro算法的C++编辑距离/字符串相似度函数

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文