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重新引入被覆盖的自带function
Jul 16 Python
跟老齐学Python之玩转字符串(1)
Sep 14 Python
Python定时执行之Timer用法示例
May 27 Python
Python读取Excel的方法实例分析
Jul 11 Python
Python使用dis模块把Python反编译为字节码的用法详解
Jun 14 Python
python 将md5转为16字节的方法
May 29 Python
如何利用python制作时间戳转换工具详解
Sep 12 Python
win10系统下Anaconda3安装配置方法图文教程
Sep 19 Python
解决python xx.py文件点击完之后一闪而过的问题
Jun 24 Python
基于Django静态资源部署404的解决方法
Jul 28 Python
Django使用消息提示简单的弹出个对话框实例
Nov 15 Python
python绘制趋势图的示例
Sep 17 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设计模式之单例、多例设计模式的应用分析
2013/06/30 PHP
PHP的cURL库简介及使用示例
2015/02/06 PHP
thinkphp5框架实现的自定义扩展类操作示例
2019/05/16 PHP
Avengerls vs Newbee BO3 第二场2.18
2021/03/10 DOTA
jQuery下的几个你可能没用过的功能
2010/08/29 Javascript
javascript 45种缓动效果 非常酷
2011/06/28 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
js中回调函数的学习笔记
2014/07/31 Javascript
js实现按钮控制图片360度翻转特效的方法
2015/02/17 Javascript
JS中处理时间之setUTCMinutes()方法的使用
2015/06/12 Javascript
学习javascript面向对象 理解javascript原型和原型链
2016/01/04 Javascript
jQuery实现内容定时切换效果完整实例
2016/04/06 Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
2016/10/04 Javascript
JavaScript注入漏洞的原理及防范(详解)
2016/12/04 Javascript
通过jsonp获取json数据实现AJAX跨域请求
2017/01/22 Javascript
nodejs模块nodemailer基本使用-邮件发送示例(支持附件)
2017/03/28 NodeJs
js使用generator函数同步执行ajax任务
2017/09/05 Javascript
Vue-router的使用和出现空白页,路由对象属性详解
2018/09/03 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
python client使用http post 到server端的代码
2013/02/10 Python
Python查找相似单词的方法
2015/03/05 Python
python检查字符串是否是正确ISBN的方法
2015/07/11 Python
python 使用tkinter+you-get实现视频下载器
2020/11/17 Python
python 合并多个excel中同名的sheet
2021/01/22 Python
python 装饰器重要在哪
2021/02/14 Python
pyx文件 生成pyd 文件用于 cython调用的实现
2021/03/04 Python
《都江堰》教学反思
2014/02/07 职场文书
学术诚信承诺书
2014/05/26 职场文书
北京离婚协议书范文2014
2014/09/29 职场文书
2014年便民服务中心工作总结
2014/12/20 职场文书
个人学习总结范文
2015/02/15 职场文书
2015学校图书管理员工作总结
2015/05/11 职场文书
劳动争议仲裁代理词
2015/05/25 职场文书
nginx前后端同域名配置的方法实现
2021/03/31 Servers
mysql配置SSL证书登录的实现
2021/09/04 MySQL