網易有道面試總結


此次算是網易的秋招補錄了吧,也不知道從哪里把我挖出來,讓我去面試。面試的崗位是數據挖掘,總共有四輪面試,全是技術面試,崗位雖然是數據挖掘,但是面試官問的問題絕大多數是偏自然語言處理的,

面試的內容不再一一闡述,下面就其中個人覺得比較有意思的問題作以下記錄。

1.第一個問題是拼寫糾正問題,面試官寫了這樣一句話:I hase an apple,顯示hase拼寫錯誤,並提出修改建議(have),這里實際上要解決兩個問題:一.如何識別拼寫錯誤,這個很簡單。二針對拼寫錯誤,如何快速給出修改建議。

這個問題我當時能想到的方法都說了,但是貌似答得不太好,下面是我整理的答案,答案來源於:http://blog.sina.com.cn/s/blog_567842410100obxd.html

現在各大流行的搜索引擎幾乎都具備一個功能,那就是提供拼寫糾錯功能。用戶將查詢的關鍵詞提交給搜索引擎之后,搜索引擎便開始分析用戶的輸入,檢查用戶的拼寫是否有錯誤,如果有的話,給出正確的拼寫建議。也就是說,搜索引擎的拼寫糾錯功能,要完成兩部分的工作,首先,對用戶輸入的查詢進行處理,判斷是否有拼寫錯誤,接着,對於有拼寫錯誤的查詢輸入,給出正確詞匯的提示。因為中文的拼寫糾錯涉及到中文分詞等復雜邏輯,所以本文只對英文的拼寫糾錯進行討論。

 

 英文單詞糾錯法

常見的英文單詞糾錯法,主要有以下幾種:誤拼詞典法、最小編輯距離法、詞干法,N-gram法和基於規則的技術等,下面我們對這些英文單詞糾錯法逐個進行介紹。

 

(1)誤拼字典法。這種方法可以理解成窮舉法,通過收集大規模真實文本中拼寫出錯的英文單詞並給出相應的正確拼寫,建造一個無歧義的誤拼字典。在進行英文單詞拼寫檢查時,查找誤拼字典,如命中,則說明該單詞拼寫有誤,該詞的正確拼寫字段為糾錯建議。比如在搜索引擎的實現中,通過記錄日志的形式,把所有用戶的輸入都記錄下來,提取有拼寫錯誤的輸入,形成誤拼詞典。該方法的特點是算法簡單,效率高。但英文拼寫錯誤具有隨機性,很難保證誤拼字典的無歧義性和全面性,因此查准率低、校對效果差;而且,對於搜索引擎用戶海量的誤拼輸入,空間復雜度也是需要考慮的問題。

 

(2)最小編輯距離法。通過計算誤拼字符串與詞典中某個詞間的最小編輯距離來確定糾錯候選詞。所謂最小編輯距離是指將一個詞串轉換為另一個詞串所需的最少的編輯操作次數。在編輯操作中,可以將單次的編輯動作歸納為三種:插入字符、刪除字符和替換字符;考慮到在實際計算機輸入過程中,字符的顛倒異位也是常見的錯誤,我們將顛倒異位也算作一種編輯動作。還有人提出了反向最小編輯距離法,這種方法首先對每個可能的單個錯誤按照編輯距離進行搜索,生成一個候選集,然后,通過查詞典看哪些是有效的單詞,並將這些有效的單詞作為誤拼字符串的糾錯建議。

(3)N-gram法。基於n元文法,通過對大規模英文文本的統計得到單詞與單詞問的轉移概率矩陣。當檢測到某英文單詞不在詞典中時。查轉移概率矩陣,取轉移概率大於某給定閾值的單詞為糾錯建議。

通過對這些現有的英文單詞糾錯法的分析,我們選定反向最小編輯距離法作為拼寫糾錯功能的實現方式

 

拼寫糾錯功能的實現

搜索引擎如何判斷用戶的輸入是否有拼寫錯誤呢?通過分析現有的著名搜索引擎的行為,我想應該是查詞典的方式。每個搜索引擎維護一個關鍵詞的詞典,對於用戶的輸入,檢查它是否在詞典中。如果詞典中有這個詞條,則直接返回搜索結果;如果發現這個用戶輸入的詞並不包含在詞典里邊,那么它很有可能是一個錯誤的輸入,於是馬上觸發拼寫糾錯功能,對用戶提供拼寫建議。我們很容易就能在Google或者百度這樣的搜索引擎中驗證這個猜想,在搜索框里輸入一個正常的詞,比如“Microsoft”,搜索引擎不會有錯誤提示;而你故意輸入一個詞典不包括的詞,比如“Micorsoft”,搜索引擎會提示你正確的搜索詞匯。

 

字典的數據結構

字典的數據結構,大多數情況下,比照C++ STL中的map,我們會想到兩種實現途徑,首先是二叉樹,其次是哈希表。對於哈希表,在選取恰當的哈希函數的情況下,它的理論查找效率是O(1),這看起來是個不錯的選擇,事實上哈希表已經用作在一些搜索引擎中[1]。於是我們可以在訓練搜索引擎的過程中,把所有的常用詞都輸入到這個詞典中,然后就能夠用很高的效率進行搜索。但是這種方法帶來一個問題,詞典里的單詞量通常是非常巨大的,每一個單詞都需要完整的存儲,隨着時間的推移,這種實現需要的內存空間也會變得越來越大。

在二叉樹的實現中,我們可以把所有的單詞都保存在二叉樹的節點中,但這樣需要的空間幾乎可以肯定不會比哈希表的方式少,除了存儲單詞的空間,還需要額外的實現二叉樹的空間,況且搜索的時間復雜度是O(logn),所以我們需要對這種方式進行優化。所有的單詞還是存儲在二叉樹結構中,但是每個節點僅保存一個字符,每個節點可以有兩個子節點,其中左子節點表示當前字符的兄弟(Sibling), 說明有多個單詞存在相同的前綴,右子節點表示當前字符的后續字符(Next)利用這種存儲方法,我們可以高效率地將有相同前綴的詞存儲在同一棵子樹中(貌似是前綴樹)。

給出拼寫建議

前面我們提到最小編輯距離法中,需要對用戶輸入的誤拼字符串按照編輯距離進行搜索並形成候選集,然后在字典中查找后選的單詞。如果存在,則說明是個有效的單詞,可以作為拼寫建議提供給用戶。我們只考慮編輯距離為1的情況,如果編輯距離更大的話,返回的結果太多,反而影響拼寫建議的准確度。

 

我們按照編輯操作來枚舉生成候選集模式。比如對於誤拼字符串abc,刪除字符可以產生ab、ac和bc;插入字符可以產生?abc、a?bc、ab?c和abc?;替換字符可以產生?bc、a?c和ab?;將字符顛倒可以產生bac和acb。然后,我們將這些候選模式放到二叉樹中去搜索,就可以返回匹配的候選單詞集合。

 

候選單詞集中包含有我們需要提供給用戶的拼寫建議,但是我們不能這樣直接給用戶。首先,候選單詞集中可能存在重復的單詞,其次存在多個單詞的情況下,如何才能把最准確的拼寫建議返回給用戶。第一個問題,我們可以通過過濾邏輯去除重復;而第二個問題,我想不同的搜索引擎都有自己不同的實現,比如可以按照單詞的優先級返回,分析用戶查詢日志,查詢次數越多的單詞優先級越高。

 2.第二個問題,是一個女面試官,和藹可親,她打開有道詞典,問了里面一個功能:網絡釋義是怎么實現的,如下圖所示,

她說網絡釋義這一塊是她帶領團隊做的。

網絡釋義這一塊,首先在海量的互聯網的網頁上、文檔中去尋找一些固定模型的pattern片段,pattern可以是:xxx(xxx)、xxx:xxx、xxx::xxx等等,找到海量的pattern片段之后,建立和維護一個庫,然后根據用戶的輸入,在這個庫當中用倒排索引的方法去查找合適的網絡釋義顯示給用戶。

1.網絡釋義的中文左邊界怎么確定 ?舉例如下:

用來做塑料袋的主要成份是聚氯乙烯,其放出的氣體氯化氫(HCL)是有毒氣體。

在這個例子中,氯化氫(HCL)是准確的網絡釋義,那么我們如何確定 氯化氫(HCL)、體氯化氫(HCL)、氣體氯化氫(HCL)、、、、、,哪個是最佳的呢。

由於我們有海量的這樣的信息,我們可以用統計學的方法,基於海量的信息計算出各個組合的概率,然后選擇概率最大的那種組合入庫即可 

2.pattern的形式有很多,可以是:氯化氫(HCL)、氯化氫:HCL、氯化氫::HCL、氯化氫--HCL等等,如何找出所有的這種解釋說明性的pattern?

不管是:、::、--、()哪一種符號,中文和英文的距離總是很近的,中間是什么符號並不重要,可以用正則表達式代替。解決方法還是基於統計學的方法,計算出距離比較近的各種組合的概率,選擇概率大的入庫。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM