自然语言理解实验报告.docx
- 文档编号:5058943
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:15
- 大小:146.67KB
自然语言理解实验报告.docx
《自然语言理解实验报告.docx》由会员分享,可在线阅读,更多相关《自然语言理解实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
自然语言理解实验报告
自然语言理解课程
实验报告
实验一、中文分词
1、实验内容
用最大匹配算法设计分词程序实现对文档分词,并计算该程序分词的正确率、召回率及F-测度。
实验数据:
(1)wordlist.txt词表文件
(2)pku_test.txt未经过分词的文档文件
(3)pku_test_gold.txt经过分词的文档文件
2、实验所采用的开发平台及语言工具
开发平台:
Eclipse软件
语言工具:
Java语言
3、实验的核心思想和算法描述
核心思想:
正向最大匹配算法(ForwardMM,FMM)
算法描述:
正向最大匹配法算法如下所示:
逆向匹配法思想与正向一样,只是从右向左切分,这里举一个例子:
输入例句:
S1="计算语言学课程有意思";
定义:
最大词长MaxLen=5;S2="";分隔符=“/”;
假设存在词表:
…,计算语言学,课程,意思,…;
最大逆向匹配分词算法过程如下:
(1)S2="";S1不为空,从S1右边取出候选子串W="课程有意思";
(2)查词表,W不在词表中,将W最左边一个字去掉,得到W="程有意思";
(3)查词表,W不在词表中,将W最左边一个字去掉,得到W="有意思";
(4)查词表,W不在词表中,将W最左边一个字去掉,得到W="意思"
(5)查词表,“意思”在词表中,将W加入到S2中,S2="意思/",并将W从S1中去掉,此时S1="计算语言学课程有";
(6)S1不为空,于是从S1左边取出候选子串W="言学课程有";
(7)查词表,W不在词表中,将W最左边一个字去掉,得到W="学课程有";
(8)查词表,W不在词表中,将W最左边一个字去掉,得到W="课程有";
(9)查词表,W不在词表中,将W最左边一个字去掉,得到W="程有";
(10)查词表,W不在词表中,将W最左边一个字去掉,得到W="有",这W是单字,将W加入到S2中,S2=“/有/意思”,并将W从S1中去掉,此时S1="计算语言学课程";
(11)S1不为空,于是从S1左边取出候选子串W="语言学课程";
(12)查词表,W不在词表中,将W最左边一个字去掉,得到W="言学课程";
(13)查词表,W不在词表中,将W最左边一个字去掉,得到W="学课程";
(14)查词表,W不在词表中,将W最左边一个字去掉,得到W="课程";
(15)查词表,“意思”在词表中,将W加入到S2中,S2=“课程/有/意思/”,并将W从S1中去掉,此时S1="计算语言学";
(16)S1不为空,于是从S1左边取出候选子串W="计算语言学";
(17)查词表,“计算语言学”在词表中,将W加入到S2中,S2=“计算语言学/课程/有/意思/”,并将W从S1中去掉,此时S1="";
(18)S1为空,输出S2作为分词结果,分词过程结束。
4、系统主要模块流程、源代码
importjava.io.*;
importjava.util.Vector;
publicclassWordSequence{
publicstaticvoidmain(Stringargs[]){
try{
FileInputStreamfis=newFileInputStream("F:
\\pku_test.txt");
InputStreamReaderSR=newInputStreamReader(fis);
BufferedReaderBR=newBufferedReader(SR);
Stringpku="";
while((pku=BR.readLine())!
=null){
Sequencepku_test=newSequence(pku);
System.out.println("");
}
}catch(IOExceptione){
System.out.print(e);
}
}
}
classSequence{
staticfinalintWORD_MAX_LENGTH=9;
staticVectorve=newVector();
FileWriterFW=newFileWriter("F:
\\mypuk_test.txt",true);
Stringseq=null;
publicSequence(Stringstr)throwsIOException{
classLoadDictionary{
publicLoadDictionary(FileReaderreader)throwsIOException{
BufferedReaderstream=newBufferedReader(reader);
StringLD=null;
while((LD=stream.readLine())!
=null){ve.add(LD);
}
}
}
FileReaderlist=newFileReader("F:
\\wordlist.txt");
LoadDictionaryDic=newLoadDictionary(list);
intnum=str.length();
if(num<=WORD_MAX_LENGTH){
inti,j=0;
while(j for(i=0;i+j seq=str.substring(j,num-i); if(ve.contains(seq)||(num-i-j==1)) {System.out.print(seq+""); FW.write(seq+""); j+=num-i-j; break; } } } } else{inti,j=0; while(num-j>=WORD_MAX_LENGTH){ i=j+WORD_MAX_LENGTH; for(;i>j;i--){ seq=str.substring(j,i); if(ve.contains(seq)||(i-j==1)) {System.out.print(seq+""); FW.write(seq+""); j=i; break; } } } while(j for(i=0;i+j seq=str.substring(j,num-i); if(ve.contains(seq)||(num-i-j==1)) {System.out.print(seq+""); FW.write(seq+""); j+=num-i-j; break; } } } } } } 程序说明: 程序由两个类组成,公共类WordSequence和类Sequence,类Sequence主要实现对一个字符串进行分词。 思路是: 首先,把词表中的词存储在一个Vector对象中,这一步很关键。 因为Vector类中提供了一个contains函数可以方便的判断词表中是否有所对照的字符串。 起初,我也尝试了直接用一个字符串数组存储词表中的字符串,但后来发现特别不方便。 然后,根据字符串的长短对其按照正向最大匹配法进行处理。 最后,在main()方法中,定义一个文件字符流,利用readLine()函数没读一行,声明一个Sequence对象,对这行字符串进行处理。 具体程序见上。 5.实验结果及分析 实验结果: 实验分析: 从上述结果可以看出,基本上程序输出的结果是正确的,只有少数词存在一些误差。 而这些误差对于这个算法是完全允许的。 比如“他是研究生物化学的。 ”输出结果为“他/是/研究生/物化/学/的/。 ”可见,正向最大匹配法并不能做到完美。 有时逆向最大匹配法会比正向最大匹配法四处结果要好很多。 实验二、分词与词性标注系统ICTCLAS 1.实验内容 实验数据: pku_test.txt未经过分词的文档文件 调用ICTCLAS程序对其中的文档进行分词 2.实验所采用的开发平台及语言工具 开发平台: ICTCLAS50_Windows_64_JNI、eclipse软件 语言工具: Java语言 3.系统主要模块流程、源代码 importICTCLAS.I3S.AC.ICTCLAS50; importjava.util.*; importjava.io.*; publicclassWS{ publicstaticvoidmain(String[]args) { try { ICTCLAS50testICTCLAS50=newICTCLAS50(); //分词所需库的路径 Stringargu="."; //初始化 if(testICTCLAS50.ICTCLAS_Init(argu.getBytes("GB2312"))==false) { System.out.println("InitFail! "); return; } //输入文件名 StringInputfilename="F: \\pku_test.txt"; byte[]Inputfilenameb=Inputfilename.getBytes(); //分词处理后输出文件名 StringOutputfilename="F: \\test_result.txt"; byte[]Outputfilenameb=Outputfilename.getBytes(); //文件分词(第一个参数为输入文件的名,第二个参数为文件编码类型,第三个参数为是否标记词性集1yes,0no,第四个参数为输出文件名) testICTCLAS50.ICTCLAS_FileProcess(Inputfilenameb,2,2,Outputfilenameb); }catch(Exceptionex) { } } } 程序说明: 本程序通过调用ICTCLAS系统来实现对字符串分词并加标注。 程序的实现很简单,只是声明一个ICTCLAS50对象并初始化,然后调用其中的ICTCLAS_FileProcess函数即可实现对F: \\pku_test.txt文件进行分词并加标注。 在调用ICTCLAS系统时普遍说总是编译出错并提示找不到文件。 问题就是出在“Stringargu=".";”,“.”表示出当前目录中查找文件。 虽然可以直接用绝对路径,但初学者常常在这犯错。 最简便的方法就是直接把java源程序的目录设在“C: \Users\dell\Desktop\ICTCLAS50_Windows_64_JNI\API”。 这样就可以编译通过并输出结果,存储在F: \\test_result.txt 5.实验结果及分析 实验结果: (限于篇幅,仅取开头的一段) 共同/d创造/v美好/a的/ude1新/a世纪/n——/wp二/m○/w○/w一年/m新年/t贺词/n (/wkz二/m○/w○/w○/w年/n十二月/t三十一日/t)/wky(/wkz附/v图片/n1/a张/q)/wky 女士/n们/k,/wd先生/n们/k,/wd同志/n们/k,/wd朋友/n们/k: /wm 2001年/m新年/t钟声/n即将/d敲响/v。 /wj人类/n社会/n前进/vi的/ude1航船/n就要/d驶入/v21/m世纪/n的/ude1新/a航程/n。 /wj中国/ns人民/n进入/v了/ule向/p现代化/vn建设/vn第三/m步/qv战略/n目标/n迈进/vi的/ude1新/a征程/n。 /wj 在/p这个/rz激动人心/bl的/ude1时刻/n,/wd我/rr很/d高兴/a通过/p中国/ns国际/n广播电台/n、/wn中央人民广播电台/nt和/cc中央电视台/nt,/wd向/p全国/n各族/rz人民/n,/wd向/p香港特别行政区/ns同胞/n、/wn澳门特别行政区/ns同胞/n和/cc台湾/ns同胞/n、/wn海外/s侨胞/n,/wd向/p世界/n各国/rzs的/ude1朋友/n们/k,/wd致以/v新/a世纪/n第一/m个/q新年/t的/ude1祝贺/vn! /wt 结果分析: 从运行结果可以看出,结果应该是非常准确的。 而且在实际运行时可以发现运行速度特别快。 在实验一中我们编的程序运行完要好几分钟,而这个程序只需不到10秒。 可能其中的算法比较便捷。 实验三、基于语言模型的音字转换 1.实验内容 设计一个基于语言模型的音字转换系统,根据拼音 实验数据: pku_test_gold.txt经过分词的文档文件 2.实验所采用的开发平台及语言工具 开发平台: Eclipse软件 语言工具: Java语言 3.实验的核心思想和算法描述 给定拼音串: jinjitizhigaige 可能的汉字串: 紧济体质改革 经济体质改革 经济体制改革 使用2-gram计算: p(CString1)=p(紧)×p(济|紧)×p(体质|济)×p(改革|体质)× p(CString2)=p(经济)×p(体质|经济)×p(改革|体质) p(CString3)=p(经济)×p(体制|经济)×p(改革|体制) 比较p(CString1),p(CString2),p(CString3) 4.系统主要模块流程、源代码 importjava.io.*; importjava.util.Vector; publicclassWordSequence{ publicstaticvoidmain(Stringargs[]){ try{ Stringpku1="紧济体质改革"; Sequencepku_test1=newSequence(pku1); Stringpku2="经济体质改革"; Sequencepku_test2=newSequence(pku2); Stringpku3="经济体制改革"; Sequencepku_test3=newSequence(pku3); }catch(IOExceptione){ System.out.print(e); } } } classSequence{ staticfinalintWORD_MAX_LENGTH=9; doubleT_test=1.00000000; staticVectorve=newVector(); Stringseq=null; publicSequence(Stringstr)throwsIOException{ classLoadDictionary{ publicLoadDictionary(FileReaderreader)throwsIOException{ BufferedReaderstream=newBufferedReader(reader); StringLD=null; while((LD=stream.readLine())! =null){ve.add(LD); } } } FileReaderlist=newFileReader("F: \\wordlist.txt"); LoadDictionaryDic=newLoadDictionary(list); intnum=str.length(); Stringfenci[]=newString[6]; intk=0; if(num<=WORD_MAX_LENGTH){ inti,j=0; while(j for(i=0;i+j seq=str.substring(j,num-i); if(ve.contains(seq)||(num-i-j==1)) {System.out.print(seq+""); fenci[k]=seq; k++; j+=num-i-j; break; } } } } else{inti,j=0; while(num-j>=WORD_MAX_LENGTH){ i=j+WORD_MAX_LENGTH; for(;i>j;i--){ seq=str.substring(j,i); if(ve.contains(seq)||(i-j==1)) {System.out.print(seq+""); j=i; break; } } } while(j for(i=0;i+j seq=str.substring(j,num-i); if(ve.contains(seq)||(num-i-j==1)) {System.out.print(seq+""); j+=num-i-j; break; } } } } FileReaderFder=newFileReader("F: \\pku_test_gold.txt"); BufferedReaderBR=newBufferedReader(Fder); StringstrInfo=""; Stringpuk=""; while((puk=BR.readLine())! =null){strInfo+=puk;} StringstrSplit="/"; String[]a=dong_split(strInfo,strSplit); System.out.println(a.length); intchk=0,cnk=a.length; for(k=1;k<6;k++){ if(fenci[k]! =null){ System.out.println("fenci["+k+"]: "+fenci[k]); if(k==1){chk=0; for(intn=0;n if(a[n].equals(fenci[k])){ chk++; } } } else{chk=0; for(intn=1;n if((a[n].equals(fenci[k]))&&(a[n-1].equals(fenci[k-1]))){ chk++; } } } System.out.println(chk); if(chk==0){T_test=0; break;}else{ T_test*=(double)chk/cnk; cnk=chk;} } } System.out.println("T_test="+T_test); } publicstaticString[]dong_split(StringstrInfo,StringstrSplit){ intsize=1; for(intk=0;k if(strInfo.substring(k,k+1)! =null&&(strInfo.substring(k,k+1)).equals("/")){ size++; } } String[]arrRtn=newString[size]; StringstrTemp=""; intlen=strInfo.length(); intindex=0; inti=0; while(len>1){ index=strInfo.indexOf(strSplit); if(index>0){ strTemp=strInfo.substring(0,index); strInfo=strInfo.substring(index+1); arrRtn[i++]=strTemp; }elseif(index==0){ strInfo=strInfo.substring(index+1); arrRtn[i++]=""; }else{ break; } len=strInfo.length(); } index=strInfo.indexOf(strSplit); if(index==0){ arrRtn[i++]=""; arrRtn[i]=""; }else{ arrRtn[i]=strInfo; } returnarrRtn; } } 程序说明: 在整个程序的编写中,我的思路就是把pku_test_gold.txt文件中每一个句子中的分词字符串存储在一个字符串数组中,然后通过与所找字符串比对,并计数。 想法很简单,但实际实施的时候遇到了些问题—怎么把文件中的分词字符串分出来。 起初我想到用java的split函数,但其中转义字符理解的不是很好。 后来就没用,而是用了一个改写的split函数实现了分词并存储。 例如”钓鱼岛/是/中国/的/国土主权/不容侵犯/”输出结果为“a[0]: 钓鱼岛a[1]: 是a[2]: 中国a[3]: 的a[4]: 国土主权a[5]: 不容侵犯”。 然后,按照2-gram法就可以输出结果。 具体实现方法如上所示。 5.实验结果及分析 紧济体质改革104372 fenci[1]: 紧 6 fenci[2]: 济 0 T_test=0.0 经济体质改革104372 fenci[1]: 经济 238 fenci[2]: 体质 0 T_test=0.0 经济体制改革104372 fenci[1]:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 自然语言 理解 实验 报告