詹茂森 秦勇
摘要:在基于社會計算的個性化推薦系統(tǒng)開發(fā)中,搜索引擎的開發(fā)是其中一個重要的環(huán)節(jié),搜索引擎的質(zhì)量直接關(guān)系系統(tǒng)搜索結(jié)果的性能。該文對該內(nèi)容進(jìn)行了專題的研究,為該模塊的設(shè)計提供了良好的理論基礎(chǔ),也為系統(tǒng)相關(guān)主題的開發(fā)奠定了一定的基礎(chǔ)。
關(guān)鍵詞:搜索引擎;推薦;系統(tǒng)
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2014)22-5370-03
基于社會計算的個性化推薦系統(tǒng)的搜索引擎是系統(tǒng)開發(fā)的一個重要環(huán)節(jié),該搜索結(jié)果質(zhì)量直接關(guān)系到系統(tǒng)的性能,從而直接影響到系統(tǒng)的整體性能。本系統(tǒng)中解析的文檔類型以html文檔為主,采用Lucene搜索引擎,獨立于運行平臺的方式,實現(xiàn)了文檔的解析和索引的創(chuàng)建。
1 Lucene搜索引擎簡介
1) Lucene
Lucene 是一個出色并且是開源的全文搜索引擎。他并不是一個完整的全文檢索應(yīng)用,但是它提供了大量的 API ,可以方便能夠高效快捷地地對全文創(chuàng)建索引,最主要的是,他可以對現(xiàn)有的在各種各種的系統(tǒng)增加全文檢索的功能,官方也一直維護(hù)、更新版本,使用越來越方便,深受廣大編程者和用戶的青睞。
Lucene是一個高效的、 可擴(kuò)展的全文檢索庫, 僅支持純文本文件的索引(Index)和檢索(Search), 并不處理從其他格式的文件中抽取純文本文件, 或從網(wǎng)絡(luò)中抓取文件。簡單地說, Lucene實現(xiàn)兩個功能,分別是索引和檢索。索引所做的工作是為各種各樣的文檔構(gòu)建Lucene 所能夠識別的索引文件。
Lucene作為一個非常優(yōu)秀并且開源的全文搜索引擎,不僅性能高,架構(gòu)清晰,擴(kuò)展性強,而且其建立索引后的文件格式也獨立于應(yīng)用平臺,從而使索引文件能夠跨平臺共享,對任意可轉(zhuǎn)換為文本格式的數(shù)據(jù)都能夠進(jìn)行索引和搜索。例如html網(wǎng)頁、本地中的ppt,txt,pdf等等都可以對其建立索引。
首先, Lucene集成了多種文檔解析器, 能夠?qū)Υ蟛糠种髁魑谋疚募?如:html, pdf, MS Word, Text File等等進(jìn)行解析, 抽取純文本內(nèi)容。由于Lucene只能索引純文本, 所以必須借助于上述各種不同功能的解析器對各種不同類型的文檔進(jìn)行解析。
然后, 使用Lucene的分詞器(Analyzer),對提取出的純文本內(nèi)容進(jìn)行索引, 并生成索引項,以供做搜索之用。
最后, Analyzer把生成的信息寫入索引文件之后。搜索所做的工作是使用反向索引找出與用戶請求相匹配的文本內(nèi)容并返還給用戶。 因為,Lucene 默認(rèn)情況下不對用戶輸入的搜索關(guān)鍵詞進(jìn)行分詞處理。所以,這部分不重點討論搜索的內(nèi)容,相關(guān)內(nèi)容在下面的章節(jié)中講解。
2) 引擎結(jié)構(gòu)
Lucene搜索引擎對系統(tǒng)的要求不高,既可以運行在Windows系統(tǒng)上,也可以運行在Linux系統(tǒng)上。搜索引擎使用的一般是集中式。把多個服務(wù)器的網(wǎng)絡(luò)資源通通下載到本地,目的是為建立索引和文本搜索做準(zhǔn)備,這就是集中式的處理方法。如果按照按結(jié)構(gòu)分,Lucene引擎結(jié)構(gòu)可由搜索器、 索引器和檢索器等組成。
搜索器就是網(wǎng)絡(luò)機器人(網(wǎng)絡(luò)蜘蛛)。利用這種爬蟲程序,在遵從機器人排除協(xié)議的前提下,從某個網(wǎng)頁開始,提取URL網(wǎng)址,如此循環(huán),不斷地提取到新的 URL 網(wǎng)址,同時取出相應(yīng) URL 的資源。
索引器的則是利用下載的到的各種網(wǎng)絡(luò)資源,提取各種資源的索引項,為生成文檔庫的索引表做準(zhǔn)備。
檢索器主要任務(wù)是通過辨識用戶的查詢需求,在文檔庫中進(jìn)行快速匹配查找并且檢索出相應(yīng)的文檔,之后就是對文檔進(jìn)行相關(guān)性排序,并提供一個網(wǎng)頁鏈接供用戶操作。所以,,一個出色的搜索引擎如果把這三個部分都做得好,用戶的使用需求就一定可以得到滿足。
3) 解析網(wǎng)頁和索引入庫
把網(wǎng)頁中的元素標(biāo)記( Token) 及其標(biāo)記之后的內(nèi)容提取出來,目的的是利于入庫,這就是網(wǎng)頁的解析。一個字段都要有一個Token與之相對應(yīng)。可以理解為此字段的內(nèi)容就是Token 的內(nèi)容。
使用的實現(xiàn)方法:自定義一個 Parser 解析類,接著實現(xiàn)網(wǎng)頁文件流的讀入,然后把這個流解析成以字符串格式輸出,為下一步處理做準(zhǔn)備,最后循環(huán)提取 Token 及其相關(guān)內(nèi)容。提取每一個Token 的目的是給不同的 Token 加上不同的權(quán)值。這樣在搜索出結(jié)果的時候,就可以根據(jù)不同的權(quán)值來排序。提取 Token便可以入庫:
2 Lucene分詞器
1) Lucene分詞簡介
lucene將關(guān)鍵詞出現(xiàn)頻率和關(guān)鍵詞出現(xiàn)位置分別作為詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不僅保存有每個關(guān)鍵詞,還保留了指向頻率文件和位置文件的指針,通過指針可以找到該關(guān)鍵詞的頻率信息和位置信息。
Lucene特點是關(guān)鍵詞是按字符順序排列的,其內(nèi)部沒有集成使用B樹結(jié)構(gòu),所以可以用二元搜索算法快速定位Lucene的關(guān)鍵詞。
Lucene中也使用了field(域)的概念,用于表達(dá)信息所在位置。如標(biāo)題、內(nèi)容、url等等。需要指出的是這些域(field)是可以自定義設(shè)置的。在索引文件中,每一個field(域)的信息也記錄在詞典文件中,每個關(guān)鍵詞都有一個field信息,因為每個關(guān)鍵詞一定屬于一個或多個field。 關(guān)鍵詞沒有在field(域)中出現(xiàn),就意味著用戶想要找的內(nèi)容沒有出現(xiàn)在數(shù)據(jù)庫中。
為了減小索引文件的大小,Lucene對索引使用壓縮技術(shù)。首先,對詞典文件中的關(guān)鍵詞進(jìn)行了壓縮,關(guān)鍵詞壓縮為<前綴長度,后綴>,例如:當(dāng)前詞為“廣東省東莞”,上一個詞為“廣東省”,那么“廣東省東莞”壓縮為<3,東莞>。
其次大量用到的是對數(shù)字的壓縮,數(shù)字只保存與上一個值的差值,目的是減小數(shù)字的長度,進(jìn)而減少保存該數(shù)字需要的字節(jié)數(shù)。例如當(dāng)前文章號是1279(不壓縮要用3個字節(jié)保存),上一文章號是1273,壓縮后保存6(只用一個字節(jié))。使用壓縮技術(shù)的好處就是提高搜索的速度和效率。需要指出的是,Lucene3.5版本后,不需要手動處理索引文件,當(dāng)索引的文件大到一定的程度之后,Lucene會自動的壓縮索引文件。
2) Lucene分詞原理
a. 建立倒排索引。同時記錄關(guān)鍵詞在文章中出現(xiàn)頻率和出現(xiàn)的位置。如何用普通的順序匹配算法,不建索引,而是對所有文章的內(nèi)容進(jìn)行字符串匹配,這個過程將會相當(dāng)緩慢,當(dāng)文章數(shù)目很大時,時間往往是長到無法忍受的。
b. 獲得文章/記錄中的關(guān)鍵詞,并對關(guān)鍵詞進(jìn)行處理。如:lives,living→live
3 IKAnalyzer分詞器
1) IKAnalyzer分詞簡介
對信息進(jìn)行索引前,需要要對關(guān)鍵詞進(jìn)行分詞。英文使用空格和標(biāo)點來分隔單詞 而中文使用表意文字,不能通過空格和標(biāo)點來進(jìn)行分詞。Lucene 自帶的分詞器,有StandardAnalyzer, StopAnalyzer ,SimpleAnalyzer,WhiteSpaceAnalyzer。這些分詞器要么是單字分詞 要么采用停用詞分詞,要么采用簡單的分詞,要么是按空格分詞。
但是,它們并不能有效地解決中文分詞的問題。目前中文分詞算法工具包大致包括paoding、imdict、mmseg4j、IK。其中最常用的是IKAnalyzer,下面我大致介紹一下這個中文分詞器,結(jié)構(gòu)圖1所示。
2) IKAnalyzer特點
IKAnalyzer支持多子處理器語言分析模式:中文、數(shù)字、字母,并兼容日文、韓文。它采用“正向迭代最細(xì)粒度切分算法”的算法,支持細(xì)粒度和最大詞長兩種分詞方式,速度最大支持80W字/秒,即1600KB/秒。此外,它擴(kuò)展lucene的擴(kuò)展實現(xiàn),采用歧義分析算法優(yōu)化查詢關(guān)鍵詞的搜索排列組合,提高lucene檢索命中率。同時,它具有較小的內(nèi)存占用,優(yōu)化詞庫占有空間,用戶可自定義擴(kuò)展詞庫。
IKAnalyzer由org.wltea.analyzer.IKSegmentation和org.wltea.analyzer.lucene.IKAnalyzer兩大主要類組成,其中,org.wltea.analyzer.IKSegmentation是IK分詞器的核心類,真正分詞的實現(xiàn)類。而org.wltea.analyzer.lucene.IKAnalyzer則是IK分詞主類,基于Lucene的Analyzer接口實現(xiàn)。
4 基于Lucene的IKAnalyzer分詞器
1) paoding、mmseg4j和IKAnalyzer
目前流行的幾大開源分詞器主要有:paoding、mmseg4j、IKAnalyzer,它們?nèi)齻€都是基于JAVA語言開發(fā)的,各有優(yōu)劣,具體如下:
mmseg4j:有兩種分詞方法,Simple和Complex,目前 complex 1200kb/s左右,simple 1900kb/s左右,但內(nèi)存開銷了50M左右。采用MMSeg算法,代碼復(fù)雜度是2500行左右代碼。有英文文檔,原理比較簡單。有自帶搜狗的詞庫,支持自定義詞庫,不支持自動檢測。 自帶詞庫16W個。Lucene和solr的支持:支持Lucene2.4、solr1.3。
Paoding:采用基于“不限制個數(shù)”的詞典文件對文章進(jìn)行有效切分算法,使能夠?qū)υ~匯分類定義,代碼復(fù)雜度是7000行左右代碼。1秒可準(zhǔn)確分詞100萬漢字。支持不限制個數(shù)的用戶自定義詞庫,自動檢測詞庫的更新。自帶詞庫22W個。
IKAnalyzer:每秒80W字。采用正向迭代最細(xì)粒度切分算法,代碼復(fù)雜度是4500行左右代碼,有一個中文使用手冊,支持自定義詞庫,不支持自動檢測。 自帶詞庫27W個。
根據(jù)上面介紹,結(jié)合本系統(tǒng)特點,本系統(tǒng)采用基于Lucene的IKAnalyzer分詞器。
2) 自定義同義詞分詞器
Lucene分詞機制:索引過程和查詢過程都用到了一個關(guān)鍵工具分詞器analyzer。它將要被索引的內(nèi)容以流的形式讀入,經(jīng)過詞語切分、過濾干擾詞等一系列處理,最終輸出一個語匯單元流、每個語匯單元攜帶了一個文本值和它的一些元數(shù)據(jù),原文本從起點到終點的偏移量、語匯單元類型和position incremen。
同義詞索引原理:索引器將語匯單元寫入文件時會丟棄每個語匯單元的起點偏移量和終點偏移量。位置增量是語匯單元攜帶到索引文件的唯一附加元數(shù)據(jù)。這個值的意義是當(dāng)前單詞與前一個單詞的位置偏移量。當(dāng)這個值為 0 是表示當(dāng)前單詞與前一個單詞被索引到同一個位置上。但是 Lucene 對中文語言處理能力十分有限,無法中文語義分詞只能將一句話機械性的分成單字或雙字 。例如: 用單字分詞會將“我來自廣東” 切分成 :“我” “來” “來” “自” “廣” “東”。顯然,這種情形為每個字添加同義詞索引是沒有意義的 因此 需要一個功能更強大的中文分詞器來支持。
本系統(tǒng)采用堆棧的形式來保存同義詞的詞組或單詞。如(“中國”,“大陸”),(“我”,“咱”)等等都可以是同義詞。自定義同義詞分詞器使用四個類來實現(xiàn)。
MyDefinedSameAnalyzer類主要是加載的搜狗中文分詞器。使用棧來定義過濾器是MyDefinedSameTokenFilter類。DefinedSamewordEngine類是一個接口,使用接口有利于程序的擴(kuò)展。DefinedSimpleSameword類是定義同義詞字典,并判斷如果有同義詞就返回true
3) 自定義停用詞過濾分析
在關(guān)鍵詞處理過程中,有可能會經(jīng)常出現(xiàn)沒有意義的詞。如,“是”,“來”等等。除此之外,停用詞分析器StopAnalyzer也已經(jīng)把沒有意義的英文單詞收錄到停用詞表中。默認(rèn)情況下,這個表被用來濾詞用戶輸入關(guān)鍵詞中的詞匯,還可以過濾掉一些特定字符,如&,*等,也會把英文的大寫字母自動轉(zhuǎn)換成小寫字母。
還有就是,當(dāng)搜索系統(tǒng)需要屏蔽掉一些用戶輸入的中文敏感詞的時候,就得把敏感詞自動的過濾掉。這個時候就得使用lucene強大的停用詞分析器。由于Luene自帶有停用詞分析器StopAnalyzer,這使得要過濾掉停用詞就變得非常簡單。而且使用Lucene3.5的版本,也支持中文分詞。
自定義一個停用詞表就可以過濾掉自己設(shè)定的中文或者英文的敏感詞。默認(rèn)情況下,Lucene會把系統(tǒng)自帶的英文停用詞加載在停用詞分析器中。TokenStream讀流屬性中的數(shù)據(jù)即讀出數(shù)據(jù)。另外,停用詞分析器StopAnalyzer自動把數(shù)字給過濾掉了,所以要實現(xiàn)數(shù)字的搜索需要經(jīng)過特別的處理。具體的處理過程可以參考GxjtController類的searchcont( )函數(shù)的代碼部分。
為了實現(xiàn)該功能,搜索的關(guān)鍵詞要先經(jīng)過過濾器處理,再經(jīng)過同義詞的處理。
參考文獻(xiàn):
[1] 馮斌.基于 Lucene 小型搜索引擎的研究與實現(xiàn)[D].武漢:武漢理工大學(xué),2008.
[2] 楊馥顯,劉嘉勇.基于JSP的數(shù)據(jù)庫開發(fā)技術(shù)研究[J].通信技術(shù),2011,44(3):51-53.
[3] 梁弼,王光瓊,鄧小青.基于 Lucene 的全文檢索系統(tǒng)模型的研究及應(yīng)用[J].微型機與應(yīng)用,2011,30(1).
[4] 費洪曉,康松林,朱小娟,等.基于詞頻統(tǒng)計的中文分詞的研究[J].計算機工程與應(yīng)用,2005,41(7):67-68,100.