FuzzyWuzzy用于Python中非常相似的记录



我有一个数据集,我想找到最匹配的字符串。为此,我以这种方式使用FuzzyWuzzy

sol=process.extract(t,dev2,scorer=fuzz.token_sort_ratio)

其中t是字符串,dev2是要比较的列表。我的问题是,有时它有非常相似的记录,而FuzzyWuzzy提供的选项似乎缺乏。我已经用token_sort、token_set、partial_token排序和设置、ratio、partial_ratio和WRatio进行了测试。

例如,字符串Italy - Serie A给出了以下两个最接近的匹配项。

Token_sort_ratio: (92, 'Italy - Serie D');(86, 'Italian - Serie A')

想要的显然是第二个,但每个角色都更接近第一个,这是一个不同的联盟。

这种情况在团队中也会发生。假设我有一个字符串Buchtholz,我会在得到TSV Buchtholz之前得到Buchtholz II

我现在的主要猜测是,尝试对几个字符的存在和不存在进行更重的加权,比如字符串末尾的单个大写字母,所以如果字母或不存在有差异,则加权为不太接近。或用于()和特殊字符。

我不知道是否有办法考虑到这一点,或者你们有更好的方法来获得真正匹配的字符串。

相似性匹配通常需要了解所分析的数据。即它不仅仅是盲的单轮匹配。我建议你通过更多的匹配步骤来传递你的结果,从低截止分数的包容/乐观方法(如token_set_ratio(开始,再到高截止分数的更排外/悲观方法,直到你有了明确的赢家。如果您对正在分析的文本了解更多,您甚至可以在进行过程中修改字符串。

在我研究的一个案例中,我对货物的运动描述进行了相似性匹配。在描述中,数字序列比文本更重要。例如,当为"SLRRY VALVE 250MM RAGMAX 2000"寻找匹配项时,字符串的250和2000部分很重要,否则我会得到"SLRRy VALVE 50MM RAGMAX 2000'"作为最佳匹配项,而不是"VALVE B/F 250MM,RAGMAX 250RAG2000 RAGON",这是一个更好的结果。

我将相似性匹配过程分为两个步骤:1。使用乐观匹配得分手(token_set_ratio(2获得一组类似的匹配。获得这些结果的数字序列,并将它们与更严格的得分手(tokensort_ratio(进行另一轮匹配。在上面的例子中,这样做给了我更好的结果。

以下是一些可能有帮助的代码块:

这里有一个从序列中获取数字的函数。(在您的情况下,您可能会使用它来从字符串中排除数字?(

def get_numbers_from_string(description):   
numbers = ''.join((ch if ch in '0123456789.-' else ' ') for ch in description)
numbers = ' '.join([nr for nr in numbers.split()])
return numbers

这是我用来通过两轮描述匹配的代码的一部分:

try:    
# get close match from goods move that has material numbers
df_material = pd.DataFrame(process.extract(description, 
corpus_material,
scorer=fuzz.token_set_ratio), 
columns=['Similar Text','Score']
)
if df_material['Score'][df_material['Score']>=cut_off_accuracy_materials].count()>=1:
similar_text = df_material['Similar Text'].iloc[0]
score = df_material['Score'].iloc[0]
if nr_description_numbers>4:
# if there are multiple matches found, then get best number combination match  
df_material = df_material[df_material['Score']>=cut_off_accuracy_materials]
new_corpus = list(df_material['Similar Text'])
new_corpus = np.vectorize(get_numbers_from_string)(new_corpus)
df_material['numbers'] = new_corpus
df_numbers = pd.DataFrame(process.extract(description_numbers, 
new_corpus,
scorer=fuzz.token_sort_ratio), 
columns=['numbers','Score']
)
similar_text = df_material['Similar Text'][df_material['numbers']==df_numbers['numbers'].iloc[0]].iloc[0]
nr_score = df_numbers['Score'].iloc[0]

希望它能有所帮助,祝好运

最新更新