Levenshtein distance(編輯距離)

基本介紹

Levenshtein distance是一種度量?jī)蓚€(gè)序列(字符串)差異大小的方法骇吭。

該方法定義如下:
兩個(gè)序列(以單詞為例歧寺,這里序列也可以表示一個(gè)句子)的Levenshtein distance是在使用一個(gè)單詞修改為另一個(gè)單詞時(shí)斜筐,通過(guò)編輯單個(gè)字符(如插入,刪除目代,修改)所需要的最小次數(shù)像啼。

這個(gè)概念由俄羅斯數(shù)學(xué)家Vladimir Levenshtein于1965年提出潭苞。目前這個(gè)距離常用來(lái)評(píng)價(jià)字符識(shí)別任務(wù)的好壞此疹。

舉個(gè)例子

將單詞“kitten”修改為“sitting”最少需要3次單字符的操作:

  1. kitten -> sitten(將“k”改為“s”)
  2. sitten -> sittin(將“e”改為“i”)
  3. sittin -> sitting(將“g”刪除)

原理

假設(shè)現(xiàn)在兩個(gè)字符串A和B蝗碎,其中A的長(zhǎng)度為a蹦骑,B的長(zhǎng)度為b,現(xiàn)要計(jì)算A與B之間的Levenshtein distance

我們可以考慮使用動(dòng)態(tài)規(guī)劃的思想解決這個(gè)問(wèn)題

假設(shè)A_{i}B_{j}分別為字符串A边败、B的前i捎废、j個(gè)字符組成的子串登疗,現(xiàn)在我們來(lái)看看將
A_{i}:A[1]\quad A[2] \quad ...\quad A[i-1]\quad A[i]
修改為
B_{j}:B[1]\quad B[2] \quad ... \quad B[j-1]\quad B[j]
需要的最少編輯次數(shù),即兩個(gè)子串的Levenshtein distance脱吱,下面我們來(lái)分別討論三種操作的操作次數(shù):

  1. 插入操作

假設(shè)將A[1...i]修改為B[1...j-1]需要操作數(shù)為op_{1}急凰,那么在A[i]后插入一個(gè)字符B[j],這樣就可以將A[1...i]修改為B[1...j]乔外,這時(shí)所需要的操作數(shù)為op_{1}+1

2.刪除操作

假設(shè)將A[1...i-1]修改為B[1...j]需要操作數(shù)為op_{2}一罩,那么刪除A[i]就可以將A[1...i]修改為B[1...j]杨幼,這時(shí)所需要的操作數(shù)為op_{2}+1

3.修改操作

假設(shè)將A[1...i-1]修改為B[1...j-1]需要操作數(shù)為op_{3},這時(shí)要將A[1...i]修改為B[1...j]分兩種情況:

a. A[i]\ne B[j]聂渊,則將A[i]替換成B[j]即可完成修改差购,這時(shí)操作數(shù)為op_{3}+1

b. A[i]== B[j],則將不需要進(jìn)行修改操作汉嗽,操作數(shù)仍為op_{3}
?
最后可以得到狀態(tài)轉(zhuǎn)移方程如下

lev_{a,b}(i, j)= \left\{ \begin{array}{lr} max(i, j),\quad if\ min(i, j) = 0 \\ min\left\{\begin{array}{lr} lev_{a,b}(i-1,j)+1 \\ lev_{a,b}(i,j-1)+1 \\ lev_{a,b}(i-1,j-1)+1_{a_{i}\ne b_{j}} \\ \end{array} \right. , otherwise\\ \end{array} \right.

上式中1_{a_{i}\ne b_{j}}表示a_{i}\ne b_{j}表達(dá)式取0欲逃,否則取1

Python代碼如下

得到上述轉(zhuǎn)移方程后我們就很容易寫出下面程序了

1.按照上述公式編寫,沒(méi)做優(yōu)化的情況

import numpy as np

def Lev_distance():
    A = "fafasa"
    B = "faftreassa"

    dp = np.zeros((len(A) + 1, len(B) + 1))

    for i in xrange(len(A) + 1):
        dp[i][0] = i
    for j in xrange(len(B) + 1):
        dp[0][j] = j

    for i in xrange(1, len(A) + 1):
        for j in xrange(1, len(B) + 1):
            if A[i - 1] == B[j - 1]:
                dp[i][j] = dp[i - 1][j - 1]
            else:
                dp[i][j] = min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1

    print("Levenshtein distance: {}".format(dp[len(A)][len(B)]))

if __name__=="__main__":
    Lev_distance()

2.使用滾動(dòng)數(shù)組優(yōu)化上述代碼

import numpy as np

def Lev_distance():
    A = "fafasa"
    B = "faftreassa"

    dp = np.array(np.arange(len(B)+1))

    for i in xrange(1, len(A)+1):
        temp1 = dp[0]
        dp[0] += 1
        for j in xrange(1, len(B)+1):
            temp2 = dp[j]
            if A[i-1] == B[j-1]:
                dp[j] = temp1
            else:
                dp[j] = min(temp1, min(dp[j-1], dp[j]))+1
            temp1 = temp2

    print("Levenshtein distance: {}".format(dp[len(B)]))

if __name__=="__main__":
    Lev_distance()

參考

[1] https://en.wikipedia.org/wiki/Levenshtein_distance
[2] http://www.cnblogs.com/BlackStorm/p/5400809.html

歡迎加入OCR交流群:785515057(此群已滿)
歡迎加入OCR交流群2:826714963

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末稳析,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弓叛,更是在濱河造成了極大的恐慌彰居,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撰筷,死亡現(xiàn)場(chǎng)離奇詭異陈惰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)毕籽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門抬闯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人关筒,你說(shuō)我怎么就攤上這事画髓。” “怎么了平委?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵奈虾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)肉微,這世上最難降的妖魔是什么匾鸥? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮碉纳,結(jié)果婚禮上勿负,老公的妹妹穿的比我還像新娘。我一直安慰自己劳曹,他們只是感情好奴愉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铁孵,像睡著了一般锭硼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜕劝,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天檀头,我揣著相機(jī)與錄音,去河邊找鬼岖沛。 笑死暑始,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的婴削。 我是一名探鬼主播廊镜,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼唉俗!你這毒婦竟也來(lái)了期升?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤互躬,失蹤者是張志新(化名)和其女友劉穎播赁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吼渡,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡容为,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寺酪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坎背。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寄雀,靈堂內(nèi)的尸體忽然破棺而出得滤,到底是詐尸還是另有隱情,我是刑警寧澤盒犹,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布懂更,位于F島的核電站眨业,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沮协。R本人自食惡果不足惜龄捡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望慷暂。 院中可真熱鬧聘殖,春花似錦、人聲如沸行瑞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)血久。三九已至突照,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洋魂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工喜鼓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留副砍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓庄岖,卻偏偏與公主長(zhǎng)得像豁翎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子隅忿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容