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群发邮件实例代码
Jan 03 Python
深入解析Python中的集合类型操作符
Aug 19 Python
Python3使用requests发闪存的方法
May 11 Python
Python实现将数据库一键导出为Excel表格的实例
Dec 30 Python
批量获取及验证HTTP代理的Python脚本
Apr 23 Python
python tkinter实现界面切换的示例代码
Jun 14 Python
python实现一行输入多个值和一行输出多个值的例子
Jul 16 Python
python字典排序的方法
Oct 12 Python
python 检查数据中是否有缺失值,删除缺失值的方式
Dec 02 Python
Django Session和Cookie分别实现记住用户登录状态操作
Jul 02 Python
用python爬虫批量下载pdf的实现
Dec 01 Python
pandas中DataFrame数据合并连接(merge、join、concat)
May 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
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
Joomla使用Apache重写模式的方法
2016/05/04 PHP
浅谈php中fopen不能创建中文文件名文件的问题
2017/02/06 PHP
PHP中str_split()函数的用法讲解
2019/04/11 PHP
extJs 文本框后面加上说明文字+下拉列表选中值后触发事件
2009/11/27 Javascript
IE的有条件注释判定IE版本详解(附实例代码)
2012/01/04 Javascript
jQuery中ajax的使用与缓存问题的解决方法
2013/12/19 Javascript
JavaScript中的关联数组问题
2015/03/04 Javascript
js实现表单及时验证功能 用户信息立即验证
2016/09/13 Javascript
判断数组的最佳方法(推荐)
2016/10/11 Javascript
BackBone及其实例探究_动力节点Java学院整理
2017/07/14 Javascript
Webpack 之 babel-loader文件预处理器详解
2018/03/23 Javascript
Bootstrap table表格初始化表格数据的方法
2018/07/25 Javascript
浅谈微信JS-SDK 微信分享接口开发(介绍版)
2018/08/15 Javascript
详解用vue2.x版本+adminLTE开源框架搭建后台应用模版
2019/03/15 Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
2019/05/10 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
一个检测OpenSSL心脏出血漏洞的Python脚本分享
2014/04/10 Python
python提取页面内url列表的方法
2015/05/25 Python
Python reduce()函数的用法小结
2017/11/15 Python
pytorch神经网络之卷积层与全连接层参数的设置方法
2019/08/18 Python
详解python播放音频的三种方法
2019/09/23 Python
python二进制读写及特殊码同步实现详解
2019/10/11 Python
Grow Gorgeous美国官网:只要八天,体验唤醒毛囊后新生的茂密秀发
2018/06/04 全球购物
马来西亚综合购物网站:Lazada马来西亚
2018/06/05 全球购物
奢华时尚的独特视角:La Garçonne
2018/06/07 全球购物
建筑公司文秘岗位职责
2013/11/29 职场文书
高二美术教学反思
2014/01/14 职场文书
家长对小学生的评语
2014/01/28 职场文书
房地产开盘策划方案
2014/02/10 职场文书
2015大学生实训报告
2014/11/05 职场文书
工作失误检讨书范文
2015/01/26 职场文书
职工宿舍管理制度
2015/08/05 职场文书
【D4DJ】美少女DJ企划 动画将于明年冬季开播第2季
2022/04/11 日漫
Python 的演示平台支持 WSGI 接口的应用
2022/04/20 Python