1、自然语言理解实验报告分词系统工程报告 课程:自然语言理解 姓名:王佳淼 学号:2011914 班级:信息安全11-1 日期:2013-11-2实验一 宋词字统计一研究背景本实验所涉及的研究背景是利用计算机来“鉴赏”宋词。主要针对宋词这种特殊的汉语诗歌体裁,开展了有关自动生成算法及其实现方法的探索性研究。通过对大量语料的学习,来自动生成宋词。由于宋词自身的特性,能够在经过大量预料学习后,利用在宋词当中出现频率较高的词语或者单字排列组合来生成宋词。二实验所采用的开发平台及语言工具实验在WIN7的环境下利用VC+编程。三系统设计(1)算法基本思想从文本中字符,判断是否为中文字符(全角字符),若为全角
2、字符则根据需要继续读取,即读取两个或三个字。利用map容器来存储统计结果。(2)流程图(3)代码字统计 #include #include #include #include using namespace std; /宋词的统计 void display_map(map &wmap); ofstream ofs(c:fenciout2.txt); int main() cout开始:endl; const char *szInputFileName=c:Text.txt; ifstream ifs(szInputFileName); string szTemp; string str1,st
3、r2,str3,str; char a10;/ map wmap; /统计双字的 while (ifs) while(ifs.peek()=n) ifs.get(); while(ifs.peek()= ) ifs.get(); while(!ifs.peek()&0x80) ifs.get(); ifs.get(a,3, ); if(a0&0x80) str1=a; while(ifs.peek()=n) continue; while(ifs.peek()= ) continue; while(!ifs.peek()&0x80) ifs.get(); ifs.get(a,3, ); if(
4、a0&0x80) str2=a; if(str1!=,&str1!=。&str1!=?&str1!=!&str1!=&str2!=,&str2!=。&str2!=?&str2!=!&str2!=) szTemp=str1+str2; wmapszTemp+; if(ifs.peek()!=n&ifs.peek()!= ) ifs.seekg(-2,ios:cur); ifs.close(); /三字 ifstream ifs1(szInputFileName); while (ifs1) while(ifs1.peek()=n) ifs1.get(); while(ifs1.peek()= )
5、 ifs1.get(); while(!ifs1.peek()&0x80) ifs1.get(); ifs1.get(a,3, ); if(a0&0x80) str1=a; while(ifs1.peek()=n) continue; while(ifs1.peek()= ) continue; while(!ifs1.peek()&0x80) ifs1.get(); ifs1.get(a,3, ); if(a0&0x80) str2=a; else continue; while(ifs1.peek()=n) continue; while(ifs1.peek()= ) continue;
6、while(!ifs1.peek()&0x80) ifs1.get(); ifs1.get(a,3, ); if(a0&0x80) str3=a; else continue; if(str1!=,&str1!=。&str1!=?&str1!=!&str1!=&str2!=,&str2!=。&str2!=?&str2!=!&str2!=&str3!=,&str3!=。&str3!=?&str3!=!&str3!=) szTemp=str1+str2+str3; wmapszTemp+; if(ifs1.peek()!=n&ifs1.peek()!= ) ifs1.seekg(-4,ios:cu
7、r); ifs1.close();/单字 ifstream ifs2(szInputFileName); while (ifs2) while(ifs2.peek()=n) ifs2.get(); while(ifs2.peek()= ) ifs2.get(); while(!ifs2.peek()&0x80) ifs2.get(); ifs2.get(a,3, ); if(a0&0x80) str=a; if(str!=,&str!=。&str!=?&str!=!&str!=) szTemp=str; wmapszTemp+; ifs2.close(); display_map(wmap);
8、 return false; void display_map(map &wmap) int sum=0; map:const_iterator map_it; for (map_it=wmap.begin(); map_it!=wmap.end();map_it+) /统计总数 sum+=map_it-second; for (map_it=wmap.begin(); map_it!=wmap.end();map_it+) /计算词频 cout(first,second); coutsecond/(sum-1)endl; for (map_it=wmap.begin(); map_it!=w
9、map.end();map_it+) /计算词频 ofs(first,second); ofssecond/sumendl; 宋词生成 #include #include #include #include using namespace std; void display_map(map &wmap); void ci(int a); map wmap; map wmapp; int main() cout开始:endl; const char *szInputFileName=c:Text.txt; ifstream ifs(szInputFileName); string szTemp,
10、szTempp; string str1,str2,str; char a10;/ /统计双字的 while (ifs) while(ifs.peek()=n) ifs.get(); while(ifs.peek()= ) ifs.get(); ifs.get(a,3, ); if(a0&0x80) str1=a; while(ifs.peek()=n) continue; while(ifs.peek()= ) continue; ifs.get(a,3, ); if(a0&0x80) str2=a; if(str1!=,&str1!=。&str1!=?&str1!=!&str1!=&str
11、2!=,&str2!=。&str2!=?&str2!=!&str2!=) szTemp=str1+str2; wmapszTemp+; if(ifs.peek()!=n&ifs.peek()!= ) ifs.seekg(-2,ios:cur); ifs.close(); / display_map(wmap); /单字 ifstream ifs1(szInputFileName); while (ifs1) while(ifs1.peek()=n) ifs1.get(); while(ifs1.peek()= ) ifs1.get(); ifs1.get(a,3, ); if(a0&0x80)
12、 str=a; if(str!=,&str!=。&str!=?&str!=!&str!=) szTemp=str; wmappszTemp+; ifs1.close(); / display_map(wmapp); int as; while(1) cout请随意输入一个数来创造宋词:(输入0时退出)as; if(as=0) return 0; ci(as); coutendlendl; cout-endl; coutendlendl; return false; void ci(int a) cout 如梦令endl; map:iterator map_it; for(int i=0;i3;
13、i+) map_it=wmap.begin(); for(int j=0;j(rand()+a*2)%(wmap.size();j+) map_it+; coutfirst; cout。; for(i=0;i3;i+) map_it=wmap.begin(); for( int j=0;jrand()%(a);j+) map_it+; coutfirst; cout。; for(i=0;i2;i+) map_it=wmap.begin(); for( int j=0;jrand()%(wmap.size();j+) map_it+; coutfirst; map_it=wmapp.begin(
14、); for( int j=0;j(rand()+a*3)%(wmapp.size();j+) map_it+; coutfirst; cout,; for(i=0;i3;i+) map_it=wmap.begin(); for( int j=0;j(rand()+a)%(wmap.size();j+) map_it+; coutfirst; cout。; map_it=wmap.begin(); for( j=0;jfirst; couttemp。temp。; for(i=0;i3;i+) map_it=wmap.begin(); for( int j=0;j(a*rand()%(wmap.
15、size();j+) map_it+; coutfirst; cout。endl; void display_map(map &wmap) map:const_iterator map_it; for (map_it=wmap.begin(); map_it!=wmap.end();map_it+) cout(first,second)endl; 四系统演示和分析(1)截图字统计:宋词生成(如梦令):(2)结果分析五对次实验的感想、意见和建议通过此次实验,能熟练利用MAP容器,为接下来的两个实验打好基础。也能对汉字进行操作,清楚的了解到汉字在计算机中的存储方式有别于字符型。利用位运算&来和0x
16、80进行比对以区分全角字符和半角字符。但因为将字作为了map的key值,所以输出的列并不是按照出现频率由大到小,这是可以进行改进的方面。在宋词生成的程序中,主要是利用随机输入的数字来产生伪随机数,以便利用产生的伪随机数选择不同出现频率的词组来生成宋词。我觉得可以改进的方面是,在统计时就能用程序自动获取不同词牌名的不同格式,在生成宋词时能选择不同的词牌名以生成不同宋词,使程序更加智能。实验二 人民日报词频统计一研究背景词是自然语言中能够独立运用的最小单位,是自然语言处理的基本单位。自动词法分析就是利用计算机对自然语言的形态 (morphology) 进行分析,判断词的结构和类别等。而词频统计是分
17、词系统的基础和关键,只有在正确、准确、快速的词频统计的情况下才能很好的进行分词算法。二实验所采用的开发平台及语言工具实验在WIN7的环境下利用VC+编程。三系统设计(1)算法基本思想从文本中字符,判断是否为中文字符(全角字符),若为全角字符则根据需要继续读取,即读取两个或三个字。利用map容器来存储统计结果。(2)流程图(3)代码 #include #include #include #include #include #include using namespace std; /人民日报的词频统计 typedef pair PAIR; vector vecpair; void display
18、_map(map &wmap); ofstream ofs(c:fenciout.txt); int cmp(const PAIR& x, const PAIR& y)/vector的sort()降序排列 return x.secondy.second; int main() cout开始:endl; const char *szInputFileName=c:cidian.txt; ifstream ifs(szInputFileName); string szTemp; string str1,str2,str3,str; char a100;/ map wmap; map wmapok;
19、 /统计 while (ifs) szTemp=; int i=0; ifsai;/逐个字符读入 if(ifs.eof() break; if(!(ai&0x80)/非中文 continue; if(!(ai&0xB0)/除去空格 ifsai; continue; while(ai!=/)/读取 szTemp+=ai; i+; ifsai; wmapszTemp+;/对应字频加1 ifs.close(); /map 根据value排序 map:const_iterator curr; for(curr=wmap.begin();curr!=wmap.end();+curr) vecpair.p
20、ush_back(make_pair(curr-first,curr-second); sort(vecpair.begin(),vecpair.end(),cmp);/调用排序函数,则vecpair中的first是词,而且降序排列 for(int i = 0 ;ivecpair.size();i+) ofs vecpairi.first , vecpairi.second endl; display_map(wmap); return; void display_map(map &wmap) int sum=0; map:const_iterator map_it; for (map_it=
21、wmap.begin(); map_it!=wmap.end();map_it+) /统计总数 sum+=map_it-second; for (map_it=wmap.begin(); map_it!=wmap.end();map_it+) /计算词频,在界面上输出,此时是无序的 cout(first,second); coutsecond/sumendl; 四系统演示和分析(1)截图排序后:(2)结果分析五对次实验的感想、意见和建议在这次实验后,能含有分词字符的文件进行读取,利用语料来训练程序,并将结果保存在文件当中,以便实验三可以使用。而且能够进行排序,按照value的值,即词语出现次数
22、由高到低进行排序。美中不足的是,程序运行速度有待提高。由于map是按照键值排序的,所以引入了vector,并利用vector的sort函数进行排序,熟悉了这两种容器的使用,提高了对c+库函数的认识。实验三 人民日报分词一研究背景自动词法分析就是利用计算机对自然语言的形态 (morphology) 进行分析,判断词的结构和类别等。自动分词是汉语句子分析的基础,而且,词语的分析具有广泛的使用(词频统计,词典编纂,文章风格研究等)二模型方法正向最大匹配算法 (Forward MM, FMM)。这种算法使得程序简单易行,开发周期短,而且仅需要很少的语言资源(词表),不需要任何词法、句法、语义资源。三系
23、统设计(1)算法基本思想FMM 算法描述:(1) 令 i=0,当前指针 pi 指向输入字串的初始位置,执行下面的操作:(2) 计算当前指针 pi到字串末端的字数(即未被切分字串的长度)n,如果n=1,转(4),结束算法。否则,令 m=词典中最长单词的字数,如果nm, 令 m=n;(3)从当前 pi起取m个汉字作为词 wi,判断:(a) 如果 wi 确实是词典中的词,则在wi 后添加一个切分标志,转(c);(b) 如果 wi 不是词典中的词且 wi 的长度大于1,将wi从右端去掉一个字,转(a)步;否则(wi 的长度等于1),则在wi 后添加一个切分标志(单字),执行 (c)步;(c) 根据 w
24、i 的长度修改指针 pi的位置,如果 pi指向字串末端,转(4),否则,i=i+1,返回 (2);(4) 输出切分结果,结束分词程序。(2)流程图图1.分词流程图图2.FMM算法流程图(3)代码 #include #include #include #include #include #include using namespace std; /人民日报的词频统计 typedef pair PAIR; vector vecpair; ofstream ofs(c:fenciout.txt); int cmp(const PAIR& x, const PAIR& y) return x.secondy.second; int main() cout开始:endl; const char *szInputFileName=c:cidian.txt; ifstream ifs(szInputFileName); string szTemp; s
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2