政务行业每年会有大量的文字报告,有些是政府本身产生的公文材料, 有些是网民提交的意见反馈等。需要对这些文本材料进行文本分析, 就涉及到很多NLP自然语言处理技术。
目录
- 中文分词
- 文本关键词提取
- 文本标注:分类、人物与地区提取
- 文本热点分析
- 文本相似度分析
- 文本摘要
- 公文校验
- 文本情感分析
中文分词
中文分词是中文语义处理独特的地方,因为中文不像英语一样可以通过空格来划分单词。 而中文分词是一切中文文本处理的基础。分词不精准,后面各种的语料模型就失去了意义。 目前市面上有几种常用的分词器,比如jseg,jieba等。之前做搜索引擎的时候还用过IK 分词器。
jieba分词器
本系列中将使用jieba分词器来进行分词。
结巴有两类分词器:
import jieba
import jieba.posseg as seg
其中posseg用于词性标注,可以把每个分词标注它是名词、人名、形容词、动词等。这个很有用,我们后面在做关键词提取的时候,会根据词性来调整每个分词的权重,可以有效提升关键词的准确性。
text = '做社会主义接班人'
list = jieba.lcut(text)
print(list)
['做', '社会主义', '接班人']
#带词性的分词
list2 = seg.lcut(text)
print(list2)
[pair('做', 'v'), pair('社会主义', 'n'), pair('接班人', 'n')]
同时jieba分词器有三种分词方式:全模式、精准模式、搜索模式
list3 = seg.lcut(text,cut_all=False) #精准模式,等同于seg.lcut(text)
print(list3)
#list3输出: ['做', '社会主义', '接班人']
list4 = seg.lcut(text,cut_all=True) #全模式,将所有可能的词都会切分
print(list4)
#list4输出: ['做', '社会', '社会主义', '会主', '主义', '接班', '接班人']
list5 = seg.lcut_for_search(text) #在精准模式的基础上再做细分,搜索模式
print(list5)
#list5输出: ['做', '社会', '会主', '主义', '社会主义', '接班', '接班人']
可以看出精准模式是我们最想要的,而别两种模式可能更适用于搜索。 其实我现在将文本导入搜索引擎做索引的时候,都不用中文分词器了。因为用了中文分词器后会导致很多用户的搜索 搜不到内容。 比如这句“做社会主义接班人”,如果我们按照中文分词建了索引后,如果用户搜“社会主义接”,搜索引擎会将 该句话分词为:“社会,主义,社会主义,接”这几个词去检索,就导致"接"这个词找不到对应的索引值,导致搜索 不到。 因此现在干脆不用分词器,直接采用搜索引擎默认的文本分词,即单个词单个词的拆分,这样无论用户 怎么输入,都能够保证搜索到内容。当然这样可能会对性能带来一定的影响。这就要具体情况具体分析了。
加载自定义词库
jieba分词是支持自定义词库的。有些新词如果不加入词库,是分不出来的。
jieba自带了词库,在jieba的lib包下有个dict.txt文件,有30多万的词库。格式如下:
龙马精神 4 nr
每一行包含三个属性,第一个即中文单词,第二列词频(可省),第三列为词性(可省)。 词频和词性可省略。词频的作用,用于结巴另一个隐含的高级功能HMM模式,可以提取文本的关键词。后续讲提取关键词算法时会讲解词频的作用。
加载自定义词库:
jieba.load_userdict("ext.dic")
比如,ext.dic下定义一个词:
男默女泪
text = '这真是让人男默女泪的剧情'
list =jieba.lcut(text)
print(list)
#加载自定义词库前,list输出: ['这', '真是', '让', '人', '男默', '女泪', '的', '剧情']
jieba.load_userdict("ext.dic")
list =jieba.lcut(text)
print(list)
#加载自定义词库后,list输出: ['这', '真是', '让', '人', '男默女泪', '的', '剧情']
如果觉得词库写在文本里,对于后续的维护与管理不方便,比如每次新加词必须重启服务重新加载。那么也可以将词库存放于数据库中。这样就方便词库的管理了。
我们这里采用mongodb来存储自定义词库:
from pymongo import MongoClient
mdbUrl1 = 'mongodb://' + uName + ':' + uPwd + '@ip:port/test' # 连接数据库url
client1 = MongoClient(mdbUrl1)
list = client1['dbName']['wordDict'].find()
#wordDict结构:两个字段,_id和tag 其中_id即中文单词,tag为词性,如 _id:男默女泪,tag=nr
for word in list:
try:
if 'tag' in word.keys():
jieba.add_word(word['_id'], tag=word['tag'])
else:
jieba.add_word(word['_id'])
except Exception:
print('add '+word+" error")
加载停用词
有些词并不需要把它分出来,比如一些助词:的、啊、了这类,可以在分词的时候直接排除掉,以免影响后续语义分析。
但是jieba需要手动加载停用词库,并且还需要手动将分词列表与停用词列表挨个比对,然后排除。相当于jieba本身并没有对停用词这一概念,纯粹是使用的人自己加的逻辑,可能是把其他分词器的停用词概念强行移植过来的。也附上这一代码吧:
def movestopwords(sentence):
stopwords = stopwordslist('./stop_words.txt') # 这里加载停用词的路径
santi_words =[x for x in sentence if len(x) >1 and x not in stopwords]