設計一個文本搜索引擎

博客中的文章均爲meelo原創,請務必以連接形式註明本文地址html

 

搜索引擎是一個十分神祕的事物,由於它鑄造了google和百度兩大傳奇互聯網公司。過去流傳一種說法,世界上只有4個國家掌握了搜索引擎的核心技術,那就是美國、中國、俄羅斯和韓國,分別對應Google、百度、naver和yandex。曾經有國有背景的即刻搜索想承擔起國家戰略,國有企業在能源、基礎設施領域雄踞一方,望風披靡,但即刻搜索最終卻失敗了。搜索引擎真的是那麼高不可攀的技術嗎?算法

其實,搜索引擎是諸多技術組成的複合體。囊括天然語言處理、並行計算、爬蟲等領域。但其最基本的原理卻並不複雜。北京大學在Coursera開設的程序設計與算法專項課程,從零基礎開始教授C語言、算法、數據結構,當你過關闖將,完成6門課程以後,最後的畢業項目就是完成一個搜索引擎。畢業項目由7個部分組成,每一個部分都有明確的目標說明,須要完成搜索引擎的一個部分。當你完成全部7個部分的時候,你就真正搭建出來一個搜索引擎啦。動手實踐是最佳的學習方式,你能夠在學習理論的同時,及時地檢驗學習的效果。這篇文章我就來介紹在畢業項目中我學到了什麼,順便揭祕所謂「搜索引擎的核心技術」。數據庫

一個網頁搜索引擎主要有四個部分組成。分別是自動下載網頁的爬蟲、對網頁創建索引、衡量網頁的質量和評價網頁和查詢的相關性。首先我必須明確提出的是,畢業項目實現的是一個文本搜索引擎,和網頁搜索引擎有必定差異。好比:文本搜索引擎無需經過爬蟲遨遊互聯網下載網頁,與之對應的是遍歷硬盤上的文本文件;另外一個差異是文本搜索引擎無法像網頁那樣使用PageRank算法衡量網頁的質量,PageRank算法是Google的兩位創始人共同發明的,其核心思想是利用鏈接不一樣網頁的URL,若是有不少高質量的網頁指向這一網頁,那麼說明這個網頁也是一個高質量的網頁,文本文件沒有連接,所以不能應用PageRank算法。緩存

即使文本搜索引擎和網頁搜索引擎有必定差別,但目標仍然是同樣的。給定一個關鍵詞或者是一句話做爲查詢(query),找到包含這個關鍵詞或者這句話的文檔,同時要求與查詢越相關的文檔排名越靠前。服務器

完成畢業項目的第一個難點就是理解文本搜索引擎的框架,這樣在完成每個部分的時候,才能清楚你在作什麼。數據結構

除去自動下載網頁的爬蟲和評價網頁和查詢的相關性,文本搜索引擎的核心就只包含對文檔創建索引和評價文檔與查詢相關性兩個組件了。下面我將介紹這兩個組件是如何在這7個部分中完成的。框架

對文檔創建索引函數

在正式進入話題以前,須要消除一個誤解。搜索引擎搜索網頁並非實時地檢索整個互聯網,如今完整請求一個網頁就須要花費將近1秒,搜索引擎可以如此之快的返回結果,這是不現實的。取而代之的是,搜索引擎在數據庫裏創建了一個索引。學習

對文檔創建的索引有兩個。第一個索引是原封不動地把文檔的內容存儲到數據庫裏,就像「百度快照」同樣,百度在它的服務器上,保存了一份網頁的副本,若是網頁沒法打開,你仍然能夠瀏覽這份副本。這對應於畢業項目的第2個部分,其實對於文本搜索引擎或者說在這個項目裏,這個「快照」並無起到什麼做用。搜索引擎

不一樣文檔的長度是不相同的,如何高效地存儲是一個須要解決的問題。這在項目的要求中已經明確的給出了。分兩個文件存儲,第一個文件連續存儲文檔的內容,第二個文件存儲每個文檔在第一個文件當中的起始位置。第二個文件的每個記錄就是定長的了,所以能夠在常數時間內,獲取文檔的起始位置和結束位置。

第二個索引是倒排索引(inverted index)。倒排索引是搜索引擎如此之快的一個核心原理。對於一篇文檔,包含語義的基本元素是一個個的單詞。處理文檔的第一步就是將文檔分割爲一個個的單詞,這是畢業項目的第1部分。在中文裏,單詞之間並無明確的分隔符,分割單詞須要涉及到天然語言處理。好在畢業項目所涉及的搜索引擎是一個英文的搜索引擎,英文單詞之間有自然的空格分割,第1部分就是利用空格或者是標點符號做爲分隔符,分割成單詞,術語叫作Token。Token不只僅是單詞,還包括單詞出現的位置,這有助於判斷兩個單詞是否相鄰,提高搜索結果的相關性,在畢業項目中雖然保存了單詞出現的位置但在搜素的時候並無使用這一信息。

倒排索引是一個表格,第一列是全部文檔裏出現的單詞,第二列是由多個元組組成的列表,元組的第一項是文檔編號,第二項是該文檔中這個單詞出現的次數,又叫作文檔頻率(text frequency)。有了倒排索引,在檢索一個單詞的時候,就無需遍歷全部文檔了,搜索倒排索引就能找到包含這個單詞的文檔。存儲倒排索引就是畢業項目第3部分須要完成的內容,與存儲原始文檔面臨的相同問題是,倒排索引也是不定長的,所以須要像存儲原始文檔那樣,分兩個表來存儲。這就是創建索引的所有了。

評價文檔與查詢相關性

檢索一般不是一個單詞而是一個短語,短語中包含多個單詞。好比個人檢索詞是「百度公司」,只要是介紹一個公司的文檔就會包含「公司」這個單詞,可是隻有涉及「百度」的文檔纔會出現「百度」這個單詞。這說明不一樣單詞的重要性不一樣的,搜索引擎須要關注檢索詞中特殊的詞語才能找到最相關的文檔。系統性衡量單詞重要性的指標是反轉文檔頻率(inverse docuement frequency)。它經過公式log(1/df)計算獲得,df表示文檔頻率(docuement frequency),是出現該單詞文檔的次數。與文檔頻率成反比意味着一個單詞在不一樣文檔中出現的次數越多,越不重要,像「這」、「我」這些詞彙,幾乎會出如今每個文檔裏,能夠說徹底不重要。這些詞稱爲中止詞(stop words)。
文檔與查詢的相關性就能夠用一篇文檔檢索詞出現的次數乘以反轉文檔頻率tf×idf表示(又記做tf-idf),若是一篇文檔出現了多個檢索詞,那麼就是全部這些檢索詞的tf-idf之和。計算tf-idf即是畢業項目第4部分須要完成的任務。

一個檢索詞在一篇文檔出現的次數能夠經過查詢倒排索引獲得,若是一篇文檔出現了一個單詞,那麼倒排索引在那個單詞的記錄中就會包含這個記錄。只有出現這一單詞的文檔纔會出如今倒排索引對應單詞的記錄中,文檔的範圍就大大減小了。在畢業項目裏,倒排索引保持字典序,在檢索一個單詞的時候就可使用二分搜索,這就是畢業項目第5部分須要完成的任務。

正如以前所說的,檢索詞能夠是一個短語,根據不一樣搜索引擎的設計,短語中的單詞能夠要求同時出如今一個文檔中,也能夠要求至少出現一個單詞。這對應兩種組合多個單詞構成最後檢索結果的方法,相與和相或。更進一步,還能夠要求搜索引擎不出現某一個關鍵詞,在百度中能夠經過一個減號「-」來表示。好比我想搜索「電子科技大學」,但不是「西安電子科技大學」,就能夠輸入「電子科技大學 -西安」。這些組合方式在數學上來講,其實就是集合操做。三種基本的集合操做「與」、「或」、「非」正對應着這三種組合方式。這就是畢業項目的第6個部分

畢業項目的第7個部分是表達式求值的一個變種。在百度或者Google中,其實能夠明確指出,多個單詞之間是或的關係仍是與的關係。好比:我想要搜索「北京」或者「大學」,可使用檢索詞「北京 | 大學」,單詞之間用豎線鏈接;若是想要同時檢索「北京」和「大學」,可使用檢索詞「北京 & 大學」,單詞之間用&鏈接。當檢索詞由多個單詞相與、相或組成複雜的邏輯表達式,就須要專門的函數來處理這種複雜的檢索了。好比檢索詞是「北京 - 北京 & 大學 - 清華」,表示我想查找北京的信息,可是不想看到北京大學或者清華大學的信息。這仍然是一個表達式求值的問題,可是不一樣的是,表達式的值並非直接求出,而是被表達成一組複合的檢索關係。這就是畢業項目的7個部分了,是否是並無想象的那麼難。

完成了這個專項課程的畢業項目,我也能夠說是,實現過搜索引擎的人了,雖然這個搜索引擎是最最簡單的版本。在這個過程當中,搜索引擎的面紗也被一步步揭開,你會發現搜索引擎也不過如此嘛。

可是搜索引擎其實遠不止如此,百度和Google爲了加快檢索的速度、提升搜索的相關性,還作出了不少的努力。好比緩存經常使用的搜索結果,搜索結果反做弊。

知識雖然漫漫無窮,值得咱們用一輩子去學習,但事物的本質與核心思想始終是簡潔的。

相關文章
相關標籤/搜索