python中文分词教程之前向最大正向匹配算法详解


Posted in Python onNovember 02, 2017

前言

大家都知道,英文的分词由于单词间是以空格进行分隔的,所以分词要相对的容易些,而中文就不同了,中文中一个句子的分隔就是以字为单位的了,而所谓的正向最大匹配和逆向最大匹配便是一种分词匹配的方法,这里以词典匹配说明。

最大匹配算法是自然语言处理中的中文匹配算法中最基础的算法,分为正向和逆向,原理都是一样的。

正向最大匹配算法,故名思意,从左向右扫描寻找词的最大匹配。

首先我们可以规定一个词的最大长度,每次扫描的时候寻找当前开始的这个长度的词来和字典中的词匹配,如果没有找到,就缩短长度继续寻找,直到找到或者成为单字。

下面话不多说了,来一起看看详细的介绍吧。

实例:

S1="计算语言学课程是三个课时" ,设定最大词长MaxLen = 5 ,S2= " "

字典中含有三个词:[计算语言学]、[课程]、[课时]

    (1)S2="";S1不为空,从S1左边取出候选子串W="计算语言学";

    (2)查词表,“计算语言学”在词表中,将W加入到S2中,S2=“计算语言学/ ”, 并将W从S1中去掉,此时S1="课程是三个课时";

    (3)S1不为空,于是从S1左边取出候选子串W="课程是三个";

    (4)查词表,W不在词表中,将W最右边一个字去掉,得到W="课程是三";

    (5)查词表,W不在词表中,将W最右边一个字去掉,得到W="课程是";

    (6)查词表,W不在词表中,将W最右边一个字去掉,得到W="课程"

    (7)查词表,W在词表中,将W加入到S2中,S2=“计算语言学/ 课程/ ”,并 将W从S1中去掉,此时S1="是三个课时";

    (8)S1不为空,于是从S1左边取出候选子串W="是三个课时";

    (9)查词表,W不在词表中,将W最右边一个字去掉,得到W="是三个课";

    (10)查词表,W不在词表中,将W最右边一个字去掉,得到W="是三个";

    (11)查词表,W不在词表中,将W最右边一个字去掉,得到W="是三"

    (12)查词表,W不在词表中,将W最右边一个字去掉,得到W=“是”,这时 W是单字,将W加入到S2中,S2=“计算语言学/ 课程/ 是/ ”,并将 W从S1中去掉,此时S1="三个课时";

    (13)S1不为空,从S1左边取出候选子串W="三个课时";

    (14)查词表,W不在词表中,将W最右边一个字去掉,得到W="三个课";

    (15)查词表,W不在词表中,将W最右边一个字去掉,得到W="三个";

    (16)查词表,W不在词表中,将W最右边一个字去掉,得到W=“三”,这时 W是单字,将W加入到S2中,S2=“计算语言学/ 课程/ 是/ 三/ ”,并 将W从S1中去掉,此时S1="个课时";

    (17)S1不为空,从S1左边取出候选子串W="个课时";

    (18)查词表,W不在词表中,将W最右边一个字去掉,得到W="个课";

    (19)查词表,W不在词表中,将W最右边一个字去掉,得到W=“个”, 这时W是单字,将W加入到S2中,S2=“计算语言学/ 课程/ 是/ 三/ 个/ ",并将W从S1中去掉,此时S1="课时";

    (20)S1不为空,从S1左边取出候选子串W="课时";

    (21)查词表,W在词表中,将W加入到S2中,S2=“计算语言学/ 课程/ 是/ 三/ 个/ 课时/ ",并将W从S1中去掉,此时S1=""。

    (22)S1为空,输出S2作为分词结果,分词过程结束。

而至于为什么选择python这个语言呢?大概是因为我周围人用得少吧,我就想尝试突破,不过我也不讳言,我的C/C++,java等等高级语言用的也不多,虽说编程语言这个东西,基本上只要熟悉一个,其他的都好学,不过我在python上尝到了甜头,索性就用这个语言了。

中文分词算法的Python实现:

脚本接受两个参数,一个是输入文件的路径,另一个是词典的路径。

它的运行方法如下:

python max-match.py <data> <dict>
#!/usr/bin/env python
import cPickle as pickle
import sys

# 词语最大长度为5
window_size=5

def max_match_segment(line, dic):
 # write your code here
 chars = line.decode("utf8")
 words = []
 idx = 0
 # 判断索引是否超过chars的长度
 while idx < len(chars):
  matched = False
  for i in xrange(window_size, 0, -1):
   cand=chars[idx:idx+i].encode("utf8")
   if cand in dic:
    words.append(cand)
    matched = True
    break
  # 判断for中是否匹配到数据
  if not matched:
   i = 1
   words.append(chars[idx].encode("utf8"))
  idx += i

 return words

if __name__=="__main__":

 try:
  fpi=open(sys.argv[1], "r")
 except:
  print >> sys.stderr, "failed to open file"
  sys.exit(1)

 try:
  dic = pickle.load(open(sys.argv[2], "r"))
 except:
  print >> sys.stderr, "failed to load dict %s" % sys.argv[2]
  sys.exit(1)
 try:
  fpo = open("out.txt","w")
 except:
  print >> sys.stderr, "failed to load out.txt"
  sys.exit(1)
 for line in fpi:
  fpo.write("\t".join( max_match_segment(line.strip(), dic) ))

当然,这只是最基础的,还可以有很多高级的优化,比如说改成Trie树版本的,控制最大词长度的等等。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python操作CouchDB的方法
Oct 08 Python
python去除文件中空格、Tab及回车的方法
Apr 12 Python
python中reduce()函数的使用方法示例
Sep 29 Python
详谈Numpy中数组重塑、合并与拆分方法
Apr 17 Python
Python面向对象程序设计多继承和多态用法示例
Apr 08 Python
解决Python图形界面中设置尺寸的问题
Mar 05 Python
Python基于Twilio及腾讯云实现国际国内短信接口
Jun 18 Python
python删除文件、清空目录的实现方法
Sep 23 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
Nov 24 Python
Python中全局变量和局部变量的理解与区别
Feb 07 Python
python基于opencv批量生成验证码的示例
Apr 28 Python
写好Python代码的几条重要技巧
May 21 Python
详解Python里使用正则表达式的ASCII模式
Nov 02 #Python
python安装numpy&amp;安装matplotlib&amp; scipy的教程
Nov 02 #Python
python中实现精确的浮点数运算详解
Nov 02 #Python
利用Python-iGraph如何绘制贴吧/微博的好友关系图详解
Nov 02 #Python
python3.0 模拟用户登录,三次错误锁定的实例
Nov 02 #Python
Python安装Numpy和matplotlib的方法(推荐)
Nov 02 #Python
Python 多进程并发操作中进程池Pool的实例
Nov 01 #Python
You might like
Ajax+PHP边学边练 之五 图片处理
2009/12/03 PHP
通过php删除xml文档内容的方法
2015/01/23 PHP
PHP遍历数组的方法汇总
2015/04/30 PHP
PHP flush 函数使用注意事项
2016/08/26 PHP
PHP编程文件处理类SplFileObject和SplFileInfo用法实例分析
2017/07/22 PHP
js批量设置样式的三种方法不推荐使用with
2013/02/25 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
JQuery select(下拉框)操作方法汇总
2015/04/15 Javascript
使用HTML5+Boostrap打造简单的音乐播放器
2016/08/05 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
vue模板语法-插值详解
2017/03/06 Javascript
js实现五星评价功能
2017/03/08 Javascript
关于页面刷新vuex数据消失问题解决方案
2017/07/03 Javascript
详解JavaScript基础知识(JSON、Function对象、原型、引用类型)
2018/01/16 Javascript
Angular-UI Bootstrap组件实现警报功能
2018/07/16 Javascript
koa socket即时通讯的示例代码
2018/09/07 Javascript
Vue实现的父组件向子组件传值功能示例
2019/01/19 Javascript
浅谈React Native 传参的几种方式(小结)
2019/05/21 Javascript
python数组复制拷贝的实现方法
2015/06/09 Python
Python根据区号生成手机号码的方法
2015/07/08 Python
Django 中间键和上下文处理器的使用
2019/03/17 Python
24式加速你的Python(小结)
2019/06/13 Python
pyqt5 实现 下拉菜单 + 打开文件的示例代码
2019/06/20 Python
python selenium 执行完毕关闭chromedriver进程示例
2019/11/15 Python
python中matplotlib实现随鼠标滑动自动标注代码
2020/04/23 Python
Python类及获取对象属性方法解析
2020/06/15 Python
纽约市的奢华内衣目的地:Anya Lust
2019/08/02 全球购物
枚举与#define宏的区别
2014/04/30 面试题
物业管理大学生个人的自我评价
2013/10/10 职场文书
cf战队收人广告词
2014/03/14 职场文书
跑操口号
2014/06/12 职场文书
党员教师个人对照检查材料(群众路线)
2014/09/26 职场文书
班级光棍节联谊会策划书
2014/10/10 职场文书
群众路线教育实践活动总结
2014/10/30 职场文书
《雪地里的小画家》教学反思
2016/02/16 职场文书
分享7个 Python 实战项目练习
2022/03/03 Python