动态规划应用--搜索引擎拼写纠错
文章目錄
- 1. 字符串相似度
- 1.1 萊文斯坦距離
- 1.2 最長公共子串長度
- 2. 計算編輯距離
- 2.1 萊文斯坦距離
- 2.2 最長公共子串長度
- 3. 搜索引擎拼寫糾錯
- 4. 練習(xí)題
在 Trie樹那節(jié)講過,利用Trie可以進(jìn)行關(guān)鍵詞提示,節(jié)省輸入時間。
在搜索框中你不小心打錯了字,它也會智能提醒你是不是要搜XXX
1. 字符串相似度
- 如何量化兩個字符串的相似度?有一個非常著名方法,編輯距離(Edit Distance)。
- 編輯距離,將一個字符串轉(zhuǎn)化成另一個字符串,需要的最少編輯操作次數(shù)(增加一個字符、刪除一個字符、替換一個字符)。
- 編輯距離越大,兩個字符串相似度越小;編輯距離越小,兩個字符串相似度越大。兩個完全相同的字符串,編輯距離是0。
1.1 萊文斯坦距離
- 萊文斯坦距離(Levenshtein distance)允許增加、刪除、替換字符這三個編輯操作
- 萊文斯坦距離的大小,表示兩個字符串差異的大小
1.2 最長公共子串長度
- 最長公共子串長度(Longest common substring length)只允許增加、刪除字符這兩個編輯操作
- 表示兩個字符串相似程度的大小
兩個字符串 mitcmu 和 mtacnu 的萊文斯坦距離是3,最長公共子串長度是4。
2. 計算編輯距離
這個問題是求把一個字符串變成另一個字符串,需要的最少編輯次數(shù)。整個求解過程,涉及多個決策階段,需要依次考察一個字符串中的每個字符,跟另一個字符串中的字符是否匹配,所以,問題符合多階段決策最優(yōu)解模型。
2.1 萊文斯坦距離
回溯解法:
回溯是一個遞歸處理的過程。如果a[i]與b[j]匹配,我們遞歸考察a[i+1]和b[j+1]。如果a[i]與b[j]不匹配,那我們有多種處理方式可選:
- 可以刪除a[i],然后遞歸考察a[i+1]和b[j];
- 可以刪除b[j],然后遞歸考察a[i]和b[j+1];
- 可以在a[i]前面添加一個跟b[j]相同的字符,然后遞歸考察a[i]和b[j+1];
- 可以在b[j]前面添加一個跟a[i]相同的字符,然后遞歸考察a[i+1]和b[j];
- 可以將a[i]替換成b[j],或者將b[j]替換成a[i],然后遞歸考察a[i+1]和b[j+1]。
-
在遞歸樹中,每個節(jié)點狀態(tài)包含三個變量(i,j,dist),dist表示處理到a[i]和b[j]時,已經(jīng)執(zhí)行的編輯次數(shù)。
-
在遞歸樹中,(i,j)兩個變量重復(fù)的節(jié)點很多,比如(3,2)和(2,3)。對于(i,j)相同的節(jié)點,我們只保留 dist最小的,繼續(xù)遞歸處理,剩下的舍棄。所以,狀態(tài)就從(i,j,dist)變成了(i,j,min_dist),其中min_dist 表示處理到a[i]和b[j],已經(jīng)執(zhí)行的最少編輯次數(shù)。
-
這個問題的狀態(tài)轉(zhuǎn)移方式,要比之前兩節(jié)課中講到的例子要復(fù)雜很多。上一節(jié)我們講的矩陣最短路徑問題中,到達(dá)狀態(tài)(i,j)只能通過(i-1,j)或(i,j-1)兩個狀態(tài)轉(zhuǎn)移過來,而今天這個問題,狀態(tài)(i,j)可能從(i-1,j),(i,j-1),(i-1,j-1)三個狀態(tài)中的任意一個轉(zhuǎn)移過來。
如果:a[i] != b[j],那么:min_dist(i, j) 就等于: min{min_dist(i-1,j)+1, min_dist(i,j-1)+1, min_dist(i-1,j-1)+1}如果:a[i] == b[j],那么:min_dist(i, j) 就等于: min{min_dist(i-1,j)+1, min_dist(i,j-1)+1, min_dist(i-1,j-1)}其中,min 表示求三數(shù)中的最小值。
寫狀態(tài)轉(zhuǎn)移方程根據(jù)狀態(tài)轉(zhuǎn)移方程,填充狀態(tài)表
2.2 最長公共子串長度
最長公共子串作為編輯距離的一種,只允許增加、刪除字符兩種操作。表征的也是兩個字符串之間的相似程度。
- 每個狀態(tài)包括三個變量(i,j,max_lcs),max_lcs表示a[0…i]和b[0…j]的最長公共子串長度。那(i,j)這個狀態(tài)都是由哪些狀態(tài)轉(zhuǎn)移過來的呢?
- 先來看回溯的處理思路。我們從a[0]和b[0]開始,依次考察兩個字符串中的字符是否匹配。
- 如果a[i]與b[j]匹配,最大公共子串長度+1,繼續(xù)考察a[i+1]和b[j+1]。
- 如果a[i]與b[j]不匹配,最長公共子串長度不變,這個時候,有兩個不同的決策路線:
1 刪除a[i],或者在b[j]前面加上一個字符a[i],然后繼續(xù)考察a[i+1]和b[j];
2 刪除b[j],或者在a[i]前面加上一個字符b[j],然后繼續(xù)考察a[i]和b[j+1]。
a[0…i]和b[0…j]的最長公共長度max_lcs(i,j),只有可能通過下面三個狀態(tài)轉(zhuǎn)移過來:
(i-1,j-1,max_lcs),max_Ics表示 a[0…i-1] 和 b[0…j-1] 的最長公共子串長度;
(i-1,j,max_lcs),max_lcs表示 a[0…i-1] 和 b[0…j] 的最長公共子串長度;
(i,j-1,max_lcs),max_Ics表示 a[0…i] 和 b[0…j-1] 的最長公共子串長度。
最大公共子串長度:4
3. 搜索引擎拼寫糾錯
-
當(dāng)用戶在搜索框內(nèi),輸入一個拼寫錯誤的單詞時,拿這個單詞跟詞庫中的單詞一—進(jìn)行比較,計算編輯距離,將編輯距離最小,作為糾正之后的單詞,提示用戶。
-
這就是拼寫糾錯最基本的原理。真正商用的搜索引擎,拼寫糾錯功能不會這么簡單。一方面,單純利用編輯距離來糾錯,效果并不一定好;另一方面,詞庫中的數(shù)據(jù)量可能很大,對糾錯的性能要求很高。
-
針對糾錯效果不好,有很多種優(yōu)化思路。
a. 取出編輯距離最小的TOP10,然后根據(jù)其他參數(shù)決策選擇。比如使用搜索熱門程度來決定。
b. 可以用多種編輯距離計算方法,比如今天講到的兩種,分別計算編輯距離最小的TOP10,求交集,用交集的結(jié)果,再繼續(xù)優(yōu)化處理。
c. 可以統(tǒng)計用戶的搜索日志,得到最常拼錯的單詞列表,以及對應(yīng)的拼寫正確的單詞。糾錯時,首先在這個最常拼錯單詞列表中查找。一旦找到,直接返回對應(yīng)的正確的單詞。這樣糾錯的效果非常好。
d. 引入個性化因素。針對每個用戶,維護(hù)這個用戶特有的搜索喜好,也就是常用的搜索關(guān)鍵詞。當(dāng)用戶輸入錯誤時,先在這個用戶常用的搜索關(guān)鍵詞中,計算編輯距離,查找編輯距離最小的單詞。 -
針對糾錯性能方面,講兩種分治的優(yōu)化思路。
a. 如果糾錯功能的TPS(每秒事務(wù)處理量(TransactionPerSecond))不高,可以部署多臺機(jī)器,每臺機(jī)器運行一個獨立的糾錯功能。當(dāng)有一個糾錯請求的時候,通過負(fù)載均衡,分配到其中一臺機(jī)器,來計算編輯距離,得到糾錯單詞。
b. 如果糾錯系統(tǒng)的響應(yīng)時間太長,也就是,每個糾錯請求處理時間過長,可以將糾錯的詞庫,分割到很多臺機(jī)器。當(dāng)有一個糾錯請求的時候,將這個拼寫錯誤的單詞,同時發(fā)送到多臺機(jī)器,并行處理,分別得到編輯距離最小的單詞,然后再比對合并,最終決定出一個最優(yōu)的糾錯單詞。
4. 練習(xí)題
LeetCode 72. 編輯距離(DP)
LeetCode 1143. 最長公共子序列(動態(tài)規(guī)劃)
總結(jié)
以上是生活随笔為你收集整理的动态规划应用--搜索引擎拼写纠错的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python将元祖设为整形_python
- 下一篇: 数据结构--堆 Heap