這應該是我第二次寫IK中文分詞的相關東西了。話說IK真心好用,最開始就用過IK的搜索後來又用它和solr結合使用。 java
關於IK能夠參考下官方文檔的介紹,使用配置也有相關的pdf文檔。http://www.oschina.net/p/ikanalyzer
算法
今天僅僅使用到了IK的分詞功能。因此代碼很簡單,我就直接貼上來了。 shell
這個代碼主要是對傳入的參數進行分詞,並統計好每一個次的頻率。代碼以下: 數據庫
public static Map getTextDef(String text) throws IOException { Map<String, Integer> wordsFren=new HashMap<String, Integer>(); IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(text), true); Lexeme lexeme; while ((lexeme = ikSegmenter.next()) != null) { if(lexeme.getLexemeText().length()>1){ if(wordsFren.containsKey(lexeme.getLexemeText())){ wordsFren.put(lexeme.getLexemeText(),wordsFren.get(lexeme.getLexemeText())+1); }else { wordsFren.put(lexeme.getLexemeText(),1); } } } return wordsFren; }
代碼很簡單,主要介紹下IK中的類,IKSegmenter是分詞的主要類,其參數分別是分詞的句子或者文章,後面的參數是是否開啓智能模式,不開啓就按最小詞義分。 工具
分詞的結果是Lexeme這個類,用其中的getLexemeText()方法就能取出相關的分詞結果。 測試
接下來是計算詞頻,將分詞結果和出現次數放到一個map結構中,map的value對應了詞的出現次數。這裏注意一下,我只記錄兩個字及兩個字以上的分詞結果。 優化
public static void sortSegmentResult(Map<String,Integer> wordsFrenMaps,int topWordsCount){ System.out.println("排序前:================"); Iterator<Map.Entry<String,Integer>> wordsFrenMapsIterator=wordsFrenMaps.entrySet().iterator(); while (wordsFrenMapsIterator.hasNext()){ Map.Entry<String,Integer> wordsFrenEntry=wordsFrenMapsIterator.next(); System.out.println(wordsFrenEntry.getKey()+" 的次數爲"+wordsFrenEntry.getValue()); } List<Map.Entry<String, Integer>> wordFrenList = new ArrayList<Map.Entry<String, Integer>>(wordsFrenMaps.entrySet()); Collections.sort(wordFrenList, new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> obj1, Map.Entry<String, Integer> obj2) { return obj2.getValue() - obj1.getValue(); } }); System.out.println("排序後:================"); for(int i=0;i<topWordsCount&&i<wordFrenList.size();i++){ Map.Entry<String,Integer> wordFrenEntry=wordFrenList.get(i); if(wordFrenEntry.getValue()>1){ System.out.println(wordFrenEntry.getKey()+" 的次數爲"+wordFrenEntry.getValue()); } } }
這個方法主要對分詞結果及詞頻按照出現次數排序,沒有本身去寫實現,主要借用了collections的sort方法。 url
測試方法以下: spa
public static void main(String args[]) throws IOException { String text = "IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。從2006年12月推出1.0版開始,IKAnalyzer已經推出 了3個大版本。最初,它是以開源項目 Lucene爲應用主體的,結合詞典分詞和文法分析算法的中文分詞組件。新版本的IKAnalyzer3.0則發展爲 面向Java的公用分詞組件,獨立於Lucene項目,同時提供了對Lucene的默認優化實現。\n" + "\n" + "IKAnalyzer3.0特性:\n" + "\n" + "採用了特有的「正向迭代最細粒度切分算法「,具備60萬字/秒的高速處理能力。\n" + "\n" + "採用了多子處理器分析模式,支持:英文字母(IP地址、Email、URL)、數字(日期,經常使用中文數量詞,羅馬數字,科學計數法),中文詞彙(姓名、地名處理)等分詞處理。\n" + "\n" + "優化的詞典存儲,更小的內存佔用。支持用戶詞典擴展定義\n" + "\n" + "針對Lucene全文檢索優化的查詢分析器IKQueryParser(做者吐血推薦);採用歧義分析算法優化查詢關鍵字的搜索排列組合,能極大的提升Lucene檢索的命中率。"; int topWordsCount=3; Map<String,Integer> wordsFrenMaps=getTextDef(text); sortSegmentResult(wordsFrenMaps,topWordsCount); }輸出結果爲:
加載擴展詞典:ikdict/ext.dic 加載擴展中止詞典:ikdict/english_stopword.dic 加載擴展中止詞典:ikdict/chinese_stopword.dic 排序前:================ ikanalyzer3.0 的次數爲2 開源 的次數爲2 開發 的次數爲1 姓名 的次數爲1 lucene 的次數爲5 內存 的次數爲1 詞彙 的次數爲1 支持 的次數爲2 英文字母 的次數爲1 查詢 的次數爲2 面向 的次數爲1 採用 的次數爲1 12月 的次數爲1 推薦 的次數爲1 ikanalyzer 的次數爲2 地名 的次數爲1 默認 的次數爲1 提供 的次數爲1 特性 的次數爲1 地址 的次數爲1 中文 的次數爲4 文法 的次數爲1 組件 的次數爲2 新版本 的次數爲1 吐血 的次數爲1 檢索 的次數爲2 全文 的次數爲1 經常使用 的次數爲1 公用 的次數爲1 分析器 的次數爲1 項目 的次數爲2 存儲 的次數爲1 數量詞 的次數爲1 處理器 的次數爲1 工具包 的次數爲1 佔用 的次數爲1 計數 的次數爲1 分析 的次數爲3 版本 的次數爲1 正向 的次數爲1 url 的次數爲1 用了 的次數爲2 迭代 的次數爲1 搜索 的次數爲1 模式 的次數爲1 email 的次數爲1 關鍵字 的次數爲1 日期 的次數爲1 擴展 的次數爲1 提升 的次數爲1 ikqueryparser 的次數爲1 能力 的次數爲1 3個 的次數爲1 詞典 的次數爲3 排列組合 的次數爲1 更小 的次數爲1 定義 的次數爲1 科學 的次數爲1 高速 的次數爲1 輕量級 的次數爲1 優化 的次數爲4 細粒度 的次數爲1 2006年 的次數爲1 發展爲 的次數爲1 多子 的次數爲1 命中率 的次數爲1 立於 的次數爲1 數字 的次數爲1 萬字 的次數爲1 60 的次數爲1 特有 的次數爲1 羅馬數字 的次數爲1 推出 的次數爲2 用戶 的次數爲1 1.0版 的次數爲1 ip 的次數爲1 算法 的次數爲3 分詞 的次數爲5 歧義 的次數爲1 做者 的次數爲1 java 的次數爲2 語言 的次數爲1 主體 的次數爲1 最初 的次數爲1 切分 的次數爲1 排序後:================ lucene 的次數爲5 分詞 的次數爲5 中文 的次數爲4
這裏面要注意一下,IK自己有一個文件叫IKAnalyzer.cfg.xml .net
這個文件能夠本身配置詞典,詞典有兩種分別是ext_dict及ext_stopwords,其中ext_dict主要定義了一些關鍵字,這些關鍵字不會被分詞分開,ext_stopwords主要配置中止詞,什麼是中止詞呢?好比「的」,「得」,「我」這些沒有具體意義可是又出現特別多的詞就不該該做爲關鍵字詞出現,因此在分詞的時候要把這些詞過濾掉。
<properties> <comment>IK Analyzer 擴展配置</comment> <!--用戶能夠在這裏配置本身的擴展字典--> <entry key="ext_dict">ikdict/ext.dic;</entry> <!--用戶能夠在這裏配置本身的擴展中止詞字典--> <entry key="ext_stopwords">ikdict/english_stopword.dic;ikdict/chinese_stopword.dic</entry> </properties>這裏我主要配置了3個詞典,其中的兩個中止詞分別是英文和中文的。網上有不少詞典,可是都不是太全,我收集了一些,彙總了一下分享給你們。
可是OSC好像沒有附件能夠傳。。。放到代碼分享中了,用的自取,http://www.oschina.net/code/snippet_195637_22628
其中中文中止詞4545個,英文中止詞1434個,數據庫相關詞彙1692個。
總結一下,最近正在研究關鍵字及摘要自動生成,這裏主要介紹了使用IK分詞並統計詞頻,並分享了相關的詞典。可是計算關鍵字單靠這樣的分詞統計詞頻仍是無論用的,最近在研究TFIDF算法,後面實現成功了再和你們分享一下。