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中endswith()函数的基本使用
Apr 07 Python
实例探究Python以并发方式编写高性能端口扫描器的方法
Jun 14 Python
python中pandas.DataFrame对行与列求和及添加新行与列示例
Mar 12 Python
Python反转序列的方法实例分析
Mar 21 Python
Numpy中矩阵matrix读取一列的方法及数组和矩阵的相互转换实例
Jul 02 Python
python如何解析配置文件并应用到项目中
Jun 27 Python
jenkins配置python脚本定时任务过程图解
Oct 29 Python
python机器学习实现决策树
Nov 11 Python
Python列表切片常用操作实例解析
Mar 10 Python
Python3 Tensorlfow:增加或者减小矩阵维度的实现
May 22 Python
Python压缩模块zipfile实现原理及用法解析
Aug 14 Python
Python3 + Appium + 安卓模拟器实现APP自动化测试并生成测试报告
Jan 27 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数组的一些常见操作汇总
2011/07/17 PHP
php强大的时间转换函数strtotime
2016/02/18 PHP
PHP页面间传递值和保持值的方法
2016/08/24 PHP
php 读取文件夹下所有图片、文件的实例
2018/10/17 PHP
js下获取div中的数据的原理分析
2010/04/07 Javascript
JS判断页面加载状态以及添加遮罩和缓冲动画的代码
2012/10/11 Javascript
jQuery 和 CSS 的文本特效插件集锦
2014/12/12 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
js编写一个简单的产品放大效果代码
2016/06/27 Javascript
vue2.0 keep-alive最佳实践
2017/07/06 Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
2017/11/22 Javascript
nodejs(officegen)+vue(axios)在客户端导出word文档的方法
2018/07/31 NodeJs
js实现动态增加文件域表单功能
2018/10/22 Javascript
django js 实现表格动态标序号的实例代码
2019/07/12 Javascript
vue遍历对象中的数组取值示例
2019/11/07 Javascript
JavaScript实现矩形块大小任意缩放
2020/08/25 Javascript
使用Mock.js生成前端测试数据
2020/12/13 Javascript
linux系统使用python监测网络接口获取网络的输入输出
2014/01/15 Python
Python中if __name__ == &quot;__main__&quot;详细解释
2014/10/21 Python
Python使用面向对象方式创建线程实现12306售票系统
2015/12/24 Python
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
Python正则表达式和元字符详解
2018/11/29 Python
在python中获取div的文本内容并和想定结果进行对比详解
2019/01/02 Python
Python读取实时数据流示例
2019/12/02 Python
使用python绘制cdf的多种实现方法
2020/02/25 Python
Python3爬虫RedisDump的安装步骤
2021/02/20 Python
添柏岚英国官方网站:Timberland英国
2019/11/28 全球购物
大学生毕业求职找工作的自我评价
2013/09/29 职场文书
化验室技术员岗位职责
2013/12/24 职场文书
2014年大班元旦活动方案
2014/02/26 职场文书
关于环保的建议书
2014/05/12 职场文书
2014年学生会个人工作总结
2014/11/07 职场文书
2015年收银员个人工作总结
2015/04/01 职场文书
酒店财务经理岗位职责
2015/04/08 职场文书
2015年小学总务工作总结
2015/07/21 职场文书
如何利用opencv判断两张图片是否相同详解
2021/07/07 Python