中文文本挖掘预处理流程总结

    在对文本作数据分析时,咱们一大半的时间都会花在文本预处理上,而中文和英文的预处理流程稍有不一样,本文就对中文文本挖掘的预处理流程作一个总结。html

1. 中文文本挖掘预处理特色

    首先咱们看看中文文本挖掘预处理和英文文本挖掘预处理相比的一些特殊点。git

    首先,中文文本是没有像英文的单词空格那样隔开的,所以不能直接像英文同样能够直接用最简单的空格和标点符号完成分词。因此通常咱们须要用分词算法来完成分词,在文本挖掘的分词原理中,咱们已经讲到了中文的分词原理,这里就很少说。github

    第二,中文的编码不是utf8,而是unicode。这样会致使在分词的时候,和英文相比,咱们要处理编码的问题。正则表达式

    这两点构成了中文分词相比英文分词的一些不一样点,后面咱们也会重点讲述这部分的处理。固然,英文分词也有本身的烦恼,这个咱们在之后再讲。了解了中文预处理的一些特色后,咱们就言归正传,经过实践总结下中文文本挖掘预处理流程。算法

2.  中文文本挖掘预处理一:数据收集

    在文本挖掘以前,咱们须要获得文本数据,文本数据的获取方法通常有两种:使用别人作好的语料库和本身用爬虫去在网上去爬本身的语料数据。数组

    对于第一种方法,经常使用的文本语料库在网上有不少,若是你们只是学习,则能够直接下载下来使用,但若是是某些特殊主题的语料库,好比“机器学习”相关的语料库,则这种方法行不通,须要咱们本身用第二种方法去获取。机器学习

    对于第二种使用爬虫的方法,开源工具备不少,通用的爬虫我通常使用beautifulsoup。可是咱们咱们须要某些特殊的语料数据,好比上面提到的“机器学习”相关的语料库,则须要用主题爬虫(也叫聚焦爬虫)来完成。这个我通常使用ache。 ache容许咱们用关键字或者一个分类算法来过滤出咱们须要的主题语料,比较强大。工具

3.  中文文本挖掘预处理二:除去数据中非文本部分

    这一步主要是针对咱们用爬虫收集的语料数据,因为爬下来的内容中有不少html的一些标签,须要去掉。少许的非文本内容的能够直接用Python的正则表达式(re)删除, 复杂的则能够用beautifulsoup来去除。去除掉这些非文本的内容后,咱们就能够进行真正的文本预处理了。post

4. 中文文本挖掘预处理三:处理中文编码问题

    因为Python2不支持unicode的处理,所以咱们使用Python2作中文文本预处理时须要遵循的原则是,存储数据都用utf8,读出来进行中文相关处理时,使用GBK之类的中文编码,在下面一节的分词时,咱们再用例子说明这个问题。学习

5. 中文文本挖掘预处理四:中文分词

    经常使用的中文分词软件有不少,我的比较推荐结巴分词。安装也很简单,好比基于Python的,用"pip install jieba"就能够完成。下面咱们就用例子来看看如何中文分词。

    完整代码参见个人github: https://github.com/ljpzzz/machinelearning/blob/master/natural-language-processing/chinese_digging.ipynb

    首先咱们准备了两段文本,这两段文本在两个文件中。两段文本的内容分别是nlp_test0.txt和nlp_test2.txt:

          沙瑞金赞叹易学习的胸怀,是金山的百姓有福,但是这件事对李达康的触动很大。易学习又回忆起他们三人分开的前一晚,你们一块儿喝酒话别,易学习被降职到道口县当县长,王大路下海经商,李达康连连赔礼道歉,以为对不起你们,他最对不起的是王大路,就和易学习一块儿给王大路凑了5万块钱,王大路本身东挪西撮了5万块,开始下海经商。没想到后来王大路居然作得风生水起。沙瑞金以为他们三人,在困难时期还能以沫相助,很不容易。

    沙瑞金向毛娅打听他们家在京州的别墅,毛娅笑着说,王大路事业有成以后,要给欧阳菁和她公司的股权,她们没有要,王大路就在京州帝豪园买了三套别墅,但是李达康和易学习都不要,这些房子都在王大路的名下,欧阳菁好像去住过,毛娅不想去,她以为房子太大很浪费,本身家住得就很踏实。

   咱们先讲文本从第一个文件中读取,并使用中文GBK编码,再调用结巴分词,最后把分词结果用uft8格式存在另外一个文本nlp_test1.txt

中。代码以下:

# -*- coding: utf-8 -*-

import jieba

with open('./nlp_test0.txt') as f:
    document = f.read()
    
    document_decode = document.decode('GBK')
    document_cut = jieba.cut(document_decode)
    #print  ' '.join(jieba_cut)  //若是打印结果,则分词效果消失,后面的result没法显示
    result = ' '.join(document_cut)
    result = result.encode('utf-8')
    with open('./nlp_test1.txt', 'w') as f2:
        f2.write(result)
f.close()
f2.close()

    输出的文本内容以下:

    沙 瑞金 赞叹 易 学习 的 胸怀 , 是 金山 的 百姓 有福 , 但是 这件 事对 李达康 的 触动 很大 。 易 学习 又 回忆起 他们 三人 分开 的 前一晚 , 你们 一块儿 喝酒 话别 , 易 学习 被 降职 到 道口 县当 县长 , 王 大路 下海经商 , 李达康 连连 赔礼道歉 , 以为 对不起 你们 , 他 最 对不起 的 是 王 大路 , 就 和 易 学习 一块儿 给 王 大路 凑 了 5 万块 钱 , 王 大路 本身 东挪西撮 了 5 万块 , 开始 下海经商 。 没想到 后来 王 大路 居然 作 得 风生水 起 。 沙 瑞金 以为 他们 三人 , 在 困难 时期 还 能 以沫 相助 , 很 不 容易 。

    能够发现对于一些人名和地名,jieba处理的很差,不过咱们能够帮jieba加入词汇以下:

jieba.suggest_freq('沙瑞金', True)
jieba.suggest_freq('易学习', True)
jieba.suggest_freq('王大路', True)
jieba.suggest_freq('京州', True)

    如今咱们再来进行读文件,编码,分词,编码和写文件,代码以下:

with open('./nlp_test0.txt') as f:
    document = f.read()
    
    document_decode = document.decode('GBK')
    document_cut = jieba.cut(document_decode)
    #print  ' '.join(jieba_cut)
    result = ' '.join(document_cut)
    result = result.encode('utf-8')
    with open('./nlp_test1.txt', 'w') as f2:
        f2.write(result)
f.close()
f2.close()   

    输出的文本内容以下:

    沙瑞金 赞叹 易学习 的 胸怀 , 是 金山 的 百姓 有福 , 但是 这件 事对 李达康 的 触动 很大 。 易学习 又 回忆起 他们 三人 分开 的 前一晚 , 你们 一块儿 喝酒 话别 , 易学习 被 降职 到 道口 县当 县长 , 王大路 下海经商 , 李达康 连连 赔礼道歉 , 以为 对不起 你们 , 他 最 对不起 的 是 王大路 , 就 和 易学习 一块儿 给 王大路 凑 了 5 万块 钱 , 王大路 本身 东挪西撮 了 5 万块 , 开始 下海经商 。 没想到 后来 王大路 居然 作 得 风生水 起 。 沙瑞金 以为 他们 三人 , 在 困难 时期 还 能 以沫 相助 , 很 不 容易 。

    基本已经能够知足要求。一样的方法咱们对第二段文本nlp_test2.txt进行分词和写入文件nlp_test3.txt。

with open('./nlp_test2.txt') as f:
    document2 = f.read()
    
    document2_decode = document2.decode('GBK')
    document2_cut = jieba.cut(document2_decode)
    #print  ' '.join(jieba_cut)
    result = ' '.join(document2_cut)
    result = result.encode('utf-8')
    with open('./nlp_test3.txt', 'w') as f2:
        f2.write(result)
f.close()
f2.close()  

    输出的文本内容以下:

    沙瑞金 向 毛娅 打听 他们 家 在 京州 的 别墅 , 毛娅 笑 着 说 , 王大路 事业有成 以后 , 要 给 欧阳 菁 和 她 公司 的 股权 , 她们 没有 要 , 王大路 就 在 京州 帝豪园 买 了 三套 别墅 , 但是 李达康 和 易学习 都 不要 , 这些 房子 都 在 王大路 的 名下 , 欧阳 菁 好像 去 住 过 , 毛娅 不想 去 , 她 以为 房子 太大 很 浪费 , 本身 家住 得 就 很 踏实 。

    可见分词效果还不错。

6. 中文文本挖掘预处理五:引入停用词

    在上面咱们解析的文本中有不少无效的词,好比“着”,“和”,还有一些标点符号,这些咱们不想在文本分析的时候引入,所以须要去掉,这些词就是停用词。经常使用的中文停用词表是1208个,下载地址在这。固然也有其余版本的停用词表,不过这个1208词版是我经常使用的。

    在咱们用scikit-learn作特征处理的时候,能够经过参数stop_words来引入一个数组做为停用词表。

    如今咱们将停用词表从文件读出,并切分红一个数组备用:

#从文件导入停用词表
stpwrdpath = "stop_words.txt"
stpwrd_dic = open(stpwrdpath, 'rb')
stpwrd_content = stpwrd_dic.read()
#将停用词表转换为list  
stpwrdlst = stpwrd_content.splitlines()
stpwrd_dic.close()

7. 中文文本挖掘预处理六:特征处理

    如今咱们就能够用scikit-learn来对咱们的文本特征进行处理了,在文本挖掘预处理之向量化与Hash Trick中,咱们讲到了两种特征处理的方法,向量化与Hash Trick。而向量化是最经常使用的方法,由于它能够接着进行TF-IDF的特征处理。在文本挖掘预处理之TF-IDF中,咱们也讲到了TF-IDF特征处理的方法。这里咱们就用scikit-learn的TfidfVectorizer类来进行TF-IDF特征处理。

    TfidfVectorizer类能够帮助咱们完成向量化,TF-IDF和标准化三步。固然,还能够帮咱们处理停用词。

    如今咱们把上面分词好的文本载入内存:

with open('./nlp_test1.txt') as f3:
    res1 = f3.read()
print res1
with open('./nlp_test3.txt') as f4:
    res2 = f4.read()
print res2

    这里的输出仍是咱们上面分完词的文本。如今咱们能够进行向量化,TF-IDF和标准化三步处理了。注意,这里咱们引入了咱们上面的停用词表。

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [res1,res2]
vector = TfidfVectorizer(stop_words=stpwrdlst)
tfidf = vector.fit_transform(corpus)
print tfidf

    部分输出以下:

  (0, 44)	0.154467434933
  (0, 59)	0.108549295069
  (0, 39)	0.308934869866
  (0, 53)	0.108549295069
  ....
  (1, 27)	0.139891059658
  (1, 47)	0.139891059658
  (1, 30)	0.139891059658
  (1, 60)	0.139891059658

    咱们再来看看每次词和TF-IDF的对应关系:

wordlist = vector.get_feature_names()#获取词袋模型中的全部词  
# tf-idf矩阵 元素a[i][j]表示j词在i类文本中的tf-idf权重
weightlist = tfidf.toarray()  
#打印每类文本的tf-idf词语权重,第一个for遍历全部文本,第二个for便利某一类文本下的词语权重
for i in range(len(weightlist)):  
    print "-------第",i,"段文本的词语tf-idf权重------"  
    for j in range(len(wordlist)):  
        print wordlist[j],weightlist[i][j]  

    部分输出以下:

-------第 0 段文本的词语tf-idf权重------
一块儿 0.217098590137
万块 0.217098590137
三人 0.217098590137
三套 0.0
下海经商 0.217098590137
.....
-------第 1 段文本的词语tf-idf权重------
.....
李达康 0.0995336411066
欧阳 0.279782119316
毛娅 0.419673178975
沙瑞金 0.0995336411066
没想到 0.0
没有 0.139891059658
浪费 0.139891059658
王大路 0.29860092332
.....

 

8. 中文文本挖掘预处理七:创建分析模型

    有了每段文本的TF-IDF的特征向量,咱们就能够利用这些数据创建分类模型,或者聚类模型了,或者进行主题模型的分析。好比咱们上面的两段文本,就能够是两个训练样本了。此时的分类聚类模型和以前讲的非天然语言处理的数据分析没有什么两样。所以对应的算法均可以直接使用。而主题模型是天然语言处理比较特殊的一块,这个咱们后面再单独讲。

9.中文文本挖掘预处理总结

    上面咱们对中文文本挖掘预处理的过程作了一个总结,但愿能够帮助到你们。须要注意的是这个流程主要针对一些经常使用的文本挖掘,并使用了词袋模型,对于某一些天然语言处理的需求则流程须要修改。好比咱们涉及到词上下文关系的一些需求,此时不能使用词袋模型。而有时候咱们对于特征的处理有本身的特殊需求,所以这个流程仅供天然语言处理入门者参考。

    下一篇咱们来总结英文文本挖掘预处理流程,尽情期待。

 

(欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com) 

相关文章
相关标签/搜索