自然语言处理-中文分词程序实验报告(含源代码)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

二、程序设计 查找算法:哈希表查找
除了分词结果的准确性,程序的性能也是至关重要的。由于本程序采用了词典法 来分词,执行过程需要检索大量数据,因此查找效率成为程序性能的决定性因素。 据我的了解,目前比较成熟的查找算法主要有顺序查找、 二分查找、 哈希表查找等。 顺序查找的算法复杂度为 O(n); 二分查找的算法复杂度为 O(logn),但需要事先排序; 哈希表查找的复杂度为 O(1)。 本程序采用效率最高的哈希表查找算法。
北京邮电大学计算机学院 《自然语言处理导论》 中文分词实验报告
姓 名: 许伟林 学 号: 08211306 指导教师: 郑岩 日 期: 2010/12/22
1
内容目录
一、实验目的...............................................................3 二、实验环境...............................................................3 三、实验材料...............................................................3 四、实验设计...............................................................3 一、分词策略.............................................................3 词典逆向最大匹配法...................................................4 基于确定文法的分词法.................................................4 二、程序设计.............................................................4 查找算法:哈希表查找.................................................4 汉字编码格式:UTF-8...................................................5 程序流程图............................................................6 程序源代码............................................................8 五、结果和性能分析........................................................16 分词结果示例............................................................16 性能分析................................................................17 六、有待解决的问题........................................................18 七、实验总结..............................................................19
3
由于时间仓促,且水平有限,本程序只实现了第 2 种和第 3 种分词法,即词典逆 向最大匹配法和基于确定文法的分词法。
词典逆向最大匹配法
词典逆向最大匹配法完成分词的大部分工作,设计思路是这样的: 1、 将词典的每个词条读入内存,最长是 4 字词,最短是 1 字词; 2、 从语料中读入一段(一行)文字,保存为字符串; 3、 如果字符串长度大于 4 个中文字符,则取字符串最右边的 4 个中文字符,作 为候选词;否则取出整个字符串作为候选词; 4、 在词典中查找这个候选词,如果查找失败,则去掉这个候选词的最左字,重 复这步进行查找,直到候选词为 1 个中文字符; 5、 将候选词从字符串中取出、删除,回到第 3 步直到字符串为空; 6、 回到第 2 步直到语料已读完。
4
汉字编码格式:UTF-8
中文处理和英文处理的一个很大不同就在于编码格式的复杂性。常见的中文编码 格式有 GB2312,GB18030,GBK,Unicode 等等。同样的中文字符,在不同的汉字 编码格式中,可能有不同的二进制表示。因此编程做字符串匹配时,通常要求统一的 编码格式。 在 linux 下可以用 file 命令查看文本文件的编码格式。经过检查,发现老师提供的 词典和语料属于不同的编码格式,直接做字符串匹配可能会有问题。 考虑到 UBUNTU 以 UTF-8 作为默认编码格式,我索性使用 enconv 命令将词典和语料都转换成 UTF-8 格式。 下面简要介绍一下 UTF-8 格式。 前 面 提 到 的 Unicode 的 学 名 是 "Universal Multiple-Octet Coded Character Set",简称为 UCS。UCS 可以看作是"Unicode Character Set"的缩写。 UCS 只是规定如何编码,并没有规定如何传输、保存这个编码。UTF-8 是被广泛 接受的方案。UTF-8 的一个特别的好处是它与 ISO-8859-1 完全兼容。UTF 是“UCS Transformation Format”的缩写。 UTF-8 就是以 8 位为单元对 UCS 进行编码。 从 UCS-2 到 UTF-8 的编码方式如下: UCS-2 编码(16 进制) 0000 – 007F 0080 – 07FF 0800 – FFFF UTF-8 字节流(二进制) 0xxxxxxx 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx
基于确定文法的分词法
基于确定文法的分词法可以进行数字、西文、时间的分词,设计思路是这样的: 1、 增加一个词典,存储中文编码(全角)的大小写拉丁字母、 中文小写数字、 阿 拉伯数字、 数字单位(百、 千、 万、 亿、 兆)、 小数点、 百分号、 除号;词类型记为[D1]; 2、 增加一个词典,存储中文编码的时间单位,包括年、 月、 日、 时、 分、 秒、 点;词 类型记为[D2]; 3、 文法的正则表达式为[D1]*[D2]?。
#include #include #include #include #include #include #include #include <iostream> <string> <fstream> <sstream> <ext/hash_map> <iomanip> <stdio.h> <time.h> // 最大词长字节(即 4 个汉字)
8
#define MaxWordLength 12
#define Separator " " #define UTF8_CN_LEN 3
// 词界标记 // 汉字的 UTF-8 编码为 3 字节
using namespace std; using namespace __gnu_cxx; namespace __gnu_cxx { template<> struct hash< std::string > { size_t operator()( const std::string& x ) const { return hash< const char* >()( x.c_str() ); } }; } hash_map<string, int> wordhash; // 词典 hash_map<string, int> numberhash;// 数字和字母 hash_map<string, int> unithash;// 时间单位 //读入词典,以及数字、字母、时间单位集 void get_dict(void) { string strtmp; //读取词典的每一行 string word; //保存每个词 typedef pair<string, int> sipair; ifstream infile("dict/CoreDict.txt.utf8"); if (!infile.is_open()) { cerr << "Unable to open input file: " << "wordlexicon" << " -- bailing out!" << endl; exit(-1); } while (getline(infile, strtmp)) // 读入词典的每一行并将其添加入哈希中 { istringstream istr(strtmp); istr >> word; //读入每行第一个词 wordhash.insert(sipair(word, 1)); //插入到哈希中 } infile.close();
2
一、实验目的
了解中文分词的意义 掌握中文分词的基本方法
Leabharlann Baidu
二、实验环境
UBUNTU 10.05 GCC v4.4.3
三、实验材料
中文常用词词典 《人民日报》1998 年合订本
四、实验设计
一、分词策略
据我的了解,目前较为成熟的中文分词方法主要有: 1、 词典正向最大匹配法 2、 词典逆向最大匹配法 3、 基于确定文法的分词法 4、 基于统计的分词方法 一般认为,词典的逆向匹配法要优于正向匹配法。基于确定文法和基于统计的方 法作为自然语言处理的两个流派,各有千秋。
例如“汉”字的 Unicode 编码是 6C49。6C49 在 0800-FFFF 之间,所以肯定要用 3 字节模板了: 1110xxxx 10xxxxxx 10xxxxxx 。将 6C49 写成二进制是: 0110 110001 001001 , 用 这 个 比 特 流 依 次 代 替 模 板 中 的 x , 得 到 : 11100110 10110001 10001001,即 E6 B1 89。 所以,就有了这个结论:汉字的 UTF-8 编码是 3 字节的。然而,语料库中出现的 字符并非都是汉字。 比如半角空格、 外国人名字间隔符等。 如果把所有字单元都视为 3 字节,就要出错了。这是编程时必须考虑的问题。
9
infile.open("dict/number.txt.utf8"); if (!infile.is_open()) { cerr << "Unable to open input file: " << "wordlexicon" << " -- bailing out!" << endl; exit(-1); } while (getline(infile, strtmp)) // 读入词典的每一行并将其添加入哈希中 { istringstream istr(strtmp); istr >> word; //读入每行第一个词 numberhash.insert(sipair(word, 1)); //插入到哈希中 } infile.close(); infile.open("dict/unit.txt.utf8"); if (!infile.is_open()) { cerr << "Unable to open input file: " << "wordlexicon" << " -- bailing out!" << endl; exit(-1); } while (getline(infile, strtmp)) // 读入词典的每一行并将其添加入哈希中 { istringstream istr(strtmp); istr >> word; //读入每行第一个词 unithash.insert(sipair(word, 1)); //插入到哈希中 } infile.close(); } //删除语料库中已有的分词空格,由本程序重新分词 string eat_space(string s1) { int p1=0,p2=0; int count; string s2; while(p2 < s1.length()){ //删除全角空格 // if((s1[p2]-0xffffffe3)==0 && // s1[p2+1]-0xffffff80==0 && // s1[p2+2]-0xffffff80==0){//空格
5
程序流程图
6
7
程序源代码
/* * segment.cpp ---- 中文分词程序 * * 功能:1)中文词典分词(逆向最大匹配) * 2)数字分词 * 3)西文分词 * 4)时间分词 * 用法: * ./segment ARTICAL * 范例: * ./segment 1998-01-qiefen-file.txt.utf8 * 屏幕输出: * 词典读入完毕,耗时 0.000776 s * 分词完毕,耗时 3.18 s * * 分词结果保存在 result.txt.utf8 中。 * * 注意:1)本程序只能处理 utf-8 文本,其他格式的文本请用 iconv 或 enconv 转换成 utf-8 格式。 * 2 ) 程 序 运 行 需 要 dict/CoreDict.txt.utf8,dict/number.txt.utf8,dict/unit.txt.utf8 三个文件。 * * 参考了以下文章,特此感谢! * http://www.52nlp.cn/maximum-matching-method-of-chinese-wordsegmentation/ * * Created on: 2010-11-30 * Author: xuweilin <usa911 at bupt.edu.cn> */
相关文档
最新文档