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实现建立SSH连接的方法
Jun 03 Python
Python的地形三维可视化Matplotlib和gdal使用实例
Dec 09 Python
python编程使用selenium模拟登陆淘宝实例代码
Jan 25 Python
python pandas时序处理相关功能详解
Jul 03 Python
简单了解python代码优化小技巧
Jul 08 Python
利用python计算时间差(返回天数)
Sep 07 Python
基于Python实现2种反转链表方法代码实例
Jul 06 Python
Python3实现英文字母转换哥特式字体实例代码
Sep 01 Python
用python实现监控视频人数统计
May 21 Python
Python一些基本的图像操作和处理总结
Jun 23 Python
Django框架之路由用法
Jun 10 Python
Python使用pandas导入csv文件内容的示例代码
Dec 24 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提取视频网站页面中的FLASH地址的代码
2010/04/17 PHP
php将字符串全部转换成大写或者小写的方法
2015/03/17 PHP
php使用Jpgraph绘制3D饼状图的方法
2015/06/10 PHP
PHP之浮点数计算比较以及取整数不准确的解决办法
2015/07/29 PHP
求帮忙修改个php curl模拟post请求内容后并下载文件的解决思路
2015/09/20 PHP
PHP语法小结之基础和变量
2015/11/22 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
2017/11/17 PHP
通过ifame指向的页面高度调整iframe的高度
2006/10/05 Javascript
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
Js切换功能的简单方法
2010/11/23 Javascript
JSONP 跨域共享信息
2012/08/16 Javascript
javascript实现文字图片上下滚动的具体实例
2013/06/28 Javascript
JS自动适应的图片弹窗实例
2013/06/29 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
js的image onload事件使用遇到的问题
2014/07/15 Javascript
JS判断客服QQ号在线还是离线状态的方法
2015/01/13 Javascript
Jquery效果大全之制作电脑健康体检得分特效附源码下载
2015/11/02 Javascript
Bootstrap每天必学之表格
2015/11/23 Javascript
基于JavaScript实现瀑布流效果
2017/03/29 Javascript
详解Angularjs 自定义指令中的数据绑定
2018/07/19 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
2018/09/20 Javascript
Vue实现商品详情页的评价列表功能
2019/09/04 Javascript
Layui表格行工具事件与数据回填方法
2019/09/13 Javascript
vue 获取及修改store.js里的公共变量实例
2019/11/06 Javascript
详解python函数的闭包问题(内部函数与外部函数详述)
2019/05/17 Python
python中bs4.BeautifulSoup的基本用法
2019/07/27 Python
详解python uiautomator2 watcher的使用方法
2019/09/09 Python
详解KMP算法以及python如何实现
2020/09/18 Python
canvas压缩图片以及卡片制作的方法示例
2018/12/04 HTML / CSS
外贸业务员求职自荐信分享
2013/09/21 职场文书
酒店服务实习自我鉴定
2013/09/22 职场文书
班主任经验交流会主持词
2014/04/01 职场文书
数字化校园建设方案
2014/05/03 职场文书
新书发布会策划方案
2014/06/09 职场文书
现场施工员岗位职责
2015/04/11 职场文书
POST提交数据常见的四种方式
2022/01/18 HTML / CSS