1、NLP简介
自然语言处理(Natural Language Processing, NLP)是计算机科学、人工智能、语言学的交叉学科,研究在人与人交互中以及与计算机交互中的语言问题。为了建设和完善语言模型,自然语言处理建立计算框架,提出相应的方法来不断的完善设计各种使用系统,并探讨这些使用系统的评测方法。
自然语言处理时人工智能的一个分支。
自然语言处理的研究方向
目前,NLP有很多研究方向,例如:文本分类(情感分析、意图识别),摘要生成(文本生成),多轮对话(智能客服)等。每一个研究方向都包含很多更基础的研究点,下面总结了从词汇、语句、篇章到系统应用的不同粒度上NLP应用场景:
- 词法短语: 分词、词性标注、命名实体识别、组块分析
- 句法语义:语言模型、依存句法分析、语义消歧、语义角色标注、深层语义分析
- 篇章理解:文本分类、聚类、文章摘要、文本生成、篇章关系识别、篇章衔接关系、指代消歧、语义表示、语义匹配、主题模型、情感分析、舆情监控
- 系统应用:信息抽取、知识图谱、信息检索、Query分析、自动问答、智能对话、机器翻译、语音识别、OCR、图像文字生成等
2、词法分析
词法分析包括分词、词性标注、命名实体识别等。分词是词法分析中最基本的任务。目前,汉字分词的准确率已达到95%左右。中文兼类词的词性歧义消解和未知词的词性识别是词性标注的热点和难点。
什么是分词?
分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文比之英文要复杂得多、困难得多。
分词的方法有哪些?
- 基于字符串匹配的方法
- 正向最大匹配法(FMM)
- 逆向最大匹配法(BMM)
- 双向最大匹配法(BM)
- 基于统计的方法
- N元文法模型(N-gram)
- 隐马尔科夫模型(HMM)
- 条件随机场(CRF)
- 基于理解的方法
- 基于语法和规则的分词方法
基于统计的分词方法
根据字符串在语料库中出现的统计频率来决定其是否构成此。主要统计模型:N元文法模型、隐马尔科夫模型、条件随机场等。
- N元文法模型:基于一种假设,文本中第
n
个词的出现只与前面n-1
个词相关,而与其他任何词都不相关,那么整句的概率就是各个词出现概率的乘积。
对于一个句子S
,假设S
是由词序列 w1 , w2, …wn 组成的,那么
P(S) = P(w1w2w3…wn)=P(w1)P(w2|w1)P(w3|w1w2)…P(wn|w1w2…wn-1)
其中P(w1)表示第一个词w1出现的概率,P(w2|w1)是已知第一个词的前提下,第二个词出现的概率。以此类推,词wn出现的概率取决于它前面全部的词。 - 马尔科夫假设:一个词的出现的概率只与它前面出现的有限的一个或者几个词有关,那么
P(S)
=P(w1w2w3…wn)
=P(w1)P(w2|w1)P(w3|w1w2)…P(wn|w1w2…wn-1)
≈P(w1)P(w2|w1)P(w3|w2)…P(wn|wn-1)
分词工具有哪些?
Jieba
常用轻量级的分词方法工具,可以实现分词、词性标注、关键词提取等功能。
项目地址: jieba
对 Python2/3
均兼容
支持三种分词模式
- 精确模式,试图将句子最精确地切开,适合文本分析;
- 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
- 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
安装
- 全自动安装:
pip isntall jieba
或者easy_install jieba
- 半自动安装:先下载http://pypi.python.org/pypi/jieba/ ,解压后运行
python setup.py install
- 手动安装:将
jieba
目录放置于当前目录或site-packages
目录 - 通过
import jieba
来引用
主要功能
1、 分词
jieba.cut
:三个输入参数:需要分词的字符串,cut_all
是否采用全模式,HMM
是否使用HMM模型jieba.cut_for_search
方法接受两个参数:需要分词的字符串,是否使用HMM
模型。该方法适用于搜索引擎构建倒排索引的分析,粒度比较细jieba.cut
和jieba.cut_for_search
返回的结果都是一个可迭代的generator
,可以使用for
循环来获得分词后得到的每一个词语(unicode
)jieba.lcut
和jieba.lcut_for_search
直接返回list
类型jieba.Tokenizer(dictionary=DEFAULT_DICT)
新建自定义分词器,可用于同时使用不同词典。jieba.dt
为默认分词器。所有全局分词相关函数都是该分词器的映射。
输出结果:import jieba seg_list = jieba.cut("我来到北京清华大学", cut_all=True) print("Full Mode: " + "/ ".join(seg_list)) # 全模式 seg_list = jieba.cut("我来到北京清华大学", cut_all=False) print("Default Mode: " + "/ ".join(seg_list)) # 精确模式 seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式 print(", ".join(seg_list)) seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式 print(", ".join(seg_list))
【全模式】: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学 【精确模式】: 我/ 来到/ 北京/ 清华大学 【新词识别】:他, 来到, 了, 网易, 杭研, 大厦 (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了) 【搜索引擎模式】: 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造
2、添加自定义词典
- 开发者可以指定自己自定义的词典,以便包含
jieba
词库里没有的词。虽然jieba
有新词识别能力,但是自行添加新词可以保证更高的正确率。 - 用法:
jieba.load_userdict(file_name)
#file_name
为文件类对象或自定义词典的路径 - 词典格式和
dict.txt
一样,一个词占一行;每一行分为三个部分:词语、词频(可省略)、词性(可省略),用空格隔开。
示例:创新办 3 i
云计算 5
凯特琳 nz
台中
调整词典
- 使用
add_word(word, freq=None, tag=None)
和del_word(word)
可在程序中动态修改词典 - 使用
suggest_freq(segment, tune=True)
可调节单个词语的词频,使其能(或不同)被分出来 - 代码示例
>>> print('/'.join(jieba.cut('如果放到post中将出错。', HMM=False))) 如果/放到/post/中将/出错/。 >>> jieba.suggest_freq(('中', '将'), True) 494 >>> print('/'.join(jieba.cut('如果放到post中将出错。', HMM=False))) 如果/放到/post/中/将/出错/。 >>> print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False))) 「/台/中/」/正确/应该/不会/被/切开 >>> jieba.suggest_freq('台中', True) 69 >>> print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False))) 「/台中/」/正确/应该/不会/被/切开
3、关键词提取
基于TF-IDF
算法的关键词抽取
import jieba.analyse
jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
sentence
为待提取的文本topK
为返回几个TF-IDF
权重最大的关键词,默认值为20
withWeight
是否一并返回关键词的权重值,默认为False
allowPOS
仅包括指定词性的词,默认值为空,即不筛选
jieba.analyse.TFIDF(idf_path=None)
新建TF-IDF
实例,idf_path
为IDF
频率文件- 示例
import jieba.analyse s = '下一步,要围绕必须确保社保费率降低、必须 确保基本养老金按时足额发放的要求,深入企业了解政策落实情况,及时研究解决新问题,确保政策落地,不打折扣。稳定缴费方式,在落实职工基本养老保险单位缴费比例不高于16%的前提下,对个别省份存在的省内费率、缴费基数标准不统一等问题,今年原则上不作政 策调整。各地要切实担起基本养老金发放主体责任,确保一户不落。对省级统筹要稳妥推进。' tags = jieba.analyse.extract_tags(s) >>> print(' '.join(tags)) 缴费 确保 养老金 发放 落实 政策 社保费 职工基本 16% 打折扣 担起 基本 必须 养老保险 足额 一户 稳妥 原则上 按时 统筹
基于TextRank
算法的关键词抽取
jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
直接使用,接口相同,注意默认过滤词性。jieba.analyse.TextRank()
新建自定义TextRank
实例- 示例
>>> for x, w in jieba.analyse.extract_tags(s, topK=5, withWeight=True): ... print('%s %s'%(x, w)) ... 缴费 0.408791852813 确保 0.387930448194 养老金 0.263083841011 发放 0.212644450916 落实 0.202288516644 >>> for x, w in jieba.analyse.textrank(s, topK=5, withWeight=True): ... print('%s %s'%(x, w)) ... 确保 1.0 缴费 0.856582759027 政策 0.66525919264 发放 0.66041604087 基本 0.596023711011
4、词性标注
jieba.posseg.POSTokenizer(tokenizer=None)
新建自定义分词器,tokenizer
参数可指定内部使用的jieba.Tokenizer
分词器。jieba.posseg.dt
为默认词性标注分析器
示例:
>>> import jieba.posseg as pseg
>>> words = pseg.cut("我爱北京天安门")
>>> for word, flag in words:
... print('%s %s'%(word, flag))
...
我 r
爱 v
北京 ns
天安门 ns
HanLP
Hanlp可以实现很多功能,例如分词、标注、实体识别等。
项目地址: HanLP
具体安装使用方法参考项目说明
3、句法分析
句法分析基本任务是确定句子的句法结构或句子中词汇之间的依存关系。
句法分析的意义
句法分析表示NLP的最终目标,但是实现最终目标的重要环节,甚至是关键环节。
句法分析的作用
- 句法结构分析判断句子构成是否符合给定的语法。
- 依存语法分析用词与词之间的依存关系描述语言结构的框架。
句法结构分析的方法
- 基于规则的分析方法
由人工组织语法规则,建立语法知识库,通过条件约束和检查实现句法结构歧义的消除- CYK分析算法
- GLR分析算法
- 语法驱动的统计句法分析
由生成语法定义被分析的语言及其分析出的类别,在训练数据中观察到的各种语言现象的分布以统计数据的方式与语法规则一起编码。- PCFG
- SCFG
4、文本表示
文字是人类认知过程中产生的高层认知抽象实体,我们需要将其转换为计算机可以处理的数据类型。计算机是以编码(如UTF-8编码)的形式存储语言文字的,计算机只会存储、传输代表文字的二进制数据。那如何让计算机理解语言文字呢?
主要有以下是那种: 词网、词袋、词向量
常见的方法有:
- 文本离散表示, 如
TF-IDF
- 文本分布式表示,如
word2vec
WordNet词网
传统的一种用于自然语言处理的方法是使用词网(WordNet)——人为定义每一个词的各种属性。
如我们定义“好”、“优秀”、“不错”是一组同义词,表示质量好;“好”和“同意”、“赞同”是一组同义词,表示赞成;“好”还和“很”是同义词,表示程度,如“好冷”……
除了同义词,我们还可以定义词的其他属性,如从属关系:“熊猫”属于“熊类”,属于“食肉动物”,属于“哺乳动物”……
然而WordNet的缺点是十分明显的:
- 词之间缺少细微差别:我们将“好”和“优秀”作为同义词,但二者还是有区别的
- 不断会有词产生新的意思,需要不断更新
- WordNet定义过于主观
- 构建WordNet需要大量的人力
- 无法计算词之间的相似程度
文本离散表示
-
Bag of words(词袋模型)
One-hot编码是指,给定一个长度为N的字典,每个词用一个长度为N的向量来表示。其中只有一个地方为1,其他地方都为0.
假设一个词典只有8个词[“今”, “我”, “好”, “看”, “文”, “章”, “天”, “你”],”好”这个词在词典中的第三个词,可用一个长度为8的词向量来表示”好”
“好” = [0, 0, 1, 0, 0, 0, 0, 0]
词袋模型(Bag of words)忽略一句话的词序和语法,把一句话中所有的词的one-hot编码相加,就得到了这句话的向量表示。
“技术杂学铺的文章写得好好看啊” = [0, 0, 2, 1, 1, 1, 0, 0]
由于词袋模型忽略了词的先后顺序,“我看文章”和“文章看我”使用同一个向量表示的,但二者的语义完全不同。
尽管如此,使用词袋模型的朴素贝叶斯算法在一些文本分类任务上的效果还是很好的。 -
TF-IDF
TF-IDF
算法是一种用于信息检索与数据挖掘的常用加权技术。TF
的意思是词频(Term-frequency)
,IDF
的意思是逆向文件频率(inverse Document frequency)
。
TF-IDF
是传统的统计算法,用于评估一个词在一个文档集中对于某一个文档的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
文本分布式表示
词向量(word vector)
和one-hot编码类似,我们依旧使用一个向量来表示一个词。只不过这些词的取值不再是整数。
注:词向量(word vectors),也称为词嵌入(word embedding)
语义相近的词,其词向量也相近。(词向量相近可以是两个向量的欧式距离很小,又或者是两个向量的夹角很小)。
词向量另一个有趣的特点是,虽然其是由一串等长的浮点数表示的,但是词向量中暗含着某种词义。比如“国王”的词向量减去“女王”的词向量约等于“男孩”的词向量减去“女孩”的词向量;“中国”-“中国人”约等于“德国”-“德国人”。
工具
gensim
参考资料: