中文分詞實現——雙向最大匹配,中文分詞匹配

來源:互聯網
上載者:User

中文分詞實現——雙向最大匹配,中文分詞匹配

關於中文分詞的一些基本介紹,可以看這篇部落格《中文分詞方法總結》。這裡就不再進行詳細介紹了。

雙向最大匹配方法

雙向最大匹配方法是一種基於詞典的分詞方法。基於詞典的分詞方法是按照一定策略將待分析的漢字串與一個“大機器詞典”中的詞條進行匹配,若在詞典中找到某個字串,則匹配成功。

按照掃描方向的不同:正向匹配和逆向匹配

按照長度的不同:最大匹配和最小匹配

正向最大匹配思想FMM

1.從左向右取待切分漢語句的m個字元作為匹配欄位,m為大機器詞典中最長詞條個數。

2.尋找大機器詞典並進行匹配。若匹配成功,則將這個匹配欄位作為一個詞切分出來。

若匹配不成功,則將這個匹配欄位的最後一個字去掉,剩下的字串作為新的匹配欄位,進行再次匹配,重複以上過程,直到切分出所有詞為止。

逆向最大匹配演算法BMM

該演算法是正向最大匹配的逆向思維,匹配不成功,將匹配欄位的最前一個字去掉,實驗表明,逆向最大匹配演算法要優於正向最大匹配演算法。


雙向最大匹配法(Bi-directction Matching method,BM)

    雙向最大匹配法是將正向最大匹配法得到的分詞結果和逆向最大匹配法的到的結果進行比較,從而決定正確的分詞方法。據SunM.S. 和 Benjamin K.T.(1995)的研究表明,中文中90.0%左右的句子,正向最大匹配法和逆向最大匹配法完全重合且正確,只有大概9.0%的句子兩種切分方法得到的結果不一樣,但其中必有一個是正確的(歧義檢測成功),只有不到1.0%的句子,或者正向最大匹配法和逆向最大匹配法的切分雖重合卻是錯的,或者正向最大匹配法和逆向最大匹配法切分不同但兩個都不對(歧義檢測失敗)。這正是雙向最大匹配法在實用中文資訊處理系統中得以廣泛使用的原因所在。


在本文實現的方法中,是綜合考慮了正向和逆向最大匹配的結果,加入了一些啟發學習法的規則來對分詞結果進行進一步消歧的。

啟發學習法規則:

    1.如果正反向分詞結果詞數不同,則取分詞數量較少的那個。

    2.如果分詞結果詞數相同

                 a.分詞結果相同,就說明沒有歧義,可返回任意一個。

                 b.分詞結果不同,返回其中單字較少的那個。


下面是具體實現


package Segment;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashSet;import java.util.Set;import java.util.Vector;public class FBSegment {private static Set<String> seg_dict;//載入詞典public static void Init(){seg_dict = new HashSet<String>();String dicpath = "data/worddic.txt";String line = null;BufferedReader br;try{br = new BufferedReader( new InputStreamReader( new FileInputStream(dicpath)));while((line = br.readLine()) != null){line = line.trim();if(line.isEmpty())continue;seg_dict.add(line);}br.close();}catch(IOException e){e.printStackTrace();}}/** * 前向演算法分詞 * @param seg_dict 分詞詞典 * @param phrase 待分詞句子 * @return 前向分詞結果 */private static Vector<String> FMM2( String  phrase){int maxlen = 16;Vector<String> fmm_list = new Vector<String>();int len_phrase = phrase.length();int i=0,j=0;while(i < len_phrase){int end = i+maxlen;if(end >= len_phrase)end = len_phrase;String phrase_sub = phrase.substring(i, end);for(j = phrase_sub.length(); j >=0; j--){if(j == 1)break;String key =  phrase_sub.substring(0, j);if(seg_dict.contains(key)){fmm_list.add(key);i +=key.length() -1;break;}}if(j == 1)fmm_list.add(""+phrase_sub.charAt(0));i+=1;}return fmm_list;}/** * 後向演算法分詞 * @param seg_dict 分詞詞典 * @param phrase 待分詞句子 * @return 後向分詞結果 */private static Vector<String> BMM2( String  phrase){int maxlen = 16;Vector<String> bmm_list = new Vector<String>();int len_phrase = phrase.length();int i=len_phrase,j=0;while(i > 0){int start = i - maxlen;if(start < 0)start = 0;String phrase_sub = phrase.substring(start, i);for(j = 0; j < phrase_sub.length(); j++){if(j == phrase_sub.length()-1)break;String key =  phrase_sub.substring(j);if(seg_dict.contains(key)){bmm_list.insertElementAt(key, 0);i -=key.length() -1;break;}}if(j == phrase_sub.length() -1)bmm_list.insertElementAt(""+phrase_sub.charAt(j), 0);i -= 1;}return bmm_list;}/** * 該方法結合正向匹配和逆向匹配的結果,得到分詞的最終結果 * @param FMM2 正向匹配的分詞結果 * @param BMM2 逆向匹配的分詞結果 * @param return 分詞的最終結果 */public static Vector<String> segment( String phrase){Vector<String> fmm_list = FMM2(phrase);Vector<String> bmm_list = BMM2(phrase);//如果正反向分詞結果詞數不同,則取分詞數量較少的那個if(fmm_list.size() != bmm_list.size()){if(fmm_list.size() > bmm_list.size())return bmm_list;else return fmm_list;}//如果分詞結果詞數相同else{//如果正反向的分詞結果相同,就說明沒有歧義,可返回任意一個int i ,FSingle = 0, BSingle = 0;boolean isSame = true;for(i = 0; i < fmm_list.size();  i++){if(!fmm_list.get(i).equals(bmm_list.get(i)))isSame = false;if(fmm_list.get(i).length() ==1)FSingle +=1;if(bmm_list.get(i).length() ==1)BSingle +=1;}if(isSame)return fmm_list;else{//分詞結果不同,返回其中單字較少的那個if(BSingle > FSingle)return fmm_list;else return bmm_list;}}}public static void main(String [] args){String test = "我是一個學生";FBSegment.Init();System.out.println(FBSegment.segment(test));}}

輸出:[我, 是, 一個, 學生]


瞭解更詳細的資訊,可以到這裡https://github.com/talentlei

參考:

中文分詞演算法筆記 http://www.cnblogs.com/lvpei/archive/2010/08/04/1792409.html;

中文分詞演算法總結  http://blog.csdn.net/chenlei0630/article/details/40710325;




為何中文分詞的幾大主流分詞技術,沒有用逆向最大匹配或者雙向最大匹配分詞演算法的?

速度是關鍵,逆向最大匹配需要專門建立逆向匹配索引。操作維護比較麻煩
 
漢語分詞演算法怎實現?

常用的分詞演算法有正向最大匹配、逆向最大匹配、雙向最大匹配、首選法、最少分詞法、詞網格演算法等等。
最大匹配法(Forward Maximum Matching method, FMM法):選取包含6-8個漢字的符號串作為最大符號串,把最大符號串與詞典中的單詞條目相匹配,如果不能匹配,就削掉一個漢字繼續匹配,直到在詞典中找到相應的單詞為止。匹配的方向是從右向左。
逆向最大匹配法(Backward Maximum Matching method, BMM法):匹配方向與MM法相反,是從左向右。實驗表明:對於漢語來說,逆向最大匹配法比最大匹配法更有效。
雙向匹配法(Bi-direction Matching method, BM法):比較MM法與RMM法的切分結果,從而決定正確的切分。
首選法(Optimum Matching method, OM法):將詞典中的單詞按它們在文本中的出現頻度的大小排列,高頻度的單詞排在前,頻度低的單詞排在後,從而提高匹配的速度。
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.