python中文分词教程之前向最大正向匹配算法详解

作者:Pala 时间:2023-07-23 12:51:22 

前言

大家都知道,英文的分词由于单词间是以空格进行分隔的,所以分词要相对的容易些,而中文就不同了,中文中一个句子的分隔就是以字为单位的了,而所谓的正向最大匹配和逆向最大匹配便是一种分词匹配的方法,这里以词典匹配说明。

最大匹配算法是自然语言处理中的中文匹配算法中最基础的算法,分为正向和逆向,原理都是一样的。

正向最大匹配算法,故名思意,从左向右扫描寻找词的最大匹配。

首先我们可以规定一个词的最大长度,每次扫描的时候寻找当前开始的这个长度的词来和字典中的词匹配,如果没有找到,就缩短长度继续寻找,直到找到或者成为单字。

下面话不多说了,来一起看看详细的介绍吧。

实例:

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树版本的,控制最大词长度的等等。

来源:http://www.chenxm.cc/post/450.html

标签:python,中文分词,最大匹配算法
0
投稿

猜你喜欢

  • ASP 精华源码收集(五年总结)第1/20页

    2011-04-07 11:15:00
  • Python爬虫信息输入及页面的切换方法

    2023-08-02 17:33:33
  • SqlServer 2005 简单的全文检索

    2024-01-18 05:00:31
  • Access数据库下如何使用通用对话框的问题

    2008-11-28 16:37:00
  • js实现一个简易计算器

    2024-04-25 13:13:38
  • Python过滤列表用法实例分析

    2021-03-21 03:47:49
  • Mybatis实现分包定义数据库的原理与过程

    2024-01-23 12:33:55
  • Go语言正则表达式示例

    2023-04-13 19:41:34
  • vue自定义过滤器创建和使用方法详解

    2024-05-09 15:17:06
  • 如何从数据库断开recordset,提高运行速度?

    2009-11-15 20:01:00
  • PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法

    2023-11-14 16:13:53
  • 用sql实现18位身份证校验代码分享 身份证校验位计算

    2024-01-13 13:37:11
  • windows11安装SQL server数据库报错等待数据库引擎恢复句柄失败解决办法

    2024-01-16 07:18:52
  • nodejs对项目下所有空文件夹创建gitkeep的方法

    2024-05-08 09:37:40
  • Windows10下安装解压版MySQL教程图文详解

    2024-01-12 20:40:57
  • python开发中range()函数用法实例分析

    2021-05-08 12:53:26
  • pandas计算最大连续间隔的方法

    2022-05-23 12:05:21
  • python 提取html文本的方法

    2021-05-27 03:43:46
  • javaScript合并对象的几个常见方式

    2024-04-16 08:58:26
  • Webpack基础教程之名词解释

    2022-12-17 19:04:30
  • asp之家 网络编程 m.aspxhome.com