mmseg 中文分词

来源:互联网 发布:淘宝电动车专卖店 编辑:程序博客网 时间:2024/05/16 05:04

区别与英文句子,子串,中文汉字之间并没有空格相隔开,所以对于一个汉语的句子来说,如何分词一直也有人在研究,现也有多种根据句子结构,根据词频概率的多种做法,之前因为项目需求需要用到一个中文分词的功能,鉴于时间和功力,就跟网上找了张华平博士的NLPIR中文分词系统,一段时间用还好,可是过段时间之后就完全用不了,错误日志说是因为线程问题,(线程跟时间应该没有关系吧,大概是版权什么的),之后又找了一下编译了一下friso的库文件,但是由于字典文件的路径问题(大神是这么说的),初始化不对,导致分词有误,遂决定自己尝试一下mmseg。
附参考前辈的博文地址 http://blog.csdn.net/sunlylorn/article/details/7652746

大致思路:
首先利用hash_map 构造一个字典 hash_map<WCHAR,vector<BSTR>>,其中vector容器中存放相同词首的词语PS:中国、中国人、中间.blabla....
构造完字典之后根据mmseg的做法
1:首先查找以当前句首词开始的所有的三词chunks
2:根据以下4个规则依次进行筛选
规则1:最大匹配
规则2:最大平均单词长度
规则3:单词长度最小方差
规则4:最大单字单词语素自由度之和

因为涉及词频的查询,最后一步未完成,个人以为,整个算法最关键的地方在于1、词典的构造,词典的大小很大程度决定分词的正确率,2:如何查找以当前句首单词开始的所有chunks这里我用了一个嵌套循环的函数,找到以当前句首开始的所有三词chunks,暂时没有考虑这个词已经是句尾的情况。DicHashmap 就是构造好的汉语字典 

void CWSdic::FindAllTrunks(BSTR str,DicHashmap& dichashmap){int Count=FindWordsCount(str,dichashmap);//获取到以当前句首词开始的最大词长,for(int i=1;i <= Count; i++){Chunk newchunk;//new 一个新的chunknewchunk.push_back( GetBstrByCount(str,i));BSTR str1=str;//str1.Delete(0,i+1);DeleteNCount(str1,i);int Count1 = FindWordsCount(str1,dichashmap);for(int j = 1; j<= Count1;j++ ){Chunk newchunk1(newchunk);//构造的过程,将chunk的元素复制到里面//newchunk1.push_back(str1.Left(j));newchunk1.push_back(GetBstrByCount(str1,j));BSTR str2 = str1;//str2.Delete(0,j+2);DeleteNCount(str2,j);int Count2 = FindWordsCount(str2,dichashmap);for(int k=1;k<= Count2;k++){Chunk newchunk2(newchunk1);//newchunk2.push_back(str2.Left(k));newchunk2.push_back(GetBstrByCount(str2,k));ChunkList.push_back(newchunk2);}}}}

调用过程


BOOL CWSdic::ComflexMaxMatch(DicHashmap& dichashmap,CString ori_str ,vector<CString>& wordvector,int Count){/*复杂最大匹配:chen 和liu 认为最大的匹配规则是三个单词:从句子头部开始,寻找所有三个分词chunks方案。从一个既定的字符开始,匹配出所有的三个词为一组的组合。使用中用四个消除歧义规则,进行过滤直到只存在一种结果或者四个规则使用完毕。1、最大匹配:有两种方案:简单最大匹配:选择长度最大的词复杂匹配:选择词组长度最大的那个词组2、最大平均词语长度:经过规则1后剩余的词组个数超过1,就选择平均词组长度最大的一个3、词语长度的最小变化率词语长度变化率可以由标准差反映,直接套用标准差公式.标准差=sqrt((x1-x)^2+(x2-x)^2+(x3-x))/34、largest sum of degree of mor...涉及统计词频,暂时不考虑*///BSTR bstr1 = function(ori_str);//int bstr1_len = SysStringLen(bstr1);BSTR bstr = ori_str.AllocSysString();//step 1:获取所有的chunksFindAllTrunks(bstr,dichashmap);if(ChunkList.size()>1){//step 2:找到所有chunks里面长度最大的若干个.GetMaxLenChunks();if(ChunkList.size()>1){//step 3:利用平均长度MaximumAvargeLength(ChunkList);if(ChunkList.size()>1){//step 4:利用方差MinimumVariance(ChunkList);if(ChunkList.size()>1){//step 5:利用词频}}}}return TRUE;}
自己构造的一个chunk类

class Chunk{public:Chunk();Chunk(const Chunk& chunk);~Chunk();public:vector<BSTR> m_chunk;int m_MaxLength;float m_MiniVariance;float m_maxavarlen ;public:void push_back(BSTR str);};




0 0