我正在使用一个函数来比较两个数据帧的句子,并提取具有最高相似性的值和句子:
df1
:包含40,000个句子df2
:包含400个句子将的每个句子df1
与的400个句子进行比较df2
,该函数返回一个元组,其中包含具有最高值和值的句子。如果返回的值小于96,则返回具有两个None
值的元组。
我尝试了不同的算法来比较句子(spacy
和nltk
),但是通过使用fuzzywuzzy.process
-instance及其process.extractOne(text1, text2)
-method和dask
进行划分df1
(分为4个分区),我发现了在处理时间方面的最佳结果。在内部,extractOne()
我使用option score_cutoff = 96
,仅返回值>= 96
,其想法是,一旦>= 96
找到一个值,该函数就不必遍历整个对象df2
,但这似乎并不起作用。
我还尝试了df2
在函数内部进行分区,但是处理时间并不比使用列表推导迭代的时间要好df2
(在代码中有注释)。
这是我的代码:
def similitud( text1 ):
a = process.extractOne( text1,
[ df2['TITULO_PROYECTO'][i]
for i in range( len( df2 ) )
],
score_cutoff = 96
)
"""
a = process.extractOne( text1,
ddf2.map_partitions( lambda df2:
df2.apply( lambda row:
#row['TITULO_PROYECTO'],
axis = 1
),
meta = 'str'
).compute( sheduler = 'processses' ),
score_cutoff #= 96
)
"""
return ( None, None ) if a == None else a
tupla_values = ddf1.map_partitions( lambda df1:
df1.progress_apply( ( lambda row:
similitud( row['TITULO_PROYECTO'] )
),
axis = 1
),
meta = 'str'
).compute( scheduler = 'processes' )
如何找到减少处理时间的解决方案?
FuzzyWuzzy并不真正关心该score_cutoff
参数。它将简单地遍历所有元素,然后搜索得分最高的元素,并在得分高于您的score_cutoff
阈值时返回。
您应该尝试使用RapidFuzz (我是作者)进行相同的操作,它提供了非常相似的界面。作为区别,process.extractOne()
-方法返回与一个元组choice
,并score
在FuzzyWuzzy,
而它返回一个元组choice
,score
将和index
在RapidFuzz。
RapidFuzz使用Levenshtein距离的一些快速近似值,保证返回的分数> =标准化Levenshtein距离的实际分数。当保证分数低于score_cutoff时,可以使用这些快速逼近来提前退出而无需执行昂贵的Levenshtein计算。但是,它也无法score_cutoff
在process.extractOne()
处理中找到分数高于第一个的元素后退出,因为它会搜索极限值,以找到高于score_cutoff
阈值的真正最佳匹配项(但是如果找到一个匹配项,它将尽早退出)得分为100的第一场比赛)。
同样similitud()
,由于FuzzyWuzzy和RapidFuzz都接受DataSeries,因此您也无需创建列表,所有列表都包含在内。因此,您可以使用类似以下的内容:
from rapidfuzz import process
def similitud( text1 ):
a = process.extractOne( text1,
df2['TITULO_PROYECTO'],
score_cutoff = 96
)
return ( None, None ) if a is None else ( a[0], a[1] )
process.extractOne()
始终会通过对字符串进行小写来对其进行预处理,将非标点符号等非字母数字字符替换为空格,并从字符串的开头和结尾删除空格。
您可以df2
预先对数据进行预处理,因此不必对要df1
比较的每个元素进行此处理。之后,您只能df1
在每次迭代中预处理的元素:
from rapidfuzz import process, utils
def similitud( text1 ):
a = process.extractOne( utils.default_process( text1 ),
df2['PROCESSED_TITULO_PROYECTO'],
processor = None,
score_cutoff = 96
)
return ( None, None ) if a is None else ( a[0], a[1] )
我最近创建了一个基准测试,process.extractOne()
用于比较FuzzyWuzzy
-module(使用Python-Levenshtein)和RapidFuzz
-module(可以在此处找到)。
可再生科学数据的来源:
titledata.csv
来自FuzzyWuzzy(具有2764个标题的数据集,最大选择长度:2500)上面绘制的基准测试的硬件在(规格)上运行:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句