实验一、中文分词一、实验内容用正向最大匹配法对文档进行中文分词,其中:(1)wordlist.txt 词表文件(2)pku_test.txt 未经过分词的文档文件(3)pku_test_gold.txt 经过分词的文档文件二、实验所采用的开发平台及语言工具Visual C++ 6.0三、实验的核心思想和算法描述本实验的核心思想为正向最大匹配法,其算法描述如下假设句子: , 某一词 ,m 为词典中最长词的字数。
(1) 令 i=0,当前指针 pi 指向输入字串的初始位置,执行下面的操作:(2) 计算当前指针 pi 到字串末端的字数(即未被切分字串的长度)n ,如果n=1,转(4),结束算法。
否则,令 m=词典中最长单词的字数,如果n<m, 令 m=n ;(3) 从当前 pi 起取m 个汉字作为词 wi ,判断:(a) 如果 wi 确实是词典中的词,则在wi 后添加一个切分标志,转(c);(b) 如果 wi 不是词典中的词且 wi 的长度大于1,将wi 从右端去掉一个字,转(a)步;否则(wi 的长度等于1),则在wi 后添加一个切分标志,将wi 作为单字词添加到词典中,执行 (c)步;(c) 根据 wi 的长度修改指针 pi 的位置,如果 pi 指向字串末端,转(4),否则, i=i+1,返回 (2);(4) 输出切分结果,结束分词程序。
四、系统主要模块流程、源代码(1) 正向最大匹配算法12n S c c c = 12i m w c c c =(2)原代码如下// Dictionary.h#include <iostream>#include <string>#include <fstream>using namespace std;class CDictionary{public:CDictionary(); //将词典文件读入并构造为一个哈希词典 ~CDictionary();int FindWord(string w); //在哈希词典中查找词private:string strtmp; //读取词典的每一行string word; //保存每个词string strword[55400];};//将词典文件读入并CDictionary::CDictionary(){ifstream infile("wordlist.txt"); // 打开词典if (!infile.is_open()) // 打开词典失败则退出程序{cerr << "Unable to open input file: " << "wordlist.txt"<< " -- bailing out!" << endl;exit(-1);}int i=0;while (getline(infile, strtmp)) // 读入词典的每一行并将其添加入哈希中{strword[i++]=strtmp;}infile.close();}CDictionary::~CDictionary(){}//在哈希词典中查找词,若找到,则返回,否则返回int CDictionary::FindWord(string w){int i=0;while ((strword[i]!=w) && (i<55400))i++;if(i<55400)return 1;elsereturn 0;}// 主程序main.cpp#include "Dictionary.h"#define MaxWordLength 14 // 最大词长为个字节(即个汉字)# define Separator " " // 词界标记CDictionary WordDic; //初始化一个词典//对字符串用最大匹配法(正向)处理string SegmentSentence(string s1){string s2 = ""; //用s2存放分词结果string s3 = s1;int l = (int) s1.length(); // 取输入串长度int m=0;while(!s3.empty()){int len =(int) s3.length(); // 取输入串长度if (len > MaxWordLength) // 如果输入串长度大于最大词长 {len = MaxWordLength; // 只在最大词长范围内进行处理 }string w = s3.substr(0, len); //(正向用)将输入串左边等于最大词长长度串取出作为候选词int n = WordDic.FindWord(w); // 在词典中查找相应的词while(len > 1 && n == 0) // 如果不是词{int j=len-1;while(j>=0 && (unsigned char)w[j]<128){j--;}if(j<1){break;}len -= 1; // 从候选词右边减掉一个英文字符,将剩下的部分作为候选词 w = w.substr(0, len); //正向用n = WordDic.FindWord(w);}s2 += w + Separator; // (正向用)将匹配得到的词连同词界标记加到输出串末尾s3 = s1.substr(m=m+w.length(), s1.length()); //(正向用)从s1-w处开始}return s2;}int main(int argc, char *argv[]){string strtmp; //用于保存从语料库中读入的每一行string line; //用于输出每一行的结果ifstream infile("pku_test.txt"); // 打开输入文件if (!infile.is_open()) // 打开输入文件失败则退出程序{cerr << "Unable to open input file: " << "pku_test.txt"<< " -- bailing out!" << endl;exit(-1);}ofstream outfile1("SegmentResult.txt"); //确定输出文件if (!outfile1.is_open()){cerr << "Unable to open file:SegmentResult.txt"<< "--bailing out!" << endl;exit(-1);}while (getline(infile, strtmp)) //读入语料库中的每一行并用最大匹配法处理{line = strtmp;line = SegmentSentence(line); // 调用分词函数进行分词处理outfile1 << line << endl; // 将分词结果写入目标文件cout<<line<<endl;}infile.close();outfile1.close();return 0;}五、实验结果及分析(1)、实验运行结果(2)实验结果分析在基于字符串匹配的分词算法中,词典的设计往往对分词算法的效率有很大的影响。
正向最大匹配分词算法是最基本的字符串匹配算法之一,它能够保证将词典中存在的最长复合词切分出来。
实验二:ICTCLAS 汉语分词系统说明一、实验内容调用ICTCLAS程序对其中的文档进行分词,并标注词性(实验数据包含1个文件:pku_test.txt 未经过分词的文档文件)二、实验所采用的开发平台及语言工具Visual C++ 6.0ICTCLAS 汉语分词系统/中科院计算所ICTCLAS 5.0接口文档三、实验的核心思想和算法描述分词系统的主要是思想是先通过CHMM(层叠形马尔可夫模型)进行分词,通过分层,既增加了分词的准确性,又保证了分词的效率.共分五层,如下图一所示:基本思路:先进行原子切分,然后在此基础上进行N-最短路径粗切分,找出前N个最符合的切分结果,生成二元分词表,然后生成分词结果,接着进行词性标注ICTCLAS程序软件使用:(1). 在函数里加入对ICTCLAS50.lib的引用#ifndef OS_LINUX#include <Windows.h>#pragma comment(lib, "ICTCLAS50.lib") //ICTCLAS50.lib库加入到工程中#endif(2).ICTCLAS_API bool ICTCLAS_FileProcess函数的调用ICTCLAS_API bool ICTCLAS_FileProcess(const char* pszSrcFileName, //文本文件的读取const char* pszDstFileName, //目标文件的存放eCodeType srcCodeType=CODE_TYPE_UNKNOWN, //类型bool bEnablePOS=false //true表示可以标注词性);(3). ICTCLAS5.0接口文档中的示例四、系统源代码/************(1). 在函数里加入对ICTCLAS50.lib的引用********/#ifndef OS_LINUX#include <Windows.h>#pragma comment(lib, "ICTCLAS50.lib") //ICTCLAS50.lib库加入到工程中#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <string>#include "ICTCLAS50.h"using namespace std;int main(int argc, char* argv[]){if(!ICTCLAS_Init()){printf("Init fails\n");return -1;}ICTCLAS_FileProcess("pku_test.txt","Test_result.txt",CODE_TYPE_GB,true);//分别表示读取所需分次的文件、存放分词结果的文件、类型、标注词性printf("Init ok\n"); //分词结束后输出提示ICTCLAS_Exit();return 0;}五、实验结果及分析(1)分词前分词后:(2)实验结果分析ICTCLAS是中科院计算所研发的中文分词软件,这个软件在第一届国际中文处理研究机构SigHan组织的评测中都获得了多项第一名,是公认的当今最好的中文分词软件。