中文分词技术(一):规则分词
基于規則的分詞是一種機械分詞方法,主要通過維護詞典,在切分語句時,將語句的每個字符串與詞典中的詞進行逐一匹配,找到則切分,否則不切分。按照語句切分的方式,可分為:正向最大匹配法、逆向最大匹配法、雙向最大匹配法。下面將詳細介紹。
一、正向最大匹配法
正向最大匹配法(Maximun Match Method,簡稱MM)的基本思路是:假設分詞詞典中最長詞的長度為i個字符,則用被處理語句的前i個字符作為匹配字段,來查找詞典。如果匹配到這個字段,則這個字段作為一個詞被切分出來。如果詞典沒有匹配到這個字段,就將匹配字段的最后一個字符去掉,再把剩下的匹配字段與詞典匹配,直至匹配成功或者剩余字符串長度為0。這樣就完成了一輪匹配,然后取下一個i個字符的字符串進行匹配處理。
大致步驟如下:
首先定義待切分字符串s1,分詞后的輸出為s2,詞典最大詞長為maxlen
例如:詞典為? ['研究','生命','命','的','研究生','起源'],則語句“研究生命的起源”可以切分為:['研究生', '命', '的', '起源']。具體代碼如下:
class MM(object):def __init__(self):self.window_size=3 #詞典的最長詞長度def cut(self,text):dic=['研究','生命','命','的','研究生','起源']result=[]index=0text_length=len(text)while text_length>index:for size in range(self.window_size+index,index,-1): #一個for循環為一個長度為詞典中最長詞條的匹配字段,沒有匹配到,去掉最后一個字,再來匹配words=text[index:size]if words in dic:index=size-1 #調整下一個匹配字段的起始位置break #匹配到字典,跳出本次循環index+=1 #出現上一個字段匹配到不在詞典中的單字符時,保證正確索引下一個匹配字段的起始位置result.append(words + '--')print(result)if __name__ =='__main__':text='研究生命的起源'cut_mm=MM()cut_mm.cut(text)二、逆向最大匹配法
逆向最大匹配法(Reverse Maximum Match Method,簡稱RMM)的基本思想與正向自帶類似,不過是分詞切分的方向與MM法相反。逆向最大匹配法從待處理文本的末端開始切分匹配,每次取最末端的i個字符(i為詞典中最長詞數)作為匹配字段,若匹配失敗,去掉匹配字段最前面的一個字,繼續匹配。
需要注意的是,逆向最大匹配法使用的詞典是逆序詞典,詞條都按逆序方式存放。?
關于準確度,與正向最大匹配法相比,逆向最大匹配法的誤差要小一點。
例如:?詞典為? ['研究','生命','命','的','研究生','起源'],則語句“研究生命的起源”可以切分為:['研究', '生命', '的', '起源']。
代碼如下:
# coding=utf-8 #逆向最大匹配法分詞 class RMM(object):def __init__(self):self.window_size=3 #詞典的最長詞長度def cut(self,text):dic=['研究','生命','命','的','研究生','起源']result=[]index=len(text)while index>0:for size in range(index-self.window_size,index): words=text[size:index]if words in dic:index=size+1 #調整下一個匹配字段的起始位置break #匹配到字典,跳出本次循環index-=1 #出現上一個字段匹配到不在詞典中的單字符時,保證正確索引下一個匹配字段的起始位置result.append(words + '--')result.reverse()print(result)if __name__ =='__main__':text='研究生命的起源'cut_rmm=RMM()cut_rmm.cut(text)?三、雙向最大匹配法
雙向最大匹配法(Bi-directction Match Method)的基本思想是將正向最大匹配法得到的分詞結果和逆向最大匹配法得到的結果進行比較,根據雙向最大匹配原則,選取分析結果。
雙向最大匹配原則:
(1)如果正反向分詞結果詞數不同,則取分詞數量較少的那個;
(2)如果正反向分詞結果詞數相同:
- 分詞結果相同,可返回任意一個;
- 分詞結果不同,返回其中單字較少的那個。
例如:
# coding=utf-8 #雙向最大匹配法 class MM(object):def __init__(self):self.window_size=3 #詞典的最長詞長度def cut(self,text):dic=['研究','生命','命','的','研究生','起源']result1=[]index=0text_length=len(text)while text_length>index:for size in range(self.window_size+index,index,-1): words=text[index:size]if words in dic:index=size-1 #調整下一個匹配字段的起始位置break #匹配到字典,跳出本次循環index+=1 result1.append(words + '--')print("正向最大匹配:",result1)return result1 class RMM(object):def __init__(self):self.window_size=3 #詞典的最長詞長度def cut(self,text):dic=['研究','生命','命','的','研究生','起源']result2=[]index=len(text)while index>0:for size in range(index-self.window_size,index): words=text[size:index]if words in dic:index=size+1 #調整下一個匹配字段的起始位置break #匹配到字典,跳出本次循環index-=1 #出現上一個字段匹配到不在詞典中的單字符時,保證正確索引下一個匹配字段的起始位置result2.append(words + '--')result2.reverse()print("逆向最大匹配:",result2)return result2if __name__ =='__main__':text='研究生命的起源'result=[]one_length1=0one_length2 = 0cut_mm=MM()result1=cut_mm.cut(text)cut_rmm = RMM()result2=cut_rmm.cut(text)if len(result1)==len(result2): #正反向分詞結果數相同if result1 ==result2 :#正反向分詞結果數相同,結果相同,返回任意一個result=result1else:#統計分析結果的單字數,#正反向分詞結果數相同,結果不同,返回單字少的for word in result1:if len(word)==1:one_length1 +=1for word in result2:if len(word)==1:one_length2 +=1if one_length2>one_length1:result=result1else:result =result2else:#正反向分詞結果數不同,選擇分次數少的if len(result1 )>len(result2 ):result =result2else:result = result1print("雙向最大匹配法:",result)綜上可知,基于規則的分詞一般都較為簡單高效,但是詞典的維護是一個很龐大的工程,很難通過詞典覆蓋到所有詞。
總結
以上是生活随笔為你收集整理的中文分词技术(一):规则分词的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python转换PDF,Word/Exc
- 下一篇: 如何看电影学英语