FuzzyWuzzy Python库
在本教程中,我们将学习如何使用Python内置的 fuzzyWuzzy 库匹配字符串,并使用各种示例确定它们之间的相似度。
介绍
Python 提供了几种比较两个字符串的方法。下面是几种主要的方法。
- 使用正则表达式
- 简单比较
- 使用dfflib
但是还有另一种可以有效比较的方法,称为 fuzzywuzzy。 这种方法在区分两个稍微不同的字符串是非常有效的,但它们指的是同一件事。有时我们需要一个能够自动识别错误拼写的程序。
它是一种查找与给定模式匹配的字符串的过程。它使用 Levenshtein距离 计算序列之间的差异。
这个库可以帮助映射缺乏公共键的数据库,比如通过公司名称将两个表连接起来,而这些表在两个表中的出现形式不同。
示例
让我们看以下示例。
Str1 = "Welcome to Javatpoint"
Str2 = "Welcome to Javatpoint"
Result = Str1 == Str2
print(Result)
输出:
True
上面的代码返回true,因为字符串完全匹配(100%)。但如果我们在str2中进行更改会怎么样。
Str1 = "Welcome to Javatpoint"
Str2 = "welcome to Javatpoint"
Result = Str1 == Str2
print(Result)
输出:
False
这里的上述代码返回了false,并且字符串在人眼中看起来非常相似,但解释器却不是这样。然而,我们可以通过将两个字符串都转换为小写来解决这个问题。
Str1 = "Welcome to Javatpoint"
Str2 = "welcome to Javatpoint"
Result = Str1.lower() == Str2.lower()
print(Result)
输出:
True
但是如果我们改变字符集,我们将遇到另一个问题。
Str1 = "Welcome to javatpoint."
Str2 = "Welcome to javatpoint"
Result = Str1.lower() == Str2.lower()
print(Result)
输出:
True
为了解决这种问题,我们需要更有效的工具来比较字符串。而fuzzywuzzy是计算字符串最佳的工具。
Levenshtein距离
Levenshtein距离用于计算两个字符串序列之间的距离。它计算给定字符串中需要更改的最小编辑次数。这些编辑可以是插入、删除或替换。
示例
import numpy as np
def levenshtein_distance (s1, t1, ratio_calculation = False):
# Initialize matrix of zeros
rows = len(s1)+1
cols = len(t1)+1
calc_distance = np.zeros((rows,cols),dtype = int)
# Populate matrix of zeros with the indeces of each character of both strings
for i in range(1, rows):
for k in range(1,cols):
calc_distance[i][0] = i
calc_distance[0][k] = k
for col in range(1, cols):
for row in range(1, rows):
if s1[row-1] == t1[col-1]:
cost = 0
if ratio_calculation == True:
cost = 2
else:
cost = 1
calc_distance[row][col] = min(calc_distance[row-1][col] + 1, # Cost of deletions
calc_distance[row][col-1] + 1, # Cost of insertions
calc_distance[row-1][col-1] + cost) # Cost of substitutions
if ratio_calculation == True:
# Computation of the Levenshtein calc_distance Ratio
Ratio = ((len(s)+len(t)) - calc_distance[row][col]) / (len(s)+len(t))
return Ratio
else:
return "The strings are {} edits away".format(calc_distance[row][col])
我们将在之前的示例中使用上面的函数,我们试图将”Welcome to javatpoint.”与”Welcome to javatpoint”进行比较。我们可以看到两个字符串很可能是相同的,因为 Levensthtein的 长度很小。
Str1 = "Welcome to Javatpoint"
Str2 = "welcome to Javatpoint"
Distance = levenshtein_distance(Str1,Str2)
print(Distance)
Ratio = levenshtein_distance(Str1,Str2,ratio_calc = True)
print(Ratio)
FuzzyWuzzy库
这个库的名字很奇怪又有趣,但它很有用。它有一种独特的方法来比较两个字符串,并返回匹配度的分数(最高100)。要使用这个库,我们需要在Python环境中安装它。
安装
我们可以使用pip命令来安装这个库。
pip install fuzzywuzzy
Collecting fuzzywuzzy
Downloading fuzzywuzzy-0.18.0-py2.py3-none-any.whl (18 kB)
Installing collected packages: fuzzywuzzy
Successfully installed fuzzywuzzy-0.18.0
现在输入以下命令并按回车键。
pip install python-Levenshtein
让我们了解fuzzuwuzzy库的以下方法。
Fuzz模块
fuzz模块用于一次比较两个给定的字符串。它使用不同的方法进行比较,返回一个0到100的得分。
Fuzz.ratio()
这是fuzz模块的一个重要方法之一。它根据给定字符串的匹配程度对字符串进行比较并得分。让我们了解以下示例。
示例
from fuzzywuzzy import fuzz
Str1 = "Welcome to Javatpoint"
Str2 = "welcome to javatpoint"
Ratio = fuzz.ratio(Str1.lower(),Str2.lower())
print(Ratio)
输出:
100
如上所示的代码, fuzz.ratio() 方法返回了分数,这意味着字符串之间的差异非常小。
Fuzz.partial_ratio()
fuzzywuzzy 库提供了另一个强大的方法 – partial_ratio() 。它用于处理复杂的字符串比较,如子字符串匹配。让我们看下面的示例。
示例 –
#importing the module from the fuzzywuzzy library
from fuzzywuzzy import fuzz
str1 = "Welcome to Javatpoint"
str2 = "tpoint"
Ratio = fuzz.ratio(str1.lower(),str2.lower())
Ratio_partial = fuzz.partial_ratio(str1.lower(),str2.lower())
print(Ratio)
print(Ratio_partial)
输出:
44
100
解释:
partial_ratio() 方法可以检测子字符串。因此,它产生了100%的相似度。它遵循部分逻辑,当短字符串 k 和长字符串 m 时,算法找到最佳匹配的长度为 k 的子字符串。
Fuzz.token_sort_ratio
该方法不能保证得到准确的结果,因为如果我们改变字符串的顺序,它可能不能给出准确的结果。
但是 fuzzywuzzy 模块提供了解决方案。让我们理解以下示例。
示例
str1 = "united states v. nixon"
str2 = "Nixon v. United States"
Ratio = fuzz.ratio(str1.lower(),str2.lower())
Ratio_Partial = fuzz.partial_ratio(str1.lower(),str2.lower())
Ratio_Token = fuzz.token_sort_ratio(str1,str2)
print(Ratio)
print(Ratio_Partial)
print(Ratio_Token)
输出:
59
74
100
解释:
在上面的代码中,我们使用了 token_sort_ratio() 方法,它比partial_ratio方法更为优越。在这个方法中,字符串按字母顺序进行排序并连接在一起。但是如果字符串的长度差异很大,可能会有另一种情况。
让我们来了解以下示例。
示例:
str1 = "The supreme court case of Democratic vs Congress"
str2 = "Congress v. Democratic"
Ratio = fuzz.ratio(str1.lower(),str2.lower())
Partial_Ratio = fuzz.partial_ratio(str1.lower(),str2.lower())
Token_Sort_Ratio = fuzz.token_sort_ratio(str1,str2)
Token_Set_Ratio = fuzz.token_set_ratio(str1,str2)
print(Ratio)
print(Partial_Ratio)
print(Token_Sort_Ratio)
print(Token_Set_Ratio)
输出:
40
64
61
95
在上面的代码中,我们使用了另一种方法 fuzz.token_set_ratio() ,该方法执行一个集合操作,取出公共令牌,然后进行ratio()成对比较。
排序令牌的交集总是相同的,因为子字符串或较小的字符串由原始字符串的较大块或剩余的令牌更接近彼此。
fuzzywuzzy包提供了 process 模块,允许我们计算具有最高相似度的字符串。让我们理解以下示例。
示例
from fuzzywuzzy import process
strToMatch = "Hello Good Morning"
givenOpt = ["hello","Hello Good","Morning","Good Evenining"]
ratios = process.extract(strToMatch,givenOpt)
print(ratios)
# We can choose the string that has highest matching percentage
high = process.extractOne(strToMatch,givenOpt)
print(high)
输出:
[('hello', 90), ('Hello Good', 90), ('Morning', 90), ('Good Evenining', 59)]
('hello', 90)
上述代码将返回给定字符串列表的最高匹配百分比。
Fuzz.WRatio
该进程模块还提供了 WRatio ,它提供比简单比率更好的结果。它处理大小写字母和其他一些参数。让我们理解以下示例。
示例
from fuzzywuzzy import process
fuzz.WRatio('good morning', 'Good Morning')
fuzz.WRatio('good morning!!!','good Morning')
输出:
100
结论
在本教程中,我们讨论了如何匹配字符串并确定它们之间的相似程度。我们展示了一些简单的示例,足以说明计算机如何处理不匹配的字符串。许多实际应用,例如拼写检查、生物信息学的匹配和DNA序列等,都基于模糊逻辑。