政务行业的NLP技术应用-中文分词

474 阅读5分钟

政务行业每年会有大量的文字报告,有些是政府本身产生的公文材料, 有些是网民提交的意见反馈等。需要对这些文本材料进行文本分析, 就涉及到很多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]