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 基础学习教程
Feb 08 Python
python端口扫描系统实现方法
Nov 19 Python
python 遍历字符串(含汉字)实例详解
Apr 04 Python
Django中url的反向查询的方法
Mar 14 Python
利用python的socket发送http(s)请求方法示例
May 07 Python
Python 使用PIL numpy 实现拼接图片的示例
May 08 Python
Python3.5实现的三级菜单功能示例
Mar 25 Python
详解用Python实现自动化监控远程服务器
May 18 Python
Python 共享变量加锁、释放详解
Aug 28 Python
Python转换字典成为对象,可以用&quot;.&quot;方式访问对象属性实例
May 11 Python
python线程池如何使用
May 28 Python
Pythonic版二分查找实现过程原理解析
Aug 11 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
谏山创故乡大分县日田市水坝将设立《进击的巨人》立艾伦、三笠以及阿尔敏的铜像!
2020/03/06 日漫
PHP取整函数:ceil,floor,round,intval的区别详细解析
2013/08/31 PHP
PHP URL路由类实例
2013/11/12 PHP
PHP中使用数组指针函数操作数组示例
2014/11/19 PHP
ThinkPHP实现支付宝接口功能实例
2014/12/02 PHP
php遍历类中包含的所有元素的方法
2015/05/12 PHP
IE8 浏览器Cookie的处理
2009/01/31 Javascript
jquery.validate使用攻略 第五步 正则验证
2010/07/01 Javascript
25个好玩的JavaScript小游戏分享
2011/04/22 Javascript
javascript获取元素偏移量的方法有哪些
2014/06/24 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
2014/10/20 Javascript
JavaScript中神奇的call()方法
2015/03/12 Javascript
jquery实现select选择框内容左右移动代码分享
2015/11/21 Javascript
JavaScript的Backbone.js框架环境搭建及Hellow world示例
2016/05/07 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
2016/09/04 Javascript
JS继承之借用构造函数继承和组合继承
2016/09/07 Javascript
微信小程序 教程之wxapp 视图容器 view
2016/10/19 Javascript
jQuery Json数据格式排版高亮插件json-viewer.js使用方法详解
2017/06/12 jQuery
vue数据传递--我有特殊的实现技巧
2018/03/20 Javascript
使用layui 渲染table数据表格的实例代码
2018/08/19 Javascript
利用weixin-java-miniapp生成小程序码并直接返回图片文件流的方法
2019/03/29 Javascript
[00:28]DOTA2北京网鱼队选拔赛
2015/04/08 DOTA
Python利用ansible分发处理任务
2015/08/04 Python
python中map()函数的使用方法示例
2017/09/29 Python
对python中的xlsxwriter库简单分析
2018/05/04 Python
和孩子一起学习python之变量命名规则
2018/05/27 Python
python多进程提取处理大量文本的关键词方法
2018/06/05 Python
python实现文本界面网络聊天室
2018/12/12 Python
python默认参数调用方法解析
2020/02/09 Python
详解python算法常用技巧与内置库
2020/10/17 Python
大学生求职中的自我评价
2013/10/01 职场文书
应届生求职推荐信
2013/10/28 职场文书
学生实习介绍信
2014/01/15 职场文书
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
文员岗位职责
2015/02/04 职场文书
2015年语文教师工作总结
2015/05/25 职场文书