Lucene實現中文分詞
阿新 • • 發佈:2019-01-29
在之前的文章中已經介紹過Lucene了,這裡就不多做介紹。
一、中文分詞的原理
中文分詞是將一個漢字序列切分為一個一個單獨的詞。分詞就是講連續的字序列安裝一定的規範重新組合成詞序列的過程。隨著機器學習的發展,很多分詞的方法都已經被科研人員實現,也越來越精確。分詞的精確性一定程度上影響了搜尋引擎的查全率與查準率,當然這是在你的中文分詞運用在搜尋引擎的前提之下。
分詞的演算法可以分為:基於字串匹配的分詞方法、基於統計的分詞方法,很容易理解基於字串匹配的分詞方法有很大的侷限性,很難做到準確的分詞,因為世界上沒有一本最完備的詞典,很多專業詞彙、人名巴拉巴拉之類很難涉及到。因此顯而易見,基於統計的分詞方法要更精確同時更復雜。
基於字串匹配的分詞方法又有:正向最大匹配、逆向最大匹配、最少切分等等方法
基於統計的分詞方法很大程度上是根據上下文中,相鄰的字同時出現的次數,字與字相鄰共現的頻率之類資訊來實現更精確的分詞,需要用到統計語言模型,設計很多數學原理,這裡就不做更多介紹了,網上有很多資料。
二、關於停用詞
停用詞是自然語言中關鍵的組成,對於語義的構成有重要的意義,但是很多時候我們在做搜尋是隻需要內容的關鍵詞而不是全部詞,所以去除停用詞是很必要的操作。例如漢語中的:“的”“是”等。
網上有一些漢語中常用停用詞的整理,我使用的是GitHub上的一個停用詞表。
三、程式碼實現
環境是Lucene4.6
import [圖片]java.io.BufferedReader; import [圖片]java.io.File; import [圖片]java.io.FileInputStream; import [圖片]java.io.IOException; import [圖片]java.io.InputStreamReader; import [圖片]java.io.StringReader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import [圖片]org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; //import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; import org.apache.lucene.analysis.util.CharArraySet; import org.apache.lucene.util.Version; public class SegWordTest { //建立一個去除停用詞的分析器物件 public static CharArraySet stopwords = new CharArraySet(Version.LUCENE_46, 3, false); public static Analyzer noStopAnalyzer; public static void initializeData() throws IOException{ //讀取停用詞表格 File filename = new File("someFiles/stopwords.txt"); InputStreamReader reader = new InputStreamReader(new FileInputStream(filename)); BufferedReader br = new BufferedReader(reader); String line = ""; line = br.readLine(); while(line != null){ stopwords.add(line); line = br.readLine(); } br.close(); noStopAnalyzer = new SmartChineseAnalyzer(Version.LUCENE_46, stopwords); } public static void testAnanlyzer(String cont) throws IOException{ /* //不去除停用詞的版本 //建立一箇中文分詞的分析器物件 Analyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_46); //從分析器物件中獲得tokenStream物件 TokenStream tokenStream = analyzer.tokenStream("myfield", new StringReader(cont)); */ TokenStream tokenStream = noStopAnalyzer.tokenStream("myfield", new StringReader(cont)); //設定一個引用,這個引用可以使多種型別,可以是關鍵詞的引用,偏移量的引用等等 //關鍵詞的引用 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); //偏移量的引用,可以得到詞彙開始和結束的位置 //OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); tokenStream.reset(); //很關鍵,不然會報錯 while(tokenStream.incrementToken()){ System.out.println(charTermAttribute); } tokenStream.close(); } public static void main(String args[]) throws IOException{ initializeData(); String con = "這是一架高空高速飛行的飛機"; testAnanlyzer(con); } }