基礎知識 一個簡單例子
假如有四個文檔,分別代表四部電影的名字:
The Shawshank Redemption Forrest Gump The Godfather The Dark Knight
如果我們想根據這四個文檔建立信息檢索,即輸入查找詞就可以找到包含此詞的所有電影,最直觀的實現方式是建立一個矩陣,每一行代表一個詞,每一列代表一個文檔,取值1/0代表該此是否在該文檔中。如下:
如果輸入是Dark,只需要找到Dark對應的行,選出值為1對應的文檔即可。當輸入是多個單詞的時候,例如:The Gump,我們可以分別找到The和Gump對應的行:1011和0100,如果是想做AND運算(既包括The也包括Gump的電影),1011和0100按位與操作返回0000,即沒有滿足查詢的電影;如果是OR運算(包括The或者包括Gump的電影),1011和0100按位與操作返回1111,這四部電影都滿足查詢。
實際情況是我們需要檢索的文檔很多,一個中等規模的bbs網站發布的帖子可能也有好幾百萬,建立這么龐大的一個矩陣是不現實的,如果我們仔細觀察這個矩陣,當數據量急劇增大的時候,這個矩陣是很稀疏的,也就是說某一個詞在很多文檔中不存在,對應的值為0,因此我們可以只記錄每個詞所在的文檔id即可,如下:
查詢的第一步還是找到每個查詢詞對應的文檔列表,之后的AND或者OR操作只需要按照對應的文檔id列表做過濾即可。實際代碼中一般會保證此id列表有序遞增,可以極大的加快過濾操作。上圖中左邊的每一個詞叫做詞項,整張表稱作倒排索引。
實際搜索過程
如果要實現一個搜索功能,一般有如下幾個過程
搜集要添加索引的文本,例如想要在知乎中搜索問題,就需要搜集所有問題的文本。
文本的預處理,把上述的收集的文本處理成為一個個詞項。不同語言的預處理過程差異很大,以中文為例,首先要把搜集到的文本做分詞處理,變為一個個詞條,分詞的質量對最后的搜索效果影響很大,如果切的粒度太大,一些短詞搜索正確率就會很低;如果切的粒度太小,長句匹配效果會很差。針對分詞后的詞條,還需要正則化:例如濾除停用詞(例如:的把并且的
根據上一步的詞項和文檔建立倒排索引。實際使用的時候,倒排索引不僅僅只是文檔的id,還會有其他的相關的信息:詞項在文檔中出現的次數、詞項在文檔中出現的位置、詞項在文檔中的域(以文章搜索舉例,域可以代表標題、正文、作者、標簽等)、文檔元信息(以文章搜索舉例,元信息可能是文章的編輯時間、瀏覽次數、評論個數等)等。因為搜索的需求各種各樣,有了這些數據,實際使用的時候就可以把查詢出來的結果按照需求排序。
查詢,將查詢的文本做分詞、正則化的處理之后,在倒排索引中找到詞項對應的文檔列表,按照查詢邏輯進行過濾操作之后可以得到一份文檔列表,之后按照相關度、元數據等相關信息排序展示給用戶。
相關度
文檔和查詢相關度是對搜索結果排序的一個重要指標,不同的相關度算法效果千差萬別,針對同樣一份搜索,百度和谷歌會把相同的帖子展示在不同的位置,極有可能就是因為相關度計算結果不一樣而導致排序放在了不同的位置。
基礎的相關度計算算法有:TF-IDF,BM25 等,其中BM25 詞項權重計算公式廣泛使用在多個文檔集和多個搜索任務中并獲得了成功。尤其是在TREC 評測會議上,BM25 的性能表現很好并被多個團隊所使用。由于此算法比較復雜,我也是似懂非懂,只需要記住此算法需要詞項在文檔中的詞頻,可以用來計算查詢和文檔的相關度,計算出來的結果是一個浮點數,這樣就可以將用戶最需要知道的文檔優先返回給用戶。
評論(0人參與,0條評論)
發布評論
最新評論