中文分词--最大正向与逆向匹配算法python实现
最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描)。例如:词典中最长词为“中华人民共和国”共7个汉字,则最大匹配起始字数为7个汉字。然后逐字递减,在对应的词典中进行查找。
下面以“我们在野生动物园玩”为例详细说明一下正向与逆向最大匹配方法:
- 1、正向最大匹配法:
正向即从前往后取词,从7->1,每次减一个字,直到词典命中或剩下1个单字。
第1次:“我们在野生动物”,扫描7字词典,无
第2次:“我们在野生动”,扫描6字词典,无
。。。。
第6次:“我们”,扫描2字词典,有
扫描中止,输出第1个词为“我们”,去除第1个词后开始第2轮扫描,即:
第2轮扫描:
第1次:“在野生动物园玩”,扫描7字词典,无
第2次:“在野生动物园”,扫描6字词典,无
。。。。
第6次:“在野”,扫描2字词典,有
扫描中止,输出第2个词为“在野”,去除第2个词后开始第3轮扫描,即:
第3轮扫描:
第1次:“生动物园玩”,扫描5字词典,无
第2次:“生动物园”,扫描4字词典,无
第3次:“生动物”,扫描3字词典,无
第4次:“生动”,扫描2字词典,有
扫描中止,输出第3个词为“生动”,第4轮扫描,即:
第4轮扫描:
第1次:“物园玩”,扫描3字词典,无
第2次:“物园”,扫描2字词典,无
第3次:“物”,扫描1字词典,无
扫描中止,输出第4个词为“物”,非字典词数加1,开始第5轮扫描,即:
第5轮扫描:
第1次:“园玩”,扫描2字词典,无
第2次:“园”,扫描1字词典,有
扫描中止,输出第5个词为“园”,单字字典词数加1,开始第6轮扫描,即:
第6轮扫描:
第1次:“玩”,扫描1字字典词,有
扫描中止,输出第6个词为“玩”,单字字典词数加1,整体扫描结束。
正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”
- 2、正向python代码实现
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 19 08:57:56 2018 @author: Lenovo
""" test_file = 'train/train.txt'#训练语料
test_file2 = 'test/test.txt'#测试语料
test_file3 = 'test_sc/test_sc_zhengxiang.txt'#生成结果 def get_dic(test_file): #读取文本返回列表
with open(test_file,'r',encoding='utf-8',) as f:
try:
file_content = f.read().split()
finally:
f.close()
chars = list(set(file_content))
return chars dic = get_dic(test_file)
def readfile(test_file2):
max_length = 5 h = open(test_file3,'w',encoding='utf-8',)
with open(test_file2,'r',encoding='utf-8',) as f:
lines = f.readlines() for line in lines:#分别对每行进行正向最大匹配处理
max_length = 5
my_list = []
len_hang = len(line)
while len_hang>0 :
tryWord = line[0:max_length]
while tryWord not in dic:
if len(tryWord)==1:
break
tryWord=tryWord[0:len(tryWord)-1]
my_list.append(tryWord)
line = line[len(tryWord):]
len_hang = len(line) for t in my_list:#将分词结果写入生成文件
if t == '\n' :
h.write('\n')
else:
h.write(t + " ") h.close() readfile(test_file2)
- 3、逆向最大匹配算法
逆向即从后往前取词,其他逻辑和正向相同。即:
第1轮扫描:“在野生动物园玩”
第1次:“在野生动物园玩”,扫描7字词典,无
第2次:“野生动物园玩”,扫描6字词典,无
。。。。
第7次:“玩”,扫描1字词典,有
扫描中止,输出“玩”,单字字典词加1,开始第2轮扫描
第2轮扫描:“们在野生动物园”
第1次:“们在野生动物园”,扫描7字词典,无
第2次:“在野生动物园”,扫描6字词典,无
第3次:“野生动物园”,扫描5字词典,有
扫描中止,输出“野生动物园”,开始第3轮扫描
第3轮扫描:“我们在”
第1次:“我们在”,扫描3字词典,无
第2次:“们在”,扫描2字词典,无
第3次:“在”,扫描1字词典,有
扫描中止,输出“在”,单字字典词加1,开始第4轮扫描
第4轮扫描:“我们”
第1次:“我们”,扫描2字词典,有
扫描中止,输出“我们”,整体扫描结束。
逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩
- 4、逆向python代码实现
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 19 08:57:56 2018 @author: Lenovo
"""
test_file = 'train/train.txt'
test_file2 = 'test/test.txt'
test_file3 = 'test_sc/test_sc.txt' def get_dic(test_file):
with open(test_file,'r',encoding='utf-8',) as f:
try:
file_content = f.read().split()
finally:
f.close()
chars = list(set(file_content))
return chars dic = get_dic(test_file)
def readfile(test_file2):
max_length = 5 h = open(test_file3,'w',encoding='utf-8',)
with open(test_file2,'r',encoding='utf-8',) as f:
lines = f.readlines() for line in lines:
my_stack = []
len_hang = len(line)
while len_hang>0 :
tryWord = line[-max_length:]
while tryWord not in dic:
if len(tryWord)==1:
break
tryWord=tryWord[1:]
my_stack.append(tryWord)
line = line[0:len(line)-len(tryWord)]
len_hang = len(line) while len(my_stack):
t = my_stack.pop()
if t == '\n' :
h.write('\n')
else:
h.write(t + " ") h.close() readfile(test_file2)
- 5、正确率,召回率和F值
正确率、召回率和F值是目标的重要评价指标。
正确率 = 正确识别的个体总数 / 识别出的个体总数
召回率 = 正确识别的个体总数 / 测试集中存在的个体总数
F值 = 正确率 * 召回率 * 2 / (正确率 + 召回率)
编写评价程序:首先对生成的文本和gold文本每行通过切分形成词汇表,然后对两个词汇表从第一个词开始比较:
如果当前词汇相同,表明结果正确,且之前的词汇拼成的字符串长度相等;
如果当前词汇不同,结果错误,不断取词汇拼字符串直到两个字符串长度相同;
依次对每行进行处理,计算出f值。
评价程序实现如下:
# -*- coding: utf-8 -*-
"""
Created on Fri Jul 27 15:32:46 2018 @author: Lenovo
""" test_file = 'test_sc/test_sc_zhengxiang.txt'
test_file2 = 'gold/test_gold.txt'
def get_word(fname): f = open(fname,'r',encoding='utf-8',)
lines = f.readlines() return lines def calc():
lines_list_sc = get_word(test_file)
lines_list_gold = get_word(test_file2) lines_list_num = len(lines_list_gold) right_num = 0
m = 0#m存逆向结果文本词的总数
n = 0#n存gold文本词的总数 for i in range(lines_list_num): line_list_sc = list(lines_list_sc[i].split())#line_list_sc为生成结果每行通过空格切分后的词汇表
line_list_gold = list(lines_list_gold[i].split())#line_list_gold为正确结果每行通过空格切分后的词汇表 m += len(line_list_sc)
n += len(line_list_gold) str_sc = ''#存结果文本每行无空格连接起来的字符串
str_gold = ''#存gold文本每行无空格连接起来的字符串 s = 0#表示结果文本每行列表的下标
g = 0#表示gold文本每行列表的下标 while s < len(line_list_sc) and g < len(line_list_gold):
str_word_sc = line_list_sc[s]
str_word_gold = line_list_gold[g] str_sc += str_word_sc
str_gold += str_word_gold if str_word_sc == str_word_gold:#如果当前词汇相同,表明结果正确,且之前的词汇拼成的字符串长度相等
s += 1
g += 1
right_num += 1 else:#如果当前词汇不同,结果错误,不断取词汇拼字符串直到两个字符串长度相同 while len(str_sc) > len(str_gold):
g += 1
str_gold += line_list_gold[g] while len(str_sc) < len(str_gold):
s += 1
str_sc += line_list_sc[s] g += 1
s += 1 print("生成结果词的个数:", m)
print("gold文本词的个数:", n)
print("正确词的个数:", right_num)
p = right_num/m
r = right_num/n
f = 2*p*r/(p+r)
print("正确率:", p)
print("召回率:", r)
print("正向f值:", f)
calc()
运行结果如下:
- 6、训练语料和测试语料见下百度云盘链接
链接: https://pan.baidu.com/s/1X0coEznut6_s0jsDG9_9Dg 密码: b393
中文分词--最大正向与逆向匹配算法python实现的更多相关文章
- 中文分词算法之最大正向匹配算法(Python版)
最大匹配算法是自然语言处理中的中文匹配算法中最基础的算法,分为正向和逆向,原理都是一样的. 正向最大匹配算法,故名思意,从左向右扫描寻找词的最大匹配. 首先我们可以规定一个词的最大长度,每次扫描的时候 ...
- 【nlp】中文分词基础原则及正向最大匹配法、逆向最大匹配法、双向最大匹配法的分析
分词算法设计中的几个基本原则: 1.颗粒度越大越好:用于进行语义分析的文本分词,要求分词结果的颗粒度越大,即单词的字数越多,所能表示的含义越确切,如:“公安局长”可以分为“公安 局长”.“公安局 长” ...
- Python 自然语言处理(1)中文分词技术
中文分词技术 中文自动分词可主要归纳为“规则分词”“统计分词”和“混合分词”,规则分词主要是通过人工设立词库,按照一定方式进行匹配切分,实现简单高效,但对新词很难进行处理,统计分词能够较好应对新词发现 ...
- 分词 | 双向匹配中文分词算法python实现
本次实验内容是基于词典的双向匹配算法的中文分词算法的实现.使用正向和反向最大匹配算法对给定句子进行分词,对得到的结果进行比较,从而决定正确的分词方法. 算法描述正向最大匹配算法先设定扫描的窗口大小ma ...
- python第三方库------jieba库(中文分词)
jieba“结巴”中文分词:做最好的 Python 中文分词组件 github:https://github.com/fxsjy/jieba 特点支持三种分词模式: 精确模式,试图将句子最精确地切开, ...
- Python第三方库jieba(中文分词)入门与进阶(官方文档)
jieba "结巴"中文分词:做最好的 Python 中文分词组件 github:https://github.com/fxsjy/jieba 特点 支持三种分词模式: 精确模式, ...
- 双向最大匹配算法——基于词典规则的中文分词(Java实现)
目录 一.中文分词理论描述 二.算法描述 1.正向最大匹配算法 2.反向最大匹配算法 3.双剑合璧 三.案例描述 四.JAVA实现完整代码 五.组装UI 六.总结 前言 这篇将使用Java实现基于规则 ...
- python中文分词:结巴分词
中文分词是中文文本处理的一个基础性工作,结巴分词利用进行中文分词.其基本实现原理有三点: 基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG) 采用了动态规 ...
- jieba中文分词(python)
问题小结 1.安装 需要用到python,根据python2.7选择适当的安装包.先下载http://pypi.python.org/pypi/jieba/ ,解压后运行python setup.py ...
随机推荐
- ViewPager PagerAdapter 的使用
1: 目的,实现全屏滑动的效果 2:类似于BaseAdapter public class MyPagerAdapter extends PagerAdapter { private Context ...
- word中选择嵌入式时图片被遮住,只显示小部分的解决方法
选中图片,点击如下 选择 行距选项 将行距改为单位行距即可.
- oracle-3种工具使用
1:原命令行,dos 2:sqlplus,图形界面 3:isqlplus,网页版的.(假如自己机器无法安装oracle,可通过别人ip地址去使用oracle,http://ip:5560/isqlpl ...
- java就业前景发展方向分析
随着信息化的发展,IT培训受倒了越来越多人的追捧.在开发领域,JAVA培训成为了许多人的首选!java拥有强大的开发者的数量已超过了之前的900万,将近97%的企业电脑也在运行着java,其下载量每年 ...
- bootstrap 模态框日期控件datepicker被遮住问题的解决
找到日期输入框,并将 .class 属性的 z-index 改大 在JSP页添加样式: 这样就OK了:
- uni-app判断各大平台的语法
uni-app是一款强大的前端框架,它除了pc端其他都可以实现,打包原生app.手机h5页面,微信小程序, 但是有一个问题就是本生的app和微信小程序是有一定的区别的,因为app有标题栏,返回键,而微 ...
- 【CF1173D】NanuuAndCircle
题目链接:http://codeforces.com/contest/1173/problem/D 赛场上弱爆了的小菜鸡(本人),怎么也没想到这道看起来近似于神仙计数/生成函数的题正解竟然如此简洁. ...
- Codeforces Round #548 (Div. 2) C. Edgy Trees
You are given a tree (a connected undirected graph without cycles) of
- C#第五节课
switch语句 using System;using System.Collections.Generic;using System.Linq;using System.Text;using Sys ...
- BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)
题面传送门 题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线 很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献 ...