主要關注查詢的拼寫校訂。例如,用戶輸入carot時,實際上可能想返回包含詞項carrot的文檔。Google的報告指出,當用戶輸入britian spears、britney's spears、brandy spears或者prittany spears時,實際上搜索引擎都會當成是britney spears的錯誤拼寫來處理。咱們將會考慮解決該問題的兩個步驟:第一步基於編程距離(edit distance),第二步基於k-gram重合度(k-gram overlap)。在介紹詳細算法以前,咱們首先簡單介紹一下搜索引擎是如何實現拼寫糾正並使其成爲用戶體驗的一部分的。算法
對於大多數拼寫糾正(spelling correction)算法而言,存在如下兩個基本的原則。編程
拼寫校訂算法基於這些鄰近度計算,其功能主要經過如下幾種方式返回給用戶。grunt
這裏咱們主要關注兩種拼寫校訂的方法:一種是詞項獨立(isolated-term)的校訂,另外一種是上下文敏感(content-sensitive)的校訂。在詞項獨立的校訂方法中,無論查詢中包含多少個查詢詞項,其每次只對單個查詢項進行校訂,也就是說在象徵時詞項是相互獨立的。上面給出的carot例子就屬於這一類作法。利用這種詞項獨立校訂的方法,就很難檢測到查詢flew form Heathrow 中實際上包含一個錯誤的詞項form(正確的形式應該是from),這是由於在校訂時每一個詞項之間就是相互獨立的。搜索引擎
首先咱們介紹兩種詞項獨立的校訂方法:編輯距離方法及k-gram重合度方法。而後,咱們基於上下文敏感校訂方法。編碼
拼寫校訂問題不知須要計算出編輯距離:給定字符串集合V
(對應詞項詞彙表)和查詢字符串q
,咱們要從V
中尋找和q
具備最小編輯距離的字符串。咱們能夠把這個問題當作是解碼問題,其中編碼詞(對應V
中的字符串)已經預先定義好。最直接的方法是,計算q
到V
中的每一個字符串的編輯距離,而後選擇其中編輯距離最小的字符串。很顯然,這種窮舉的搜索方法開銷很大。所以實際中使用了多種啓發式方法來提升查找的效率。
最簡單的啓發式方法是將搜索限制在與查詢詞具備相同的首字母的字符串上,也就是說咱們指望查詢的拼寫錯誤不會出如今第一個字符上。上述啓發式方法的一個更復雜的作法是利用輪排索引的某種版本,忽略了刺蝟的$
符號。考慮查詢字符串q
的全部旋轉結果集合,對集合中每一個旋轉r,經過遍歷B樹來訪問輪排索引(即輪排索引的詞彙表查找能夠經過B樹來實現),返回旋轉結果中以r開頭的詞項。例如,若是q爲mase,那麼咱們考慮其旋轉r=sema,這是咱們會返回諸如semantic和semaphore的詞,而這些詞和mase之間的編輯距離並不小。遺憾的是,採用這種作法咱們會錯過包括mare和mane在內的一些更可能相關的詞。爲解決這個問題,咱們改變旋轉的使用機制:對每一個旋轉結果,在遍歷B樹以前咱們忽略其長度的e
的後綴,這樣作能夠保證返回詞項集合R中的每一個詞項和q之間都包含一段較長的公共子串。e
的值取決於q的長度。固然咱們也能夠設置爲常數。日誌
爲了進一步限制計算編輯距離後獲得的詞彙表大小,如下介紹如何經過使用k-gram索引來輔助返回與查詢q具備較小編輯距離的詞項。一旦返回這些詞項以後,利用k-gram索引,就能從中找出與q具備最小編輯距離的詞。
實際上,咱們利用k-gram索引來查找與查詢具備不少公共k-gram的詞項。只要對「具備不少公共k-gram」進行合理定義,咱們認爲上述查找其實是對查詢字符串q中k-gram的倒排記錄表進行單遍掃面的過程。
查詢bord的2-gram索引的一個片斷,其中包含3個2-gram組成的倒排記錄表。假定咱們想返回包含上面3個2-gram中的至少2個詞項,對倒排記錄表的單遍掃描(和第一章相似)會返回知足該條件的全部詞項,本例當中詞項包括aboard、boardroom及border。 code
這種經過線性掃描並當即合併倒排記錄表的作法十分簡單,只須要待匹配詞項包含查詢q中某個固定數目的k-gram便可。可是這種作法有一個缺點,好比boardroom這種不多是bord的正確拼寫形式的詞也會被返回。因此,咱們須要計算詞彙表中詞項與查詢q之間更精細的重疊計算方法。好比採用jaccard係數(jaccard coefficient)就能夠對先前的線性掃描合併方法進行修正。這裏,Jaccard係數的計算公式爲|A∩B|/|A∪B|,其中A、B分別是查詢q、詞彙表詞項中的k-gram集合、掃描過程當中,一旦掃描到與當前的詞項t,就快速計算出q和t的Jaccard係數,而後繼續掃描下一個詞項。若是Jaccard係數超過預約的閾值,則將t輸出。不然,咱們每每繼續掃描。上述過程代表,在計算Jaccard係數時,咱們須要知道q和t的k-gram集合。
因爲是對q中的全部k-gram掃描倒排記錄表,所以q中的k-gram集合是已知的,因而問題就變成如何求解t中的全部k-gram。理論上咱們能夠窮舉出t中全部k-gram。可是這種作法不只慢並且在實際中也難以實現。在不少狀況下,倒排記錄自己極可能並不包含完整的t字符串而每每是t的某種編碼形式。也就是說,每每並不知道t的k-gram集合。然而,一個重要的發現使得這種狀況下q和tJaccard係數的計算成爲可能。這個發現就是,在計算Jaccard係數的時候,咱們只須要知道t的長度便可。對於查詢q=bord掃描倒排記錄表直到t=boardroom。這時咱們知道有2個2-gram已經匹配上了。若是倒排記錄表中已經預先記錄了boardroom所包含的2-gram的數目(這裏是8),那麼全部計算Jaccard的係數的信息都已知,計算公式2/(8+3-2)。其中,分子爲倒排記錄的命中數(值爲2,分別來自bo和rd),分母爲bord及boardroom中的2-gram之和減去倒排記錄表的命中數。
須要指出的是,也能夠把Jaccard係數替換成其餘可以進行快速計算的衡量指標。那麼如何拼寫校訂中使用這些度量方式呢?一種經驗性的方法是,首先使用k-gram索引返回多是q的潛在正確拼寫形式的詞項集合,而後計算該集合中的每一個元素和q之間的編輯距離並選擇具備較小距離的那些詞項。orm
獨立的詞項拼寫校訂方法在面對諸如flew form Heathrow 中的輸出錯誤時無能爲力,所以這3個單詞獨立看來拼寫都沒有錯誤。當輸入這類查詢時,搜索引擎可能會發現返回的文檔很是少,隨後也許提供正確的查詢建議flew form Heathrow。 這種功能的一種簡單的實現方法就是,及時每一個單詞拼寫都是對的,仍然要對每一個單詞找到可能的拼寫正確詞,而後嘗試對短語中的每一個詞進行替換。好比對於上面flew form Heathrow的例子,咱們可能會返回以下短語fled from Heathrow 和 flew fore Heathrow。對每一個替換後的短語,搜索引擎進行查找並肯定最後的返回數目。
對於單獨的查詢有多種可能的正確拼寫形式,那麼上述方法中窮舉過程的開銷會很是大,最後咱們就會面對很是多的拼寫組合。有一些啓發式方法能夠減小可能的拼寫結果空間。上述例子中,咱們對flew及from進行擴展時,咱們只保留文檔集合或者查詢日誌中的高頻組合結果。好比,咱們可能會保存flew from 而不是 fled fore 或 flea form,這是由於fled fore極可能比flew from 出現的次數少。接下來咱們僅僅根據高頻雙詞(如flew from)來得到Heathrow的可能的正確拼寫。計算雙詞頻率的時候可使用文檔集,也可使用用戶的查詢日誌。索引
最後一項用戶容錯檢索技術與發音有關,即拼寫錯誤的緣由在於用戶輸入一個和目標詞項發音類似的查詢。該方法尤爲適合用於人名的查找,其基本的思路是:對每一個詞項,進行一個語音的哈希操做,發音類似的詞項都被映射爲同一值。該思路最先源於國際警察部門的工做,它們自20世紀初開始就在全球範圍內尋找與罪犯嫌疑人發音類似的人名,而無論這些人名在不一樣國家發音是否有所不一樣。上述思路主要用於專有名詞的語音校訂。
這類通用語音哈希方法一般統稱soundex算法(soundex algorithm)。其中,一個原始的soundex算法的構建方法以下。須要指出的是,該基本算法存在不少變形。ci