目录
一、实验目的
1、掌握正向最大匹配法;
2、掌握逆向最大匹配法;
3、熟悉中文分词工具。
二、实验任务
1、给定字典,[‘研究’,’研究生’, ’生命’,’命’,’的’,‘起源’]
(1)实现正向最大匹配法或逆向最大匹配法,以实现对“研究生命的起源”这个串的分词(必做);
(2)对比两种方法在切分“研究生命的起源”的差异(附加)。
2、利用Jieba实现高频词提取(附加)。
三、实验原理
1 NumPy 简介
NumPy(Numerical Python)是Python语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。NumPy是一个运行速度非常快的数学库,主要用于数组计算,包含:一个强大的N维数组对象ndarray;广播功能函数;整合 C/C++/Fortran 代码的工具;线性代数、傅里叶变换、随机数生成等功能。NumPy最重要的一个特点是其N维数组对象ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组,它的每个元素在内存中都有相同存储大小的区域。
图3.1 ndarray存储示意图
图3.2 ndarray知识框架
2 匹配算法
正向最大匹配算法(FMM):从左到右将待分词文本中的几个连续字符与词表匹配,如果匹配上,则切分出一个词。它是一种基于词典的分词方法,同样的基于词典的方法还有逆向最大匹配法(RMM),ngram法.FMM故名思意,左向右扫描寻找词的最大匹配,是一种贪心的思想。
四、实验过程
1 正向最大匹配法
Step 1:假定分词词典中的最长词有i个汉字字符,则用被处理的当前字串中的前i个字作为匹配字段,查找字典。
Step 2:若字典中存在这样一个i字词,则匹配成功;否则,失败,将匹配字段中的最后一个字符去掉, 对剩下字串进行匹配。
Step 3:如此进行下去,直到匹配成功,即切分出一个词或剩余字串长度为0。
不停的匹配,直到文档被扫描完为止。
2 逆向最大匹配法
Step 1:假定分词词典中的最长词有i个汉字字符,则用被处理的当前字串中的后i个字作为匹配字段,查找字典。
Step 2:若字典中存在这样一个i字词,则匹配成功;否则,失败,将匹配字段中的首字符去掉, 对剩下字串进行匹配。
Step 3:如此进行下去,直到匹配成功,即切分出一个词或剩余字串长度为0。
不停的匹配,直到文档被扫描完为止。
*3 jieba英文词组分词
往相应的正则表达式添加空格,然后手动添加需要统计的词组:
五、实验结果
1 中文分词
采用两种不同的分词方法,其相应结果如下表4.1所示。
表4.1 分词结果对比
分词方法 | 结果 |
正向最大匹配法 | ['研究生', '命', '的', '起源'] |
逆向最大匹配法 | ['研究', '生命', '的', '起源'] |
正向最大匹配法和逆向最大匹配法两种不同的分词方法,分词的结果是不相同的。按照我们的理解,对本实验的例句进行分词,第二种匹配方法更为恰当。本次实验,我们只是采用了一个简单的中文句子,结果都不一样。可想而知,如果对于一篇文章或者一部文学著作而言,最终的结果更是有所差别。
2 jieba词频统计
如下图4.1所示,可以统计出自定义词组“5G network”的词频。
图4.1 jieba词频统计示意图
参考资料
- jieba官网:https://pypi.org/project/jieba/
- jieba英文空格分词问题:https://segmentfault.com/q/1010000016011808
附录
1 任务一:中文分词代码
# -*- coding: utf-8 -*- """ Created on Fri Feb 28 17:16:47 2020 @author: 小果果学长 """ dic_list=['研究生','研究','生命','命','的','起源']; text="研究生命的起源" ans_forward=[] ans_reverse=[] max_len=3#记录字典中词的最大长度 def Forward_Match(sentence): len_now=len(sentence) while len_now>0: divide=sentence[0:max_len] while divide not in dic_list: if len(divide)==1: dic_list.append(divide) break; divide=divide[0:(len(divide)-1)] ans_forward.append(divide) sentence=sentence[len(divide):] len_now=len(sentence) print("\"正向最大匹配\"的分词结果:",ans_forward) def Reverse_Match(sentence): len_now=len(sentence) while len_now>0: divide=sentence[-max_len:]#取text后三个字符 while divide not in dic_list: if len(divide)==1: dic_list.append(divide) break; divide=divide[1:] ans_reverse.append(divide) sentence=sentence[:(len_now-len(divide))] len_now=len(sentence) print("\"逆向最大匹配\"的分词结果:",ans_reverse[::-1])
if __name__=='__main__': Forward_Match(text) Reverse_Match(text) |
2 任务二:jieba词频统计
import jieba import re jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持 f=open('ex1_news.txt',encoding="ANSI"); text=f.read(); jieba.re_han_default = re.compile("([\u4E00-\u9FD5a-zA-Z0-9+#&\._% ]+)", re.U) jieba.add_word('5G network') seg_list = list(jieba.cut(text, cut_all=False)) dic_seg_list = set(seg_list) newText=''; for i in dic_seg_list: newText=newText+i+' '+str(seg_list.count(i))+'\n'; newFile=open('ex1_结巴词频统计结果.txt','w'); newFile.write(newText); newFile.close(); |