標籤:fas target eve setup env special www deletion 期望
編輯距離定義:
編輯距離,又稱Levenshtein距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。
許可的編輯操作包括:將一個字元替換成另一個字元,插入一個字元,刪除一個字元。
例如將eeba轉變成abac:
- eba(刪除第一個e)
- aba(將剩下的e替換成a)
- abac(在末尾插入c)
所以eeba和abac的編輯距離就是3
俄羅斯科學家Vladimir Levenshtein在1965年提出這個概念。
演算法:
演算法就是簡單的線性動態規劃(最長上升子序列就屬於線性動態規劃)。
設我們要將s1變成s2
定義狀態矩陣edit[len1][len2],len1和len2分別是要比較的字串s1和字串s2的長度+1(+1是考慮到動歸中,一個串為空白的情況)
然後,定義edit[i][j]是s1中前i個字元組成的串,和s2中前j個字元組成的串的編輯距離
具體思想是,對於每個i,j從0開始依次遞增,對於每一次j++,由於前j-1個字元跟i的編輯距離已經求出,所以只用考慮新加進來的第j個字元即可
插入操作:在s1的前i個字元後插入一個字元ch,使得ch等於新加入的s2[j]。於是插入字元ch的編輯距離就是edit[i][j-1]+1
刪除操作:刪除s1[i],以期望s1[i-1]能與s2[j]匹配(如果s1[i-1]前邊的幾個字元能與s2[j]前邊的幾個字元有較好的匹配,那麼這麼做就能得到更好的結果)。另外,對於s1[i-1]之前的字元跟s2[j]匹配的情況,edit[i-1][j]中已經考慮過。於是刪除字元ch的編輯距離就是edit[i-1][j]+1
替換操作:期望s1[i]與s2[j]匹配,或者將s1[i]替換成s2[j]後匹配。於是替換操作的編輯距離就是edit[i-1][j-1]+f(i,j)。其中,當s1[i]==s2[j]時,f(i,j)為0;反之為1
於是動態規劃公式如下:
- if i == 0 且 j == 0,edit(i, j) = 0
- if i == 0 且 j > 0,edit(i, j) = j
- if i > 0 且j == 0,edit(i, j) = i
- if 0 < i ≤ 1 且 0 < j ≤ 1 ,edit(i, j) == min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) },當第一個字串的第i個字元不等於第二個字串的第j個字元時,f(i, j) = 1;否則,f(i, j) = 0。
Python實現:
官方擴充包:
python有一個官方擴充包(在pypi裡面,即python package index),叫做python-Levenshtein,這個包不僅可以計算編輯距離,還能計算hamming(漢明)距離,Jaro-Winkler距離等,連結如下:
https://pypi.python.org/pypi/python-Levenshtein
下載python-Levenshtein-0.10.2.tar.gz,解壓後,cd到解壓後的檔案夾,執行:
python setup.py build
python setup.py install
即可。
注意:如果沒有安裝setuptools的話要先安裝setuptools,連結如下:
https://pypi.python.org/pypi/setuptools/
下載setuptools 0.6c11即可,解壓後,cd到對應目錄,執行:
python setup.py build
python setup.py install
即可。
檢查是否安裝成功:進入python,執行from Levenshtein import *,如果沒有報錯則安裝成功
具體使用方法見如下博文(這邊博文下方還有完整的使用文檔的串連):
http://www.cnblogs.com/kaituorensheng/archive/2013/05/18/3085653.html
注意:如果採用from Levenshtein import *匯入,則調用函數的時候不用加Levenshtein.
例如:直接調用distance(str1, str2)即可計算編輯距離
簡單的實現代碼:
如果你想要更加輕量級的實現的話,就用下面的代碼吧:
(選自邊蘇濤的部落格,http://biansutao.iteye.com/blog/326008)
[python] view plain copy
- #!/user/bin/env python
- # -*- coding: utf-8 -*-
-
- class arithmetic():
-
- def __init__(self):
- pass
- ‘‘‘‘‘ 【編輯距離演算法】 【levenshtein distance】 【字串相似性演算法】 ‘‘‘
- def levenshtein(self,first,second):
- if len(first) > len(second):
- first,second = second,first
- if len(first) == 0:
- return len(second)
- if len(second) == 0:
- return len(first)
- first_length = len(first) + 1
- second_length = len(second) + 1
- distance_matrix = [range(second_length) for x in range(first_length)]
- #print distance_matrix
- for i in range(1,first_length):
- for j in range(1,second_length):
- deletion = distance_matrix[i-1][j] + 1
- insertion = distance_matrix[i][j-1] + 1
- substitution = distance_matrix[i-1][j-1]
- if first[i-1] != second[j-1]:
- substitution += 1
- distance_matrix[i][j] = min(insertion,deletion,substitution)
- print distance_matrix
- return distance_matrix[first_length-1][second_length-1]
-
- if __name__ == "__main__":
- arith = arithmetic()
- print arith.levenshtein(‘GUMBOsdafsadfdsafsafsadfasfadsfasdfasdfs‘,‘GAMBOL00000000000dfasfasfdafsaf
編輯距離演算法(Levenshtein)