TAG | Lucene
InfoQ: Lucene 2.3:大幅提升索引性能,新增機器學習項目
Ingersoll認為這次的版本中最大的變化是新的索引算法,它使用了新的in-memory模型來達到大幅的速度提升。據Ingersoll 說,單單是把Lucene 2.2 JAR換成Lucene 2.3 JAR就能在某些測試中把索引性能提速500%。其他改變還包括:
- 改進的索引管理——以前在索引過程中,當合併內部索引文件時偶爾會出現長時間的停頓,現在已經消滅了這種現象。另外現在也更容易實現其他途徑去管理索引過程。
- 對象池——
Document、Field和Token的實例現在可在索引分析中重用,因此不但提升了分析的速度,還減少了索引過程中的內存分配次數。- 重新打開IndexReader ——重新打開一個IndexReader去捕捉索引中最新的變化,這個操作的速度現在也更快了,新的reopen()方法只會加載那些變更過的索引片斷,而不是重新加載完整的索引。
- 更簡易的IndexWriter微調——
setMaxBufferedDocs已被更直觀的setRAMBufferSizeMB所取代。另外,2.3的目標是只需通過文件替換就能換下2.2,完全不需要重新編譯。這裡是完整的更新說明。
在寫程式時,基本上都一定要為錯誤的輸入作檢查或修正。這是基本可以用來檢查一個程式有沒有偷懶/偷工減料的最簡單方法。
在上電腦的基本課時,應該一定會提到有關 GIGO(garbage in, garbage out; 垃圾輸入, 無用輸出)。就是說電腦很苯,當輸入的數據是垃圾,輸出就一定只會是垃圾。電腦會出錯,可是人類更易出錯,而且犯的錯誤更多。
最基本的,是能在輸入時即時先作出反應和指出錯誤。最簡單是檢查數據的型態和空白(第一類),而一個比較像樣的程式都有數字、時間、日期、大小和特定格式 (如 email 或 UUID) 的 Pattern 檢查(第二類)。造得仔細一點的程式都有會進一步的檢查,就是數據有效性的檢查;例如年月日的組合是否合理,沒有沒串錯字,重復性,在 database 能不能找到相對應的 ID 之類的(第三類)。而最好的則會著重與人的互動關係,清楚的錯誤說明,能在使用者保持集中力的時間內反應(好像大約三秒),自動的修正、建議(第四類)。
實例
第一類: Yahoo 字典
雖然它說 “請輸入單字查詢,中英文皆可” ,可是日文,法文,德文也能過。假如輸入簡体字或日文漢字它也不會了解。
第二類: 一般的網頁上常見的 “E-mail this page” 表格(我一直很好奇誰會用)。例如這頁的 footer。
它會要求你依一定的格式輸入 email,可是在都不會知道這個 email 是否正確的。
第三類: 現時 forum 的 Signup form。
它會以寄出 validation code 的方式檢查你輸入的 email。
第四類: Google Suggest / Gmail
能在在未按下 sutmit 前給建議,修正,甚至 auto-complete。
以上例子都是 web-application 的原因只是誰也看得到。事實上 client application 的例子更多。
如: Notepad vs UltraEdit vs Microsoft Word vs Eclipse IDE.
好像越說越遠了。回到正題,其中最麻煩,最難實作的是自動化的修正建議。因為它的目的不做到 GIGO,這不是和上文所說的電腦很苯相反嗎?沒有矛盾,它是建基在數據當中正確的部份。
再回到主題,英文串字修正是以沒串錯的部份基礎。(從語言角度上著手也可以,不過這是人類善長的工作,不在本文內容)
英文是由字母組合而成,而它們的組合次序和方式,則可以提示出正確的建議。
用實例來說或會比較易明白: 例如 Monstor (Monster 的誤寫)。以 n-Gram 方式拆解的話,就可以得到 mon, ons, nst, sto, tor。如果和 Monster 比較(mon, mon, nst, ste, ter),其中 3/5 * 3/5 都是對的(因為是互相比較, 所以是兩組)。而如果和 “monsters inc” 比較,則只有 3/5 * 3/8。而拿來和 apple 比較,則完全不付合。只要事先為字並建立 index,用這方法可以快速得到幾個相近的詞語。
一般,英文只要有 3-gram 和 4-gram 就可以有不錯的結果。當然啦,這等零件老早就有寫了出來。如果你是用 Lucene 1.4 的話,花一點心思也可以自己寫出來,而如果用 Lucene 2.0,則已經有現成的 library 可用。
參考: SpellChecker – Lucene-java Wiki
參考: Lucene 2.0 org.apache.lucene.search.spell
就算不用 Lucene,自已利用 php+mysql 也可以寫得到類似的功能,只要依著以上的方式建立 index table 和設計出一句 inner join SQL 就可以。
9 July 2007
Dennis
Apache Lucene 是一個以 java 編寫(現在已有 .NET 版本), 具有高效率, 支持全文檢索的開源搜索引擎. 主要功能是對數據作索引及搜索,它與其他工具配合能處理 word, html, pdf, excel 的全文搜尋。
Lucene 提供了一個簡單確強大的應用程式介面,能夠做全文索引和搜尋,在 Java 裡 Lucene 是一個成熟的免費開放原始碼工具;就其本身而論,Lucene是現在並且是這幾年,最受歡迎的免費 java 資訊檢索程式庫。 人們經常提到資訊檢索程式庫,就像是搜尋引擎,但是不應該將資訊檢索程式庫與網搜索引擎相混淆。
Lucene @ wikipedia 有關 Lucene 的簡介,可以讀 車案 chedong 的文章 http://www.chedong.com/tech/lucene.html (簡體中文) 我就先跳過中文分詞的理論,直接深討在現實應用中會一定會發生多國語言的問題。 體、繁體、英文甚至多國語言在同一文件中同時出現 面對正式的,官方的文件和公司內部文件時是沒有問題的。 它們一般都不會把不同語言混合使用,會更多單一語言。 但是,在 Internet 等的公開場合呢?特別是夾在世界各國文化之間的香港。 "中式英文", "英式中文", 簡體、繁體、日文、英文混合也是很常見的現像。 單純的一個 "ChineseAnalyzer/CJKAnalyzer" 根本沒有用。 就算是比較官方的通告也是一樣,例如:公告以三種語言分別寫一次,放在同一文件內,而不是以連結方式轉換語言。 而在非官方場合,最可怕的情況,卻也是最常見的;就是留言版討論區的文化。 你不能事先知道被索引的文件會是甚麼語言的的。 對自動化的程式來說 Unicode 內文所用的語言是一個謎。 你可能想在統計字元或內碼方面著手。但事實上,實作字碼檢查時已經很麻煩了,再加上語言推算就更亂了,更何況我們根本沒有這方面的數據。算你有 google 一樣的海量數據,它經常還是會出錯。 選擇分詞引擎 雖然,你很想看到純英文文件時應用 StandardAnalyzer。體的文件用相應字典,繁體的文件用另一套字典。是,BIG5 也可能寫英文。 GBK 不但可寫英文,也可以寫繁體,甚至日文的。 Unicode 情況下,你甚至可能使用了日文漢字和簡體也不自覺。如果你參考別人的程式,一般都是把會應用到的 StandardAnalyzer 的名字寫死在原始碼/設定檔中,而不是依被讀的文件而自動更換的。 分詞字典應用建立和更新 如果只是單純使用 n-Gram 或 Bi-gram 的話,可能沒有這麻煩。 但根據字典分詞還是十分有吸引力的,它能提昇一定的準確性和減少索引檔的大小。 先說建立字典的方法,幸好兩岸也有人做常用詞的統計。幸苦一點自己找免費的,還是付錢買的也可以。 把它們合併,轉換成一個 "繁簡中文字典" 相對整體來說還是簡單的。 可是更新就是一個問題了~任由它不更新不是不可以,但網絡和語言都是活的。 而且,在更新後,你要重新為舊件建立新的索引,這比甚麼都要麻煩。 在香港,應該應用那一個 Analyzer 當你發覺 StandardAnalyzer 不太支持中文的時候,在 sandbox 中找到了 CJKAnalyzer。 可是事實上它們都是低能兒,寫得太過簡單了(相對 StandardAnalyzer)。 StandardAnalyzer 應該是用 javacc 生成的,自行胡亂改動不是一個好方法。 以前試過應用 StandardTokenizer,而單純在它不支持的中文 Token 組合再進行二次分詞,效果不錯。 這一篇文章其實是在數年前寫下的 Draft,最近整理 My Documents 時發現。反正有空,拿來修改一下之後就貼在這 Blog。
