自然语言理解实验报告.docx
- 文档编号:17460976
- 上传时间:2023-07-25
- 格式:DOCX
- 页数:30
- 大小:757.48KB
自然语言理解实验报告.docx
《自然语言理解实验报告.docx》由会员分享,可在线阅读,更多相关《自然语言理解实验报告.docx(30页珍藏版)》请在冰点文库上搜索。
自然语言理解实验报告
分词系统工程报告
课程:
自然语言理解
姓名:
王佳淼
学号:
2011914
班级:
信息安全11-1
日期:
2013-11-2
实验一宋词字统计
一.研究背景
本实验所涉及的研究背景是利用计算机来“鉴赏”宋词。
主要针对宋词这种特殊的汉语诗歌体裁,开展了有关自动生成算法及其实现方法的探索性研究。
通过对大量语料的学习,来自动生成宋词。
由于宋词自身的特性,能够在经过大量预料学习后,利用在宋词当中出现频率较高的词语或者单字排列组合来生成宋词。
二.实验所采用的开发平台及语言工具
实验在WIN7的环境下利用VC++编程。
三.系统设计
(1)算法基本思想
从文本中字符,判断是否为中文字符(全角字符),若为全角字符则根据需要继续读取,即读取两个或三个字。
利用map容器来存储统计结果。
(2)流程图
(3)代码
①字统计
#include
#include
#include
#include
usingnamespacestd;
//宋词的统计
voiddisplay_map(map
ofstreamofs("c:
\\fenciout2.txt");
intmain()
{
cout<<"开始:
"< constchar*szInputFileName="c: \\Text.txt"; ifstreamifs(szInputFileName); stringszTemp; stringstr1,str2,str3,str; chara[10];// map //统计双字的 while(ifs) { while(ifs.peek()=='\n')ifs.get(); while(ifs.peek()=='')ifs.get(); while(! ifs.peek()&0x80)ifs.get(); ifs.get(a,3,''); if(a[0]&0x80) { str1=a; while(ifs.peek()=='\n')continue; while(ifs.peek()=='')continue; while(! ifs.peek()&0x80)ifs.get(); ifs.get(a,3,''); if(a[0]&0x80)str2=a; if(str1! =","&&str1! ="。 "&&str1! ="? "&&str1! ="! "&&str1! =""&&str2! =","&&str2! ="。 "&&str2! ="? "&&str2! ="! "&&str2! ="") { szTemp=str1+str2; wmap[szTemp]++; } if(ifs.peek()! ='\n'&&ifs.peek()! ='')ifs.seekg(-2,ios: : cur); } } ifs.close(); //三字 ifstreamifs1(szInputFileName); while(ifs1) { while(ifs1.peek()=='\n')ifs1.get(); while(ifs1.peek()=='')ifs1.get(); while(! ifs1.peek()&0x80)ifs1.get(); ifs1.get(a,3,''); if(a[0]&0x80) { str1=a; while(ifs1.peek()=='\n')continue; while(ifs1.peek()=='')continue; while(! ifs1.peek()&0x80)ifs1.get(); ifs1.get(a,3,''); if(a[0]&0x80)str2=a; elsecontinue; while(ifs1.peek()=='\n')continue; while(ifs1.peek()=='')continue; while(! ifs1.peek()&0x80)ifs1.get(); ifs1.get(a,3,''); if(a[0]&0x80)str3=a; elsecontinue; if(str1! =","&&str1! ="。 "&&str1! ="? "&&str1! ="! "&&str1! =""&&str2! =","&&str2! ="。 "&&str2! ="? "&&str2! ="! "&&str2! =""&&str3! =","&&str3! ="。 "&&str3! ="? "&&str3! ="! "&&str3! ="") { szTemp=str1+str2+str3; wmap[szTemp]++; } if(ifs1.peek()! ='\n'&&ifs1.peek()! ='')ifs1.seekg(-4,ios: : cur); } } ifs1.close(); //单字 ifstreamifs2(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(a[0]&0x80) { str=a; } if(str! =","&&str! ="。 "&&str! ="? "&&str! ="! "&&str! ="") { szTemp=str; wmap[szTemp]++; } } ifs2.close(); display_map(wmap); returnfalse; } voiddisplay_map(map { intsum=0; map : const_iteratormap_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<<"(\""< cout<<(double)map_it->second/(sum-1)< } for(map_it=wmap.begin();map_it! =wmap.end();map_it++)//计算词频 { ofs<<"(\""< ofs<<(double)map_it->second/sum< } } ②宋词生成 #include #include #include #include usingnamespacestd; voiddisplay_map(map voidci(inta); map map intmain() { cout<<"开始: "< constchar*szInputFileName="c: \\Text.txt"; ifstreamifs(szInputFileName); stringszTemp,szTempp; stringstr1,str2,str; chara[10];// //统计双字的 while(ifs) { while(ifs.peek()=='\n')ifs.get(); while(ifs.peek()=='')ifs.get(); ifs.get(a,3,''); if(a[0]&0x80) { str1=a; while(ifs.peek()=='\n')continue; while(ifs.peek()=='')continue; ifs.get(a,3,''); if(a[0]&0x80)str2=a; if(str1! =","&&str1! ="。 "&&str1! ="? "&&str1! ="! "&&str1! =""&&str2! =","&&str2! ="。 "&&str2! ="? "&&str2! ="! "&&str2! ="") { szTemp=str1+str2; wmap[szTemp]++; } if(ifs.peek()! ='\n'&&ifs.peek()! ='')ifs.seekg(-2,ios: : cur); } } ifs.close(); //display_map(wmap); //单字 ifstreamifs1(szInputFileName); while(ifs1) { while(ifs1.peek()=='\n')ifs1.get(); while(ifs1.peek()=='')ifs1.get(); ifs1.get(a,3,''); if(a[0]&0x80) { str=a; } if(str! =","&&str! ="。 "&&str! ="? "&&str! ="! "&&str! ="") { szTemp=str; wmapp[szTemp]++; } } ifs1.close(); //display_map(wmapp); intas; while (1) { cout<<"请随意输入一个数来创造宋词: (输入0时退出)"< cin>>as; if(as==0)return0; ci(as); cout< cout<<"-----------------------------------------------------------------------------"< cout< } returnfalse; } voidci(inta) { cout<<"如梦令"< map : iteratormap_it; for(inti=0;i<3;i++) { map_it=wmap.begin(); for(intj=0;j<(rand()+a*2)%(wmap.size());j++)map_it++; cout< } cout<<"。 "; for(i=0;i<3;i++) { map_it=wmap.begin(); for(intj=0;j cout< } cout<<"。 "; for(i=0;i<2;i++) { map_it=wmap.begin(); for(intj=0;j cout< } map_it=wmapp.begin(); for(intj=0;j<(rand()+a*3)%(wmapp.size());j++)map_it++; cout< cout<<","; for(i=0;i<3;i++) { map_it=wmap.begin(); for(intj=0;j<(rand()+a)%(wmap.size());j++)map_it++; cout< } cout<<"。 "; map_it=wmap.begin(); for(j=0;j<(2*rand()+a)%(wmap.size());j++)map_it++; stringtemp=map_it->first; cout< "< "; for(i=0;i<3;i++) { map_it=wmap.begin(); for(intj=0;j<(a*rand())%(wmap.size());j++)map_it++; cout< } cout<<"。 "< } voiddisplay_map(map { map : const_iteratormap_it; for(map_it=wmap.begin();map_it! =wmap.end();map_it++) { cout<<"(\""< } } 四.系统演示和分析 (1)截图 ①字统计: ②宋词生成(如梦令): (2)结果分析 五.对次实验的感想、意见和建议 通过此次实验,能熟练利用MAP容器,为接下来的两个实验打好基础。 也能对汉字进行操作,清楚的了解到汉字在计算机中的存储方式有别于字符型。 利用位运算&来和0x80进行比对以区分全角字符和半角字符。 但因为将字作为了map的key值,所以输出的列并不是按照出现频率由大到小,这是可以进行改进的方面。 在宋词生成的程序中,主要是利用随机输入的数字来产生伪随机数,以便利用产生的伪随机数选择不同出现频率的词组来生成宋词。 我觉得可以改进的方面是,在统计时就能用程序自动获取不同词牌名的不同格式,在生成宋词时能选择不同的词牌名以生成不同宋词,使程序更加智能。 实验二人民日报词频统计 一.研究背景 词是自然语言中能够独立运用的最小单位,是自然语言处理的基本单位。 自动词法分析就是利用计算机对自然语言的形态(morphology)进行分析,判断词的结构和类别等。 而词频统计是分词系统的基础和关键,只有在正确、准确、快速的词频统计的情况下才能很好的进行分词算法。 二.实验所采用的开发平台及语言工具 实验在WIN7的环境下利用VC++编程。 三.系统设计 (1)算法基本思想 从文本中字符,判断是否为中文字符(全角字符),若为全角字符则根据需要继续读取,即读取两个或三个字。 利用map容器来存储统计结果。 (2)流程图 (3)代码 #include #include #include #include #include #include usingnamespacestd; //人民日报的词频统计 typedefpair vector voiddisplay_map(map ofstreamofs("c: \\fenciout.txt"); intcmp(constPAIR&x,constPAIR&y)//vector的sort()降序排列 { returnx.second>y.second; } intmain() { cout<<"开始: "< constchar*szInputFileName="c: \\cidian.txt"; ifstreamifs(szInputFileName); stringszTemp; stringstr1,str2,str3,str; chara[100];// map map //统计 while(ifs) { szTemp=""; inti=0; ifs>>a[i];//逐个字符读入 if(ifs.eof()) break; if(! (a[i]&0x80))//非中文 continue; if(! (a[i]&0xB0))//除去空格 { ifs>>a[i]; continue; } while(a[i]! ='/')//读取 { szTemp+=a[i]; i++; ifs>>a[i]; } wmap[szTemp]++;//对应字频加1 } ifs.close(); //map根据value排序 map : const_iteratorcurr; for(curr=wmap.begin();curr! =wmap.end();++curr) { vecpair.push_back(make_pair(curr->first,curr->second)); } sort(vecpair.begin(),vecpair.end(),cmp);//调用排序函数,则vecpair中的first是词,而且降序排列 for(inti=0;i { ofs<<"<"< } display_map(wmap); return; } voiddisplay_map(map { intsum=0; map : const_iteratormap_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<<"(\""< cout<<(double)map_it->second/sum< } } 四.系统演示和分析 (1)截图 排序后: (2)结果分析 五.对次实验的感想、意见和建议 在这次实验后,能含有分词字符的文件进行读取,利用语料来训练程序,并将结果保存在文件当中,以便实验三可以使用。 而且能够进行排序,按照value的值,即词语出现次数由高到低进行排序。 美中不足的是,程序运行速度有待提高。 由于map是按照键值排序的,所以引入了vector,并利用vector的sort函数进行排序,熟悉了这两种容器的使用,提高了对c++库函数的认识。 实验三人民日报分词 一.研究背景 自动词法分析就是利用计算机对自然语言的形态(morphology)进行分析,判断词的结构和类别等。 自动分词是汉语句子分析的基础,而且,词语的分析具有广泛的使用(词频统计,词典编纂,文章风格研究等) 二.模型方法 正向最大匹配算法(ForwardMM,FMM)。 这种算法使得程序简单易行,开发周期短,而且仅需要很少的语言资源(词表),不需要任何词法、句法、语义资源。 三.系统设计 (1)算法基本思想 FMM算法描述: (1)令i=0,当前指针pi指向输入字串的初始位置,执行下面的操作: (2)计算当前指针pi到字串末端的字数(即未被切分字串的长度)n,如果n=1,转(4),结束算法。 否则,令m=词典中最长单词的字数,如果n (3)从当前pi起取m个汉字作为词wi,判断: (a)如果wi确实是词典中的词,则在wi后添加一个切分标志,转(c); (b)如果wi不是词典中的词且wi的长度大于1,将wi从右端去掉一个字,转(a)步;否则(wi的长度等于1),则在wi后添加一个切分标志(单字),执行(c)步; (c)根据wi的长度修改指针pi的位置,如果pi指向字串末端,转(4),否则,i=i+1,返回 (2); (4)输出切分结果,结束分词程序。 (2)流程图 图1.分词流程图 图2.FMM算法流程图 (3)代码 #include #include #include #include #include #include usingnamespacestd; //人民日报的词频统计 typedefpair vector ofstreamofs("c: \\fenciout.txt"); intcmp(constPAIR&x,constPAIR&y) { returnx.second>y.second; } intmain() { cout<<"开始: "< constchar*szInputFileName="c: \\cidian.txt"; ifstreamifs(szInputFileName); stringszTemp; s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 自然语言 理解 实验 报告
![提示](https://static.bingdoc.com/images/bang_tan.gif)