近期,在自学自然语言处理,初次接触NLP觉得十分的难,各种概念和算法,而且也没有很强的编程基础,学着稍微有点吃力。不过经过两个星期的学习,已经掌握了一些简单的中文、英文语料的预处理操作。写点笔记,记录一下学习的过程。
第一点:中文语料中词与词之间是紧密相连的,这一点不同与英文或者其它语种的语料,因此在分词的时候不能像英文使用空格分词,可以jieba库进行分词。第二点:编码问题,中文语料的编码格式是unicode,而不是utf-8编码格式。这里介绍utf-8编码和unicode编码读取的区别,unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节,因此如果不注意编码问题,在处理过程中肯定会出错的。
本次我做的中文语料预处理包含了以下操作:数据导入、数据清洗、中文分词、去停用词、特征处理(TF-IDF权重计算)。下面我将模块介绍我的处理过程。
首先,先准备好本次要使用的数据集,一段摘自腾讯体育新闻中新闻报道,文本保存格式设置为utf-8。然后倒入进python,使用到open函数读取文件,读取格式选择‘r'表示读取文件,编码encoding=’utf-8',查看文件中的内容用read函数。具体编码如下:
#文件读取defread_txt(filepath):file=open(filepath,'r',encoding='utf-8')txt=file.read()returntxt读取结果展示:
(注意:返回的txt是str类型的,即字符串类型,不需要decode。str与bytes表示的是两种数据类型,str为字符串型,bytes为字节型。对str编码encode得到bytes,对bytes解码decode得到str)
新闻文本数据中不仅包括了中文字符,还包括了数字、英文字符、标点等非常规字符,这些都是无意义,并且需要处理的数据。清洗的方法使用的是正则表达式,匹配规则为:[\u4e00-\u9fa5],\un匹配n,其中n是一个用四个十六进制数字表示的Unicode字符,而4e00-9fa5之间的Unicode编码表示的是20000多个中文字符。具体编码如下:
#匹配[^\u4e00-\u9fa5]deffind_chinese(file):pattern=re.compile(r'[^\u4e00-\u9fa5]')chinese_txt=re.sub(pattern,'',file)returnchinese_txt解释:[\u4e00-\u9fa5]表示匹配汉字,[^\u4e00-\u9fa5]表示匹配除汉字以外的所有字符。
分词是中文文本分析的重要内容,正确的分词可以帮助我们更好的构建模型、运用算法分析。中文分词一般使用jieba库中的cut方法,cut方法分词有两种模式,一种为全模式,另一种为精准模式,相较于全模式,精准模式分词更加精准可靠,因此选用精准模式对文本分词。注:精准模式和全模式的区别在于是否cut_all,精准模式选择cut_all=False;全模式选择cut_all=True。Jieba库的安装十分简单,只需要在命令框中输入:pipinstalljieba即可安装。
importjiebatxt='''腾讯体育3月6日讯史蒂芬-库里时隔127天后复出,勇士113-121不敌猛龙。猛龙本场比赛过后,取得44胜18负战绩,锁定季后赛,成为本赛季联盟第2支锁定季后赛的球队,第1支是雄鹿。比赛开始后,库里持球组织进攻,明显改变了猛龙的防守,给克里斯和维金斯创造了轻松得分的机会。但在第一节还剩6分11秒下场时,库里没有得分,2次三分出手全部偏出。但在第二节比赛重新登场后,我们看到了那个熟悉的库里。他接球投三分命中,迎着防守人超远压哨三分命中,第三节还迎着洛瑞完成3+1。那个三分之王和2次常规赛MVP风采依旧。勇士将士就像打不死的小强,从第一节开始就非常顽强,紧紧的咬住比分,甚至伺机反扑。'''#全模式jieba_list=jieba.cut(txt,cut_all=True)jieba_txt1=''.join(jieba_list)print('全模式分词:',jieba_txt1)#精准模式jieba_list=jieba.cut(txt,cut_all=False)jieba_txt2=''.join(jieba_list)print('精准模式分词:',jieba_txt2)通过这段代码我们可以体会一下全模式分词和精准模式分词的区别。
需要注意的一点是jieba分词后返回的数据类型是generator类型,是一个迭代器,需要使用for循环才能读取其中的内容。
处理的算法:
无论是中文中,还是英文中,都有用来起连接作用的连词、虚词、语气词等无意义的词,这些词没有具体的含义,只是起着衔接句子的作用。这些词对文本分析没有任何帮助,因此我们还需要对分词后的数据做停用词处理。进行停用词处理需要停用词表,本文中选用的停用词表为哈工大的停用词表,因为在国内研究自然语言处理他们属于翘楚。
#去除停用词defseg_sentence(list_txt):#读取停用词表stopwords=stopwords=read_txt('哈工大停用词表.txt')seg_txt=[wforwinlist_txtifwnotinstopwords]returnseg_txt去停用词结果:
#词频统计defcounter(txt):seg_list=txtc=Counter()forwinseg_list:ifwisnot'':c[w]+=1returnc统计结果如下所示:
#TF_IDF计算deftf_idf(txt):corpus_txt=[''.join(txt)]stopword_list=read_txt(r'哈工大停用词表.txt').splitlines()vector=TfidfVectorizer(stop_words=stopword_list)tfidf=vector.fit_transform(corpus_txt)print(tfidf)#获取词袋模型中的所有词wordlist=vector.get_feature_names()#tf-idf矩阵元素a[i][j]表示j词在i类文本中的tf-idf权重weightlist=tfidf.toarray()#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重foriinrange(len(weightlist)):print("-------第",i,"段文本的词语tf-idf权重------")forjinrange(len(wordlist)):print(wordlist[j],weightlist[i][j])运行结果:
到此中文文本的预处理就结束了。暂时这两个星期学到的预处理就这么多,如有不当之处,还忘大佬能不吝指导。最后附上全部代码: