1. 序
词是句子组成的基本单元,不想英语句子已经分好词了,中文处理的第一步就是中文分词。
分词中面临的三大基本问题
- 分词规范
- 分词歧义
- 未登录词的识别
中文分词算法大概分为两大类
第一类:基于字符串匹配
即扫描字符串,如果发现字符串的子串和词相同,就算匹配。这类分词通常会加入一些启发式规则,比如“正向/反向最大匹配”, “长词优先” 等策略。
优点:速度块,都是O(n)时间复杂度,实现简单,效果尚可
缺点:就是对歧义和未登录词处理不好
案例:庖丁解牛分词器就是基于字符串匹配的分词。
- 歧义的例子很简单"长春市/长春/药店"、 "长春/市长/春药/店"
- 未登录词即词典中没有出现的词,当然也就处理不好
第二类:基于统计以及机器学习的分词方式
这类分词基于人工标注的词性和统计特征,对中文进行建模,即根据观测到的数据(标注好的语料)对模型参数进行估计,即训练。 在分词阶段再通过模型计算各种分词出现的概率,将概率最大的分词结果作为最终结果。常见的序列标注模型有HMM和CRF。
优点:很好处理歧义和未登录词问题,效果比基于字符串匹配效果好
缺点:需要大量的人工标注数据,较慢的分词速度
案例:Stanford Word Segmenter
2. 基于字符串匹配的中文分词(以前向最大匹配为例)
参考代码
f = file(Inputfile)
w = file(Outputfile, 'w')
for line in f:
line = line.strip().decode('utf-8')
senList = []
newsenList = []
tmpword = ''
for i in range(len(line)):
if line in StopWord:
senList.append(tmpword)
senList.append(line)
tmpword = ''
else:
tmpword += line
if i == len(line) - 1:
senList.append(tmpword)
#Pre
for key in senList:
if key in StopWord:
newsenList.append(key)
else:
tmplist = PreSenSeg(key, span)
for keyseg in tmplist:
newsenList.append(keyseg)
Prewriteline = ''
for key in newsenList:
Prewriteline = Prewriteline + key + ' '
w.write(Prewriteline.encode('utf-8') + '\n')
f.close()
w.close()
def PreSenSeg(sen, span):
post = span
if len(sen) < span:
post = len(sen)
cur = 0
revlist = []
while 1:
if cur >= len(sen):
break
s = re.search(u"^[0|1|2|3|4|5|6|7|8|9|\uff11|\uff12|\uff13|\uff14|\uff15|\uff16|\uff17|\uff18|\uff19|\uff10|\u4e00|\u4e8c|\u4e09|\u56db|\u4e94|\u516d|\u4e03|\u516b|\u4e5d|\u96f6|\u5341|\u767e|\u5343|\u4e07|\u4ebf|\u5146|\uff2f]+", sen[cur:])
if s:
if s.group() != '':
revlist.append(s.group())
cur = cur + len(s.group())
post = cur + span
if post > len(sen):
post = len(sen)
s = re.search(u"^[a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|\uff41|\uff42|\uff43|\uff44|\uff45|\uff46|\uff47|\uff48|\uff49|\uff47|\uff4b|\uff4c|\uff4d|\uff4e|\uff4f|\uff50|\uff51|\uff52|\uff53|\uff54|\uff55|\uff56|\uff57|\uff58|\uff59|\uff5a|\uff21|\uff22|\uff23|\uff24|\uff25|\uff26|\uff27|\uff28|\uff29|\uff2a|\uff2b|\uff2c|\uff2d|\uff2e|\uff2f|\uff30|\uff31|\uff32|\uff33|\uff35|\uff36|\uff37|\uff38|\uff39|\uff3a]+", sen[cur:])
if s:
if s.group() != '':
revlist.append(s.group())
cur = cur + len(s.group())
post = cur + span
if post > len(sen):
post = len(sen)
if (WordDic.has_key(sen[cur:post])) or (cur + 1 == post):
if sen[cur:post] != '':
revlist.append(sen[cur:post])
cur = post
post = post + span
if post > len(sen):
post = len(sen)
else:
post -= 1
return revlist
注意几点
- 首先根据标点切开分成小句子,标点绝对是分割的最佳标志。
- 句子中的数字(阿拉伯、汉字、阿拉伯+汉字。注意有十白千万亿)自动检测出来,不用再切割了。比如1998年=>1998 年
- 句子中的英文单词直接识别出来,不用分割了。比如:Happy New Year。
后向最大匹配与前向思路相同,只不过切分方向是从后往前。
3. 利用N-gram进行中文分词
语言模型是根据语言客观事实而进行的语言抽象数学建模,是一种对应关系。语言模型与语言客观事实之间的关系,如同数学上的抽象直线与具体直线之间的关系。
N-gram
语言模型在自然语言处理中占有重要地位,尤其是在基于统计模型的NLP任务中得到了广泛的应用,目前主要采用的是n元愈发模型(N-gram model),这种模型构建简单、直接,但同时也因为数据缺乏而必须采取平滑算法。
一个语言模型通常构建为字符串s的概率分布p(s),p(s)试图反映字符串s作为一个句子出现时?div style="border-bottom:1px solid #aaa;margin-bottom:25px">avalon1.3的新特性预览 - 司徒正美 阅读原文»
avalon1.2的性能优化风暴很快就告一段落,入职也快一个月了,许多乱七八糟的事也少了下来,估计未来一个月会有许多好东呈现给大家。
首先是一个性能检测工具。由于MVVM是将原本由人脑干的事,转到各种绑定上,因此性能是各MVVM框架一直关注的头等问题。这时性能检测工具就帮上大忙了。
内部编译器的改进。这分几部分,一是抽取变量,二是确定变量与某个VM的关系,最后是转换为求值函数。上个月基本上完后了后两部分。第一步自0.7后基本没动,最近几天内部悄悄做了一个新的parser,还在测试中,待稳定下来,则加入到新版本中。这将会大大提高扫描速度。
ms-widget的重构。将一个普通的元素节点变成一个功能齐备的控件是一个美妙的特性,这是所有MVVM框架都必需装备的杀手锏。但无法说得多么神奇,它内部的实现与之前的JQ对象没多区别,就是要传入要操作的元素节点以及一些配置项。由于之前过于追求自由,不对用户进行各种限制,结果用户有点不知所措,就算出了问题也不好定位。其次,之前一直缺乏对控件的生命周期管理,容易出现内存泄漏的危险。下面是对新ms-widget的一些规划,希望能脱骨换胎,浴火重生:
- 在控件没有初始化时,不对控件内部进行扫描,确保从外到内的扫描原则
- 为了完成第一原则,以及防止控件加载前其内部的{{}}被显示出来,决定将控件所在的元素临时移出DOM树,用一注释节点占位
- 原元素要保持原有的VM链及绑定属性, 方便以后还原(这个已经实现)
- 控件VM必须有一个$init方法,用于生成它的视图
- 控件VM必须有一个$remove方法,用于销毁它的视图(此方法与上面的方法可以多次调用,比如弹出层,允许不断初始化与销毁)
- 控件模块必须返回控件VM,用于自动销毁控件与控件VM(CG回收)
考虑将avalon.require.text移入核心库。显然随着UI库的扩充,这个模块越来越有用了。相对而言,avalon.mobile的触屏模块将变成一个插件,avalon.mobile或许会改名。次世代avalon.seber也在研发中,它使用了es6的新特性,以期获得更好的性能。目前avalon能在一个大页面上扛住1万个绑定,相对而言angular是2千个。
其实我本人是很讨厌"预览"什么吊人口胃的东西,不喜欢画大饼,但工作忙,很可能会忘掉了这些点子,就公开出来让大家监督我了。另一个,我在公司内部成立了一个小组是专门维护与升级avalon.ui,以期让它能与大阿狸的KISSY小组相抗衡。avalon相对KISSY有一个很大的优势,就是它是一个MVVM框架做底层。怎么描述比较avalon与传统的框架的区别呢?我们大致可以联想一下"自变量"与"因变量"这两个概念。传统框架,包括jQuery,它就是自变量太多,程序员在处理内部类的一些行为时,还要考到来自DOM的用户触发事件,总在几十个类与DOM上进行思维跳跃。avalon的理念是操作数据即操作DOM,这个数据就是VM,总是围绕它进行编程就行了,其他DOM操作,计算属性等等都是因变量,由框架自行处理。人的精力是有限的,因为每一辆汽车才只允许有一个转向盘,你见过有五六个转向盘的车子吗?!目前主流DOM框架就是这吊样,司机在五六个转向盘挥舞双手,因此才有这么多事故(BUG)的发生!最后还是为自己拉些选票吧,希望大家都来试用avalon,在GITHUB上关注(star)一下。
本文链接:http://www.cnblogs.com/rubylouvre/p/3632226.html,转载请注明。
没有评论:
发表评论