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调用Moxa PCOMM Lite通过串口Ymodem协议实现发送文件
Aug 15 Python
Python的Bottle框架中实现最基本的get和post的方法的教程
Apr 30 Python
Python函数式编程指南(二):从函数开始
Jun 24 Python
Python实现利用最大公约数求三个正整数的最小公倍数示例
Sep 30 Python
python生成随机图形验证码详解
Nov 08 Python
详解Python异常处理中的Finally else的功能
Dec 29 Python
Python实现动态图解析、合成与倒放
Jan 18 Python
python递归实现快速排序
Aug 18 Python
Tensorflow使用支持向量机拟合线性回归
Sep 07 Python
Python 使用 PyMysql、DBUtils 创建连接池提升性能
Aug 14 Python
OpenCV-Python使用cv2实现傅里叶变换
Jun 09 Python
如何Python使用re模块实现okenizer
Apr 30 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
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
ThinkPHP里用U方法调用js文件实例
2015/06/18 PHP
php微信公众号开发之秒杀
2018/10/20 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
基于jquery的放大镜效果
2012/05/30 Javascript
获取客户端电脑日期时间js代码(jquery)
2012/09/12 Javascript
从js向Action传中文参数出现乱码问题的解决方法
2013/12/29 Javascript
js模仿php中strtotime()与date()函数实现方法
2015/08/11 Javascript
javascript中alert()与console.log()的区别
2015/08/26 Javascript
基于Jquery代码实现手风琴菜单
2015/11/19 Javascript
基于Node.js的强大爬虫 能直接发布抓取的文章哦
2016/01/10 Javascript
JavaScript实现Base64编码转换
2016/04/23 Javascript
原生JS下拉加载插件分享
2016/12/26 Javascript
nodejs入门教程五:连接数据库的方法分析
2017/04/24 NodeJs
JS控制GIF图片的停止与显示
2019/10/24 Javascript
JavaScript实现点击切换验证码及校验
2021/01/10 Javascript
python提取字典key列表的方法
2015/07/11 Python
python消除序列的重复值并保持顺序不变的实例
2018/11/08 Python
深入了解和应用Python 装饰器 @decorator
2019/04/02 Python
对python中不同模块(函数、类、变量)的调用详解
2019/07/16 Python
python实现电子词典
2020/03/03 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
详解selenium + chromedriver 被反爬的解决方法
2020/10/28 Python
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
锐步英国官网:Reebok英国
2019/11/29 全球购物
编写类String的构造函数、析构函数和赋值函数
2012/05/29 面试题
中式餐厅创业计划书范文
2014/01/23 职场文书
人力资源求职信
2014/05/25 职场文书
社区服务活动小结
2014/07/08 职场文书
担保书范文
2015/01/20 职场文书
卫生保健工作总结2015
2015/05/18 职场文书
党小组考察意见
2015/06/02 职场文书
开学季:喜迎新生,迎新标语少不了
2019/11/07 职场文书
pytorch 如何使用float64训练
2021/05/24 Python
Java 异步任务计算FutureTask
2022/04/28 Java/Android
pd.DataFrame中的几种索引变换的实现
2022/06/16 Python