自然语言理解实验报告.docx

上传人:b****0 文档编号:17460976 上传时间:2023-07-25 格式:DOCX 页数:30 大小:757.48KB
下载 相关 举报
自然语言理解实验报告.docx_第1页
第1页 / 共30页
自然语言理解实验报告.docx_第2页
第2页 / 共30页
自然语言理解实验报告.docx_第3页
第3页 / 共30页
自然语言理解实验报告.docx_第4页
第4页 / 共30页
自然语言理解实验报告.docx_第5页
第5页 / 共30页
自然语言理解实验报告.docx_第6页
第6页 / 共30页
自然语言理解实验报告.docx_第7页
第7页 / 共30页
自然语言理解实验报告.docx_第8页
第8页 / 共30页
自然语言理解实验报告.docx_第9页
第9页 / 共30页
自然语言理解实验报告.docx_第10页
第10页 / 共30页
自然语言理解实验报告.docx_第11页
第11页 / 共30页
自然语言理解实验报告.docx_第12页
第12页 / 共30页
自然语言理解实验报告.docx_第13页
第13页 / 共30页
自然语言理解实验报告.docx_第14页
第14页 / 共30页
自然语言理解实验报告.docx_第15页
第15页 / 共30页
自然语言理解实验报告.docx_第16页
第16页 / 共30页
自然语言理解实验报告.docx_第17页
第17页 / 共30页
自然语言理解实验报告.docx_第18页
第18页 / 共30页
自然语言理解实验报告.docx_第19页
第19页 / 共30页
自然语言理解实验报告.docx_第20页
第20页 / 共30页
亲,该文档总共30页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

自然语言理解实验报告.docx

《自然语言理解实验报告.docx》由会员分享,可在线阅读,更多相关《自然语言理解实验报告.docx(30页珍藏版)》请在冰点文库上搜索。

自然语言理解实验报告.docx

自然语言理解实验报告

分词系统工程报告

课程:

自然语言理解

姓名:

王佳淼

学号:

2011914

班级:

信息安全11-1

日期:

2013-11-2

实验一宋词字统计

一.研究背景

本实验所涉及的研究背景是利用计算机来“鉴赏”宋词。

主要针对宋词这种特殊的汉语诗歌体裁,开展了有关自动生成算法及其实现方法的探索性研究。

通过对大量语料的学习,来自动生成宋词。

由于宋词自身的特性,能够在经过大量预料学习后,利用在宋词当中出现频率较高的词语或者单字排列组合来生成宋词。

二.实验所采用的开发平台及语言工具

实验在WIN7的环境下利用VC++编程。

三.系统设计

(1)算法基本思想

从文本中字符,判断是否为中文字符(全角字符),若为全角字符则根据需要继续读取,即读取两个或三个字。

利用map容器来存储统计结果。

(2)流程图

(3)代码

①字统计

#include

#include

#include

#include

usingnamespacestd;

//宋词的统计

voiddisplay_map(map&wmap);

ofstreamofs("c:

\\fenciout2.txt");

intmain()

{

cout<<"开始:

"<

constchar*szInputFileName="c:

\\Text.txt";

ifstreamifs(szInputFileName);

stringszTemp;

stringstr1,str2,str3,str;

chara[10];//

mapwmap;

//统计双字的

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&wmap)

{

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<<"(\""<first<<"\","<second<<")";

cout<<(double)map_it->second/(sum-1)<

}

for(map_it=wmap.begin();map_it!

=wmap.end();map_it++)//计算词频

{

ofs<<"(\""<first<<"\","<second<<")";

ofs<<(double)map_it->second/sum<

}

}

②宋词生成

#include

#include

#include

#include

usingnamespacestd;

voiddisplay_map(map&wmap);

voidci(inta);

mapwmap;

mapwmapp;

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<first;

}

cout<<"。

";

for(i=0;i<3;i++)

{

map_it=wmap.begin();

for(intj=0;j

cout<first;

}

cout<<"。

";

for(i=0;i<2;i++)

{

map_it=wmap.begin();

for(intj=0;j

cout<first;

}

map_it=wmapp.begin();

for(intj=0;j<(rand()+a*3)%(wmapp.size());j++)map_it++;

cout<first;

cout<<",";

for(i=0;i<3;i++)

{

map_it=wmap.begin();

for(intj=0;j<(rand()+a)%(wmap.size());j++)map_it++;

cout<first;

}

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<first;

}

cout<<"。

"<

}

voiddisplay_map(map&wmap)

{

map:

:

const_iteratormap_it;

for(map_it=wmap.begin();map_it!

=wmap.end();map_it++)

{

cout<<"(\""<first<<"\","<second<<")"<

}

}

四.系统演示和分析

(1)截图

①字统计:

②宋词生成(如梦令):

(2)结果分析

五.对次实验的感想、意见和建议

通过此次实验,能熟练利用MAP容器,为接下来的两个实验打好基础。

也能对汉字进行操作,清楚的了解到汉字在计算机中的存储方式有别于字符型。

利用位运算&来和0x80进行比对以区分全角字符和半角字符。

但因为将字作为了map的key值,所以输出的列并不是按照出现频率由大到小,这是可以进行改进的方面。

在宋词生成的程序中,主要是利用随机输入的数字来产生伪随机数,以便利用产生的伪随机数选择不同出现频率的词组来生成宋词。

我觉得可以改进的方面是,在统计时就能用程序自动获取不同词牌名的不同格式,在生成宋词时能选择不同的词牌名以生成不同宋词,使程序更加智能。

实验二人民日报词频统计

一.研究背景

词是自然语言中能够独立运用的最小单位,是自然语言处理的基本单位。

自动词法分析就是利用计算机对自然语言的形态(morphology)进行分析,判断词的结构和类别等。

而词频统计是分词系统的基础和关键,只有在正确、准确、快速的词频统计的情况下才能很好的进行分词算法。

二.实验所采用的开发平台及语言工具

实验在WIN7的环境下利用VC++编程。

三.系统设计

(1)算法基本思想

从文本中字符,判断是否为中文字符(全角字符),若为全角字符则根据需要继续读取,即读取两个或三个字。

利用map容器来存储统计结果。

(2)流程图

(3)代码

#include

#include

#include

#include

#include

#include

usingnamespacestd;

//人民日报的词频统计

typedefpairPAIR;

vectorvecpair;

voiddisplay_map(map&wmap);

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];//

mapwmap;

mapwmapok;

//统计

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&wmap)

{

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<<"(\""<first<<"\","<second<<")";

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;

//人民日报的词频统计

typedefpairPAIR;

vectorvecpair;

ofstreamofs("c:

\\fenciout.txt");

intcmp(constPAIR&x,constPAIR&y)

{

returnx.second>y.second;

}

intmain()

{

cout<<"开始:

"<

constchar*szInputFileName="c:

\\cidian.txt";

ifstreamifs(szInputFileName);

stringszTemp;

s

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2