对于中文和日文这样的特殊亚洲语系文本而言,字和字之间是紧密相连的,单纯从文本形态上无法区分具备独立含义的次(拉丁语系纯天然由空格分割不同的word),而不同的词以不同的方式排布,可以表达不同的内容和情感,因此在很多中文任务中,我们需要做的第一个处理就是“分词”。
目前主流的分词方法主要是基于词典匹配的分配方式(正向量大匹配法、逆向量大匹配法和双向匹配分词法)和基于统计的分词方法(HMM、CRF、和深度学习);主流的分词工具包括:中科院计算所NLPIR、哈工大LTP、清华大学THULAC、hanlp分词器、python jieba工具库等。
在自然语言处理的很多任务中,文本中有一些功能性词汇经常出现,然而对于最后的任务目标来说并没有帮助,甚至会对统计方法带来一些干扰,我们把这类词叫做停用此,通常我们会用一个停用词表把它们过滤出来。比如英语中的定冠词和不定冠词(a、an、the)等
中文当中常用的停用词词表参见:
https://github.com/goto456/stopwords
关于机器学习中停用词的产出与收集方法,可以参见知乎讨论:机器学习中如何收集停用词
https://www.zhihu.com/question/34939177
N-gram在中文中叫做n元语法,指文本中连续出现n个词语,n元语法模型是基于(n-1)阶马尔可夫链的一种概率语言模型,通过n个语词出现的概率来推断语句的结构。
https://www.ngui.cc/el/1856417.html?action=onClick
词性(part-of-speech)是词汇基本的语法属性,通常也称为词性。
词性标注,又称为词类标注或简称标注,是指分词结果中的每个单词标注一个正确的词性的程序,也即确定每个词是名词、动词或者是其他词性的过程
词性标注是多NLP任务的预处理步骤,如句法分析,经过词性标注后的文本会带来很大的便利性,但也不是不可或缺的步骤。
在很多复杂nlp问题中,我们还需要完成句法分析的任务,更具体一点说,需要确定橛子的句法结构,确定句子中各词之间的依存关系。
从一段非结构化文本中找出相关实体,并标注其位置以及类型,是nlp领域中的一些复杂任务的基础(比如关系抽取、信息检索、知识问答、知识图谱等)的基础。
对文本信息进行高度凝练的一种有效手段,通过3-5个词语准确概述文本的主题,帮助读者快速理解文本信息,是文本检索、文本摘要等许多下游文本挖掘任务的基础性和必要性工作。
jieba.cut 以及jieba.cut_for_search返回的结构都是一个可迭代的generator,可以使用for循环获得分词后得到的每一个词语
jieba.cut方法接受三个输入参数:
a. 需要分词的字符串;
b. cut_all参数用来控制是否采用全模式;
c. HMM参数用来控制是否使用HMM模式
jieba.cut_for_search方法接受两个参数:
a. 需要分词的字符串;
b. HMM(马尔可夫)参数用来控制是否使用HMM模式
全模式方法适合用于搜索引擎构建倒排序索引的分词,粒度比较细
import jiebaseg_list = jieba.cut("我在网易云课堂科学自然语言处理", cut_all=True)
print("Full model:" + "/".join(seg_list))
#Full model:我/在/网易/云/课堂/科学/自然/自然语言/语言/处理
#在cut_all模式下,得到的分词粒度较细,自然语言既保持了其原本的单词构成,也能切分成自然和语言两个单词print(seg_list)
#
#返回的是一个迭代器seg_list_1 = jieba.cut("我在网易云课堂科学自然语言处理", cut_all=False)
print("Default model:" + "/".join(seg_list_1))
#Default model:我/在/网易/云/课堂/科学/自然语言/处理
#在默认切分模式下,只返回常用的分词情况seg_list_2 = jieba.cut("他毕业于北京航空航天大学,在百度深度学习研究所进行研究") #默认是精确模式
print(",".join(seg_list_2))
#他,毕业,于,北京航空航天大学,,,在,百度,深度,学习,研究所,进行,研究seg_list_3 = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在斯坦福大学深造") #搜索引擎
print(",".join(seg_list_3))
#小明,硕士,毕业,于,中国,科学,学院,科学院,中国科学院,计算,计算所,,,后,在,福大,大学,斯坦福,斯坦福大学,深造seg_list_4 = jieba.cut_for_search("他毕业于北京航空航天大学,在百度深度学习研究所进行研究")
print(",".join(seg_list_4))
#他,毕业,于,北京,航空,空航,航天,天大,大学,北京航空航天大学,,,在,百度,深度,学习,研究,研究所,进行,研究
出现报错:AttributeError: partially initialized module ‘jieba’ has no attribute ‘cut’ (most likely due to a circular import)
原因:py文件或者模块名以“jieba” 进行命名了。
当我们希望返回的分词不是以迭代器形式呈现,而是返回列表形式,那么就使用lcut和lcut_for_search
print(jieba.lcut("我在网易云课堂科学自然语言处理"))
#['我', '在', '网易', '云', '课堂', '科学', '自然语言', '处理']print(jieba.lcut_for_search("小明硕士毕业于中国科学院计算所,后在斯坦福大学深造"))
#['小明', '硕士', '毕业', '于', '中国', '科学', '学院', '科学院', '中国科学院', '计算', '计算所', ',', '后', '在', '福大', '大学', '斯坦福', '斯坦福大学', '深造']
添加用户自定义字典
很多时候我们需要针对自己的场景进行分词,有一些领域内的专用词汇出现
可以使用jieba.load_userdict(filename)加载用户字典;
少量词汇可以自己用下面方法手动添加:
·用add_word(word, freq=None, tag=None)和del_word(word)在程序中动态修改词典
·用suggest_freq(segment, tune=True)可调节单个词语的词频,使其能(不能)被分出来
print("/".join(jieba.cut("如果放到旧字典中将出错", HMM=False)))
#如果/放到/旧/字典/中将/出错
jieba.suggest_freq(("中", "将"), True)
print("/".join(jieba.cut("如果放到旧字典中将出错", HMM=False)))
#如果/放到/旧/字典/中/将/出错
import jieba.posseg as pseg
words = pseg.cut("我在网易云课堂学习自然语言处理")
for word, flag in words:print('{}: {}'.format(word, flag))
'''
我: r
在: p
网易: n
云: ns
课堂: n
学习: v
自然语言: l
处理: v
'''
基于TF-IDF算法的关键词抽取
<1> import jieba. analyse
<2>jieba. analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
其中,sentence为待提取的文本,topK为返回几个TF/IDF权重最大的关键词,默认值是20,withWeight为是否一并返回关键词权重,默认值是False,allowPOS仅包括指定词性的词,默认为空,即不筛选