ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:55.54KB ,
资源ID:591427      下载积分:5 金币
已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  
下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(《自然语言处理技术》——实训6 中文命名实体识别.docx)为本站会员(极速器)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(发送邮件至doc331@126.com或直接QQ联系客服),我们立即给予删除!

《自然语言处理技术》——实训6 中文命名实体识别.docx

1、目录项目2初识文本基础处理1中文命名实体识别11 实训目标12 实训环境13 实训说明14 实训步骤24.1 COrPUSPrOCeSS类实现文本预处理21 .类定义及初始化22 .语料读写操作33 .标签提取及转换44 .语料初始化55 .语料预处理66 .窗口切分87 .特征提取98 .CorPUSPrOCeSS类重要函数说明104.2 CRF_NER类实现模型训练与模型预测175 实训小结19项目2初识文本基础处理在文命名实体识别1实训目标(1) 掌握使用Sklearn-Crfsuite库进行中文命名实体识别的方法。(2) 熟悉文本预处理流程,包括类定义及初始化、语料读写操作、标签提取及

2、转换、语料初始化、语料预处理、窗口切分、特征提取。(3) 掌握模型训练与预测流程,包括初始化模型参数、定义模型、模型训练、使用模型进行预测。2实训环境环境版本说明Windows1064电脑操作系统Python3.8.5Python语言版本pandas1.3.0主要用于数据读取、清洗等操作NumPy1.21.6主要用于Python中的数值计算jieba0.42.1主要用于文本分词Gensim4.2.0主要用于检索文本、计算文本相似度、训练词向量、建模主题等Matplotlib3.3.0主要用于数据可视化PaddIePaddle2.4.2是一个深度学习框架,提供了高效的计算框架和优化算法Paddl

3、eSpeech1.2.0主要用于语音和音频中的各种关键任务的开发scikit-leam1.0.2广泛地用于统计分析和机器学习建模等数据科学领域Librosa0.8.1主要用于分析一般的音频信号,是一个非常强大的Python语音信号处理的第三方库NLTK3.5是一个常用的自然语言处理工具包,可用于文本处理、语义分析、词性标注等SciPy1.7.3是一个科学计算工具包,可用于数学、科学、工程学等领域pyttsx32.9.0主要用于将文本转换成语音3实训说明使用Skleam-CrfSUite库进行中文命名实体识别,其实现步骤包括文本预处理(类定义及初始化、语料读写操作、标签提取及转换、语料初始化、语

4、料预处理、窗口切分、特征提取)、模型训练与预测(初始化模型参数、定义模型、模型训练、使用模型进行预测)。其中,将实现文本预处理步骤的代码定义为CorpusProcess类,将实现模型训练与预测步骤的代码定义为CRF_NER类,如图3-1所示。文本预处理步骤CorPUSProCeSS类类定义及初始化语料读写操作标签提取及转换模型训练与模型预测CRF_NER类初始化模型参数定义模型语料初始化模型训练语料预处理使用模型进行预测窗口切分特征提取图3-1中文命名实体识别步骤4实训步骤4.1CorpusProcess类实现文本预处理CorpusProcess类主要实现内容包括类定义及初始化、语料读写操作、

5、标签提取及转换、语料初始化、语料预处理、窗口切分以及特征提取。1 .类定义及初始化CorPUSProCeSS类定义及初始化如代码21所示。目前,CorPUSPrOCeSS类还没有做任何实际处理,只是定义了类的结构和初始化属性。后续的方法将在这个类中实现,用于预处理语料、提取特征、切分窗口等操作。代码2-1CorpusProcess类定义及初始化fromskleam_crfsuiteimportmetricsimportjoblib#用于保存和加载模型的库importsklearn_crfsuite#CRF模型库importre#正则表达式库classCorpusProcess(Object):

6、definit_(self):初始化self.train_corpus_path=./data/1980_01rmrb.txtn#训练集语料路径self.process_corpus_path=,.dataresult-rmrb.txt#处理后的语料路径self._maps=ut,:uT,u,nr,:uPER,uns,:u,ORG,u,nt,:u,LOC#定义标记与实体类别的对应关系self.tag_seq=None2 .语料读写操作语料读写操作如代码2-2所示,包括从文件中读取语料和将处理后的语料写入文件这两部分内容。read_COrPUS_from_file函数负责读取文件并返回一个包含文

7、件所有行的列表。write_corpus_to_file函数则将处理后的数据写入指定的文件。代码2-2语料读写操作defread_corpus_from_file(self,file_path):读取语料f=open(file_path,r,encoding=,utf-8,)lines=f.readlines()f.close()returnlinesdefwrite_corpus_to_file(self,data,f!le_path):写语料f=open(file_path,wb)f.write(data)f.close()# 实例化CorpusProcess类corpus_process

8、CorpusProcessO# 读取原始语料文件input_file_path=11.datainput.txtinputjines=corpus_process.read_corpus_from_file(input_file_path)PrintC原始语料为:H,inputjines)# 将处理后的数据写入新文件output_file_path=.tmpOUtPUt.txt”corpus_process.write_corpus_to_file(data=nn,.join(inputJines).encode(utf-8,),file_path=output_file_path)运行数据

9、读取操作代码,得到文件input.txt中的语料如下。原始语料为:ufeff我爱北京天安门W:天安门上太阳升W3.标签提取及转换标签提取及转换如代码2-3所示,不仅根据词性提取对应的实体标签,还将标签转换为BIO(BeginInsideOutside)模式。POS_to_tag函数根据输入的词性P在字典中查找并返回对应的实体标签,若找不到,则返回O(表示非实体)。tag_Perform函数将标签转换为BIo模式,即在实体词组的开头添加前缀,实体词组内部的其他词添加匚前缀,非实体词保持0o代码2-3标签提取及转换#由词性提取标签defpos_to_tag(self,p):#通过self._map

10、s来获取对应的标签t=self._maps.get(p,None)returntiftelse0#标签使用Blo模式deftag_perform(self,tag,index):ifindex=0andtag!=0:# 第一个词的标签为B_TAGreturnB_),.format(tag)eliftag!=0:# 非第一个词的标签为LTAGreturn*I_,.format(tag)else:# 没有实体的标签为Oreturntag#示例句子及其词性标注sentence=”李华/nr“,“在/p“,北京/ns“,“工作/v”#将词性标注转换为实体标签entity_tags=corpus_pro

11、cess.pos_to_tag(word.split(7)1)forwordinsentencePrint(实体标签为:,entity_tags)#将实体标签转换为BIo模式bio_tags=corpus_process.tag_perfbrm(tag,index)forindex,taginenumerate(entity_tags)Print(BIO模式标签为:,bio_tags)运行标签提取与转换代码,得到实体标签以及转换后的Blo模式标签如下。实体标签为:PER,0,ORG,0BIO模式标签为:|BPER,O,L0RG0输出的实体标签PER,OJORG;Orl表示为:第一个词是人名(P

12、ER),第二个词不是实体(0),第三个词是组织名(ORG),第四个词也不是实体(O)。而BIO模式标签B_PER,y,LORGJO则表示为:第一个词是一个人名实体的开始(B_PER),第二个词不是实体(0),第三个词是一个组织名实体的内部部分(LoRG),第四个词也不是实体(0)。4.语料初始化语料初始化如代码2-4所示,首先从文件中读取语料,然后将每行语料切分成单词列表。接着,将语料按词性标注序列和单词序列分开。将词性标注转换成BIO标记,并进行拼接操作。拼接好的标记序列会被扁平化,统一放到一个列表中。最后,将单词序列加上BOS(开始标记)和Ec)S(结束标记),并进行拼接操作。代码2-4语

13、料初始化#语料初始化definitialize(self):# 从文件中读取语料lines=self.read_corpus_from_file(self.process_corpus_path)# 将每行语料切分成单词列表WOrdsist=line.strip().split(,)forlineinlinesifline.strip()# 释放内存dellines# 初始化字、词性、标签序列self.init_sequence(words_list)definit_sequence(self,words_list):# 将语料按词性标注序列和单词序列分开words_seq=word.spli

14、t(,)0forwordinwordsforwordsinwords_listpos_seq=word.split(7)lforwordinwordsforwordsinwordsjist# 将词性标注转换成BIO标记,并进行拼接操作tag_seq=self.pos_to_tag(p)forpinposforposinpos_seqself.tag_seq=self.tag_perform(tag_seqindexi,w)forwinrange(len(words_seqindexi)foriinrange(len(tag_seqindex)forindexinrange(len(tag_se

15、q)# 将拼接好的标记序列扁平化,统一放到个IiSt中self.tag_seq=tfortagintag_seqfortintagfortag_seqinself.tag_seq# 将单词序列加上BOS和EOS,并进行拼接操作self.word_seq=,+wforwordinword_seqforWinword+,forword_seqinwords_seq#窗口统一切分# 返回单词序列和标记序列returnself.word_seq,self.tag_seqline=rr爱v中国/ns”# 将语料行切分成单词列表words=line.strip().split(,)# 将单词和词性分开wo

16、rds_seq=word.split(7)0forwordinwordspos_seq=word.split(7)lforwordinwords# 将词性标注转换成BIO标记tag_seq=corpus_process.pos_to_tag(p)forpinpos_seq# 获取BIO模式标签bio_tag_seq=corpus_process.tag_perform(tag_seqi,i)foriinrange(len(tag_seq)# 添加开始和结束标记word_seq_with_bos_eos=,+words_seq+,# 输出结果Print(词序列:,words_seq)Print(

17、词性序列:,pos_seq)print(BIO标记序列:”,bio_tag_seq)Print(带有开始和结束标记的词序列:,word_seq_with_bos_eos)运行语料初始化代码,从语料行到生成各种序列的过程如下。词序列:我词性序列:,rr爱BIO标记序列:O带有开始和结束标记的词序列:1,我从语料行到生成各种序列结果可以看出,词性序列包含了一个多余的词性“爱”,正确的词性序列应该只有一个元素行1,这可能是因为分词部分的处理不够完善导致的。5 .语料预处理语料预处理如代码2-5所示。虽然代码中包含了一些未实现的预处理函数(如process、ProCeSS_nr、ProCeSS_k和q

18、to_b函数),但是该函数并未对语料产生实际影响,后续(本任务的第小节)将会对预处理函数进行介绍。Pre_ProCeSS函数读取训练集语料文件,对每一行进行处理,然后将处理后的语料写入新的语料文件。代码2-5语料预处理defprocess_t(self,words):passdefprocess_nr(self,words):passdefprocess_k(self,words):passdefq_to_b(self,q_str):passdefpre_process(self):语料预处理lines=self.read_corpus_from_file(self.train_corpus

19、path)new_lines=forlineinlines:words=self.q_to_b(line.strip().split(u)pro_words=self.process_t(words)pro_words=self.process_nr(pro_words)pro_words=self.process_k(pro_words)newjines.append(,.join(pro-words1:)self.write-corpus-to-file(data=n.join(new-lines).encode(,utf-8,),file_path=self.process_corpu

20、s_path)words=李nrJ丽nr在/p一九九七年/t二十二月此十十一日/t/与c张11三mV会面vjpro_words=corpus_process.init_sequence(words)Print(沫预处理的语料:n,words:)PrintC预处理后的语料:11pro_words:)运行语料预处理代码,得到未处理语料和预处理后的语料如下。未预处理的语料:李nr丽nr在p一九九七年t,十二月/t丁三十一日与c,张nr:三nrJ会面v7,w预处理后的语料:(,n,r,W,n,r,p,九,九七,年t,JJ十;二,,月T,VEOS,r,J三十;一1曰,f,与,c,张;n,T,三,n,r,

21、1,会,面,v,w,0,O,O,0,0,O,0,O,0,0,O,0,0,0,0,O,0,O,0,0,O,0,O,0,O,O,0,0,0,O,O,0,O,O,O,0)从预处理后的结果可以看出,未预处理的语料是一个列表,包含了一句话中每个词的词语和词性标注。预处理后的语料是一个元组,其中包含了两个列表,第一个列表是单词序列,包含了每句话中每个词的单词(没有词性标注),并且在每句话的开始和结束位置添加了特殊的词BOS和EOS第二个列表是标记序列,使用BIO标记,每个标记表示该位置上的单词是否属于一个实体。6 .窗口切分窗口切分如代码2-6所示,主要用于通过滑动窗口的方式对词序列进行切分。滑动窗口是一

22、种常见的序列处理技术,它可以帮助捕捉序列中相邻元素之间的局部关系。Segment_by_WindOW函数可以对给定的词语列表进行滑动窗口分割,基本步骤如下。a. 初始化一个空列表WordS来存储分割后的窗口,并初始化窗口的起始位置为begin,结束位置为end。b. 循环切分每一个窗口,并将切分窗口添加到窗口列表中。其中,切分前会检查窗口的结束位置是否超出词语列表的长度,若超出,则跳出循环;否则,将从词语列表中切分出一个窗口,并将其添加到WOrdS列表中。c. 将窗口添加到列表后,需要更新窗口的起始位置和结束位置,使窗口向右滑动一个位置。d. 最后,返回包含所有切分窗口的列表WOrds。代码2

23、6窗口切分defsegment_by_window(self,words_list=None,window=3):Printc原始文本:n,wordsJist)# 初始化切分后的窗口列表words=# 初始化窗口起始位置和结束位置begin,end=0,window# 循环切分每一个窗口for_inrange(1,Ien(WordsJist):# 如果结束位置超出了列表长度,那么跳出循环ifendlen(wordsjist):break# 切分窗口并添加到窗口列表中words.append(wordsjistbegin:end)# 更新起始位置和结束位置begin=begin+1end=en

24、d+1#PrintC分窗文本列表:n,WordsJist)returnwordsinput.wordsjist=我,暧丁自然丁语言处理window_size=3#对词序列进行窗口切分segmented_windows=corpus_process.segment_by_window(words_list=input_words_list,window=window_size)Print(切分后的窗口列表:”,segmented_windows)segment_by_window函数的常用参数说明如表2-1所示。表2-1Segment_by_window函数的常用参数说明参数名称参数说明word

25、s_list接收numpy数组,表示需要进行滑动窗口分割的词语列表。无默认值window接收int,表示滑动窗口的大小,即每个窗口包含的元素数量。默认为3运行窗口切分代码,得到切分后的窗口列表如下。切分后的窗口列表:我,爱自然,爱自然语言自然语言处理I从切分结果可以看出,表示原词序列被切分成了3个大小为3的窗口。7.特征提取特征提取如代码2-7所示。首先,generator函数将字序列按照指定窗口大小切分成n元序歹IJ(Word_grams),然后调用extract_feature函数来提取每个n元序列的特征(extract_feature函数将在本任务的第小节中进行介绍)。最后,genera

26、tor函数返回提取到的特征和对应的标签序列。通过这个过程,可以将原始的字序列转换为适用于训练CRF模型的特征和标签序列。代码2-7特征提取#特征提取defextract_feature(self,word_grams):passdefgenerator(self):# 将字序列切分成n元序列word_grams=self.segment_by.window(Wordist)forword_listinself.word_seq# 提取n元序列的特征features=self.extract_feature(word_grams)# 返回特征和标签序列returnfeatures,self.ta

27、g_seq# 设置词序列corpus_process.word_seq=我,爱自然语言处理# 调用generator函数features=corpus_process.generator()# 输出结果Print(特征序列:nfeatures)运行特征提取代码,针对文本进行特征提取的过程如下。原始文本:W我,爱自然I,r爱,自然语言r自然语言,处理用文本特征:W-1:我,w:爱,w+l:自然我爱w:w+l:爱自然,bias:1.0,w-f:爱JW一自然7w+l:语言,W-1:WT爱自然7w:w+r自然语言bias:l.0),w-l:自然,w:语言,w+l:处理,w-Lw:自然语言,w:w+l:

28、语言处理,bias:1.0)特征序列:(w-:我,w:爱,w+l:自然,w-lW:我爱,w:w+l:爱自然,bias:1.0,w-T:,爱丁W一自然7w+l:语言,w-1W:,爱自然,w:w+l:自然语言,bias:1.0,w-g然沿WT语言w+r:处理7W-1:W1自然语言,w:w+l:语言处理;bias:1.0从特征提取结果可以看出,原始文本是一个三维列表,每个子列表表示一句话,其中每个元素是一个单词。文本特征是一个三维列表,每个子列表表示一句话,其中每个元素是一个字典,表示该单词的特征,包括前一个单词、当前单词、后一个单词、当前单词与前一个单词的组合、当前单词与后一个单词的组合以及偏置项

29、特征序列是一个二维列表,其中每个子列表表示一句话,其中每个元素是一个字典,表示该单词的特征。为此,文本特征和特征序列的内容是一致的。8.CorpusProcess类重要函数说明为了更好的理解CorpusProcess类的框架运行过程,针对重要函数,如q_to_b函数、PrOCeSS_t函数、ProCeSS_nr函数、PrOCeSs_k函数、extracJfeature函数进行说明。(1)q_to_b函数q_to_b函数将输入字符串中的全角字符转换为半角字符。全角字符是指在显示时占据两个半角字符宽度的字符,如全角英文字母、全角数字和全角标点符号。半角字符则仅占用一个标准字符宽度。在处理文本数据

30、时,统一字符格式可以简化后续的文本处理和分析任务。具体来说,q_to_b函数接受一个包含全角字符的字符串q_Str作为输入参数,然后遍历q_Str中的每个字符。如果字符是全角空格(内码为12288),那么将其转换为半角空格(内码为32);如果字符是其他全角字符(内码在6528165374之间),那么将其内码减去65248以得到相应的半角字符。最后,将转换后的半角字符拼接到新字符串b_Str中,并返回b_str。通过q_to_b函数将全角符号转换为半角符号,如代码2-8所示。代码2-8q_to_b函数#全角转半角defq_to_b(self,q_str):#初始化空字符串b_strb_str=#

31、遍历字符串中每个字符forucharinq_str:# 获得字符的内码inside_code=ord(uchar)# 如果字符是全角空格,那么直接转换为半角空格ifinside_code=12288:inside_code=32# 如果字符是全角字符(除空格),那么根据关系转换为半角字符elif65374=inside_code=65281:inside_code-=65248# 将转换后的字符拼接到1_Str中b_str+=chr(inside_code)returnb_strq_str=,w,#使用类的实例调用q_to_b函数Print(,未进行全角转半角:n,q_str)b_str=co

32、rpus_process.q_to_b(q_str)Printe全角转半角:n,b_str)运行q_to_b函数代码,未进行全角转半角数据和全角转半角数据如下。未进行全角转半角:,w全角转半角:,/W从全角转半角数据可以看出,全角逗号(,)被转换为半角逗号(,),全角空格C)被转换为半角空格通过转换全角字符为半角字符,可以使文本更加统一,并减少在后续文本处理和分析过程中可能出现的错误。(2) process_t函数process_t函数合并语料库中被分开标注的时间词,将分散的时间词合并成一个完整的时间表示,有助于简化后续任务。ProCeSs_t函数通过遍历输入的单词列表,并检查每个单词是否包含

33、时间标记。如果当前单词是时间标记,那么函数会将其添加到一个临时变量temp中,并移除标记。当遇到非时间标记的单词时,函数会将临时变量中累积的时间词添加到处理后的单词列表pro_WOrdS中,并将当前单词也添加到该列表。最后,函数返回处理后的单词列表。通过process_t函数将分散时间词进行合并,如代码2-9所示。代码2-9process_t函数defprocess_t(self,words):处理时间,合并语料库分开标注的时间词,类似:(w一九九七年/t十二月/t三十一日/t)/Wpro_words=#初始化处理后的单词列表index=0#初始化单词位置temp=uu#初始化临时变量whil

34、eTrue:word=wordsindexifindexlen(words)elseu#获取当前单词,如果已经遍历完了,那么设置为空字符串ifu7t,inword:#判断当前单词是时间标记temp=temp.replace(u,t,u,1)+word#将当前单词中的标记替换成空字符串,然后添加到临时变量中eliftemp:#判断临时变量不为空pro_words.append(temp)#将临时变量中的时间标记添加到处理后的单词列表中pro-words.append(word)#将当前单词添加到处理后的单词列表中temp=u,#将临时变量清空elifword:#判断当前单词不为空pro_word

35、s.append(word)#直接将当前单词添加到处理后的单词列表中else:#break#跳出循环index+=1#更新单词位置returnpro_words#返回处理后的单词列表words=(w,一九九七年t,十二月/t,三H一日化)/WrIpro_words=corpus_process.process_t(words)PrintC未处理时间数据:n,words:)PrintC处理时间后的数据:n,pro_words:)运行process_t函数代码,输出未处理时间数据和处理时间后的数据如下。未处理时间数据:(/w一九九七年t,十二月tJ三T-日t,)w处理时间后的数据:(w,一九九七年

36、十二月三!-日t,)w从处理前后的时间数据中可以看出,处理时间数据后的列表显示了将分开的时间词语合并成一个完整时间,即一九九七年/L,十二月和三十一日被合并成了一九九七年十二月三十一日/t。这个处理过程有助于更准确地识别和表示文本中的时间信息,从而在进行时间实体识别、事件抽取或其他与时间相关的任务时,提高模型的准确性和效果。(3) process_nr函数ProCeSSJr函数合并语料库中分开标注的姓和名。在进行文本处理和分析时,将姓和名合并成一个完整的姓名,有助于简化后续任务。process-nr函数通过遍历输入的单词列表,并检查每个单词是否包含姓名标记。如果当前单词是姓名标记,那么函数会检

37、查下一个单词是否也是姓名标记。如果下一个单词也是姓名标记,那么函数会将两个姓名标记合并成一个完整的姓名。否则,函数会保留当前的姓名标记。最后,函数返回处理后的单词列表。通过process_nr函数将分开的姓与名进行合并,如代码2-10所示。代码2-10process-nr函数defprocess_nr(self,words):处理姓名,合并语料库分开标注的姓和名心”pro-words=#用于存储处理后的词语列表index=0#当前正在处理的词语在列表中的索引whileTrue:#获取当前词语(如果有)或空字符串word=wordsindexifindexlen(words)elseuifu7n

38、rinword:#如果当前词语标注为“人名”(nr)nextjndex=index+1ifnext_indexlen(words)andu7nrinwordsnext_index:#如果下一个词语也是人名,那么将两个词语合并成一个pro_words.append(word.replace(u7nru)+wordsnextjndex)index=nextjndex#将索引设置为下一个词语的位置else:#如果下一个词语不是人名,那么只保留当前词语,去掉标注pro_words.append(word.replace(u7nrun)elifword:#如果当前词语不是人名且不为空,那么直接添加到处理

39、后的列表中pro_words.append(word)else:#如果当前词语为空字符串,那么说明已经处理完了所有词语,退出循环breakindex+=1#处理下一个词语returnpro_wordswords=张/m丁三/m丁在p,公司工作v1pro_words=corpus_process.process_nr(words)Print(未处理姓名数据:n1,words:)Printe处理姓名后的数据:npro_words:)运行processor函数代码,输出未处理姓名数据和处理姓名后的数据如下。未处理姓名数据:张nr三/nr;在p,公司nJ工作v1处理姓名后的数据:张三/nr;在pJ公司

40、nJ工作/V从输出结果中可以看出,处理姓名数据后的列表显示了将分开的姓名词语合并成一个完整姓名,即张/和三/nF被合并成眯三nr这个处理过程有助于更准确地识别和表示文本中的姓名,从而在进行命名实体识别、关系抽取或其他与人名相关的任务时,提高模型的准确性和效果。(4) ProCeSs_k函数process.k函数处理大粒度分词,合并语料库中括号的大粒度分词。在分词任务中,有时会遇到需要将多个连续的分词合并为一个实体的情况。process_k函数用于处理这类情况,将括号内的词组合并成一个整体。PrOCeSS_k函数通过遍历输入的单词列表,并检查每个单词是否包含左括号“”或右括号如果遇到左括号,那么

41、函数将开始合并括号内的词语,去除词性标注,并将它们添加到一个临时变量temp中。当遇到右括号时,函数会将括号内的词语和右括号后面的词性标注合并成一个新词语,并添加到处理后的单词列表Pro_words中。如果遇到的单词不属于大粒度分词,那么直接添加到处理后的单词列表中。通过process_k函数处理大粒度分词,如代码2-11所示。代码2-11process.k函数defprocess_k(self,words):处理大粒度分词,合并语料库中括号的大粒度分词,类似:国家/n环保局nntpro-words=#用于存储处理后的词语列表index=0#当前正在处理的词语在列表中的索引temp=uu#用于

42、暂时存储括号中的大粒度分词whileTrue:#获取当前词语(如果有)或空字符串word=wordsindexifindexlen(words)elseu11ifu,inword:#如果当前词语包含左括号,那么说明遇到了一个大粒度分词# 去掉左括号和词性标注,并添加到暂存字符串中temp+=re.sub(pattcrn=u7a-zA-Z*repl=u,string=word.rcplace(uIr)elifuinword:#如果当前词语包含右括号,那么说明大粒度分词已经结束# 将当前词语分成两部分,去掉右括号后面的词性标注w=WOrd.split(uT)# 去掉左括号和词性标注,并添加到暂存字

43、符串中temp+=re.sub(pattern=u7a-zA-Z*,repl=un,string=wO)#将括号中的大粒度分词和右括号后面的词性标注合并成一个新词语,并添加到处理后的列表中pro-words.append(temp+u7,+w1)# 清空暂存字符串temp=Ireliftcmp:#若暂存字符串中有内容,则说明当前词语属于大粒度分词中的一个子词语# 去掉词性标注,并添加到暂存字符串中temp+=re.sub(pattern=ua-zA-Z*,repl=u,string=word)elifword:#若当前词语不属于大粒度分词,也不是空字符串,则直接添加到处理后的列表中pro_words.append(word)else:#若当前词语是空字符串,则说明已经处理完了所有词语,退出循环breakindex+=1#处理下一个词语returnpro_wordswords=上海ns丁浦东nsns浦是材J中国ns7最大/J的丁城市/n丁之一fj,w丁中国ns丁环境监测vn丁总站nnk位于v这里丁。pro_words=corpus_process.process_k(words)Pr

宁ICP备18001539号-1