三、NLP基础 (朴素贝叶斯、隐马尔可夫)

一、什么是NLP

1、自然语言处理

(英语:natural language processing,缩写作 NLP )此领域探讨如何处理及运用自然语言;自然语言认知则是指让电脑“懂”人类的语言。

这里的自然语言,一般包括两种。一种是指我们这说话的声音,也就说语音,另外一种是指文字。比如说我们写一篇文章,或者说跟客服进行聊天,它属于文字。实际上就是指让电脑来理解人类的语言,因为无论是用文字也好还是用语音也好,它都属于人类的语言。

2、自然语言处理的主要范畴

1、文本分析,给你一段文章你要分析出相关的内容,根据你的需求进行一定量的分析。

2、信息检索,像百度搜一个关键词。他可以通过这些关键词来去给你检索出一些内容。当然,这种搜索引擎,它的搜索功能并不是单纯的检索那么简单,里面可能还会包含着,比如说如何分析这个文本,或者说一个词义的理解等等。

3、词性标注,比如说我们在小学的时候,学动词,副词,名词,主谓宾等等。词性标注就是指一个词的词性,比如说人,他是一个名词。北京,它是一个地名。这些都是词性,还有名词形容词比如说美丽的,好看的等等这是一个形容词。词性标注是用来解释这个词的词性是什么。

4、问答系统,比如说,我们跟这个智能机器人进行聊天,这就是一种问答系统。或者说我们在京东,在淘宝等等其他的电商平台买东西有的时候比如说客服不在线。那么他有一种智能问答,你可以去问这个聊天机器人。聊天机器人根据你的语言,然后跟你进行相关的回复,这就是问答系统,当然我们也可以去做一些邮件系统。比如说自动回复邮件,还有比如说去做一些语音处理或者文本分类辨别。

二、NLP技术

我们在网上看到的任何关于机器学习的算法,或者说深度学习的模型。跟这个nlp相关的这些算法也好模型也好。他最基本的都离不开词法分析,句法分析和语法分析。

1、词法分析

主要包括分词技术、词性标注、命名实体、识别词义消歧四大内容。

分词技术:如在文章中切分词语

在这里插入图片描述

1.1词性标注
词性标注(part-of-speech tagging),又称为词类标注或者简称标注,是指为分词结果中的每个单词标注一个正确的词性的程序,也即确定每个词是名词、动词、形容词或者其他词性的过程。

1.2命名实体识别:
(Named Entity Recognition,简称NER)又称“专名识别”,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。

命名实体识别是信息提取、问答系统、句法分析、机器翻译、面向Semantic Web的元数据标注等应用领域的重要基础工具,在自然语言处理技术走向实用化的过程中占有重要地位。

一般来说,命名实体识别的任务就是识别出待处理文本中的三大类(实体类、时间类和数字类)、七小类(人名、机构名、地名、时间、日期、货币和百分比)命名实体。
步骤:
(1)实体边界识别(类似分词)

(2)确定实体类别(英文实体,中文实体)
方法:
(1)基于规则和词典的方法,比如一句话,今天早上天气非常好,我要想进行分词,他会怎么分呢?首先,他会把今天早晨天气非常好这九个字放到词典里去查,看这九个字是不是一个词。发现这九个字不是一个词。这个时候,那在从最后去掉一个字,那就变成了,今天早上天气非常。看这么几个字,他是不是一个词,那不是再去掉,那就变成了今天早上天气非。直到我们最后能够从词典中去匹配到一个字进而找到这么一个词。那这个词就是我们被切分出来的一词,那被切分出来之后,那可能到最前面,那就应该是今天,是一个词。今天这个词找到之后,那就从早晨开始再去进行这么一遍一遍的循环,直到最后把这个词进行切分出来,使用这种方法就能切分,有什么坏处呢?实际上,使用这种方法切分的话,当你遇到非常长非常长的一个句子或者说一个段落的时候。我们都需要经过非常多的次数的循环,这样是严重的影响了机器的效率,这是第一个缺点。第二个缺点,我们利用这种方法需要建立一个大量的词库,或者建立一个大量的词典,也需要建立大量的规则。但是我们知道,每年,或者说时时刻刻都会有新的词出现。那只要有新的词出现,我就要给他加在词典中。那这样的话词典会非常非常的庞大。那如果变得非常庞大的话,就会导致这个分词会非常复杂,或者说在词典中去解锁去查找的过程会非常复杂。所以说目前来讲是不可取的,这是最早期的一种方法。

(2)基于统计的方法:在实际过程中,一般我们是基于这个机器学习来进行分词,或者进行命名实体识别。一般来讲,我们有四种方法,这四种方法实际上是四个模型

  • 隐马尔可夫模型(Hidden Markov Mode, HMM)
  • 较大熵(Max mium Entropy, ME)
  • 支持向量机(Support Vector Machine, SVM)
  • 条件随机场(Conditional Random Fields, CRF)

1.3词义消歧:将具有多种含义词义的内容消除歧义

2、贝叶斯分类

  • 贝叶斯分类算法是统计学的一种分类方法,它是一类利用概率统计知识进行分类的算法。是统计学和概率学的交叉知识。它利用的是概率学里面的概率图模型来进行计算进行分类的。
  • 朴素贝叶斯法是基于贝叶斯定理:与特征条件独立假设的分类方法。最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM)。
  • 在许多场合,朴素贝叶斯(Naive Bayes, NB)分类算法可以与决策树和神经网络分类算法相媲美,该算法能运用到大型数据库中,而且方法简单、分类准确率高、速度快

首先我们先说一下什么是贝叶斯算法。首先,朴素贝叶斯分类,是基于一个简单的假设:给另一个目标要值时,属性之间相互独立。实际上就是这个公式

在这个公式中,c表示的是随机事件发生的一种情况。x表示的就是证据(evidence)\状况(condition),泛指与随机事件相关的因素。

  • P(clx):在x的条件下,随机事件出现c情况的概率。(后验概率) 
  • P(c):(不考虑相关因素)随机事件出现c情况的概率。(先验概率)
  • P(xIc):在已知事件出现c情况的条件下,条件x出现的概率。(后验概率)
  • P(x):x出现的概率。(先验概率)

先验概率就是说,我们大概预先能够判断或者预先知道这件事情所出现的概率是多少。我们能够进行一个预估的概率,把它叫做先验感率。

那么什么是后验概率呢?就是说除了先验概率之外,在这个先验概率的基础上加了一些考虑,因为先验概率只是一个预知。这个预知,对于后续的一个估量可能并不是特别准确,因为它是基于之前的一些特征或者之前的一些条件来求得的概率。但是,实际上我们在做概率预测的时候。我们需要的是增加一些条件或者增加一些这个推理。那么这个后验概率就是根据这个而来的,也就说这个在贝叶斯推断中,一个随机条件事件,它出现的后验概率,是指就是当事件相关的一系列证据或者背景也被考虑进来,这种情况下所出现的一个概率。

3、朴素贝叶斯算法

朴素贝叶斯分类器基于一个简单的假定:给定目标值时属性之间相互条件独立。说白了就是,我们可以假设他是一个互斥的一种关系。

这个公式前半部分就是朴素贝叶斯。后面实际上是在这个的基础上,只是增加了一块。

这个公式右面,实际上就是在左面的等式中加了一个条件联合的一个概率。而这一块,实际上就是指就是多个条件的概率进行相乘得到的一个概率。因为朴素贝叶斯和贝叶斯的区别在于,朴树贝叶斯它的每一个目标的概率都是互斥的,独立的。所以说在用朴素贝叶斯进行分类的时候,我们需要把每一个概率进行相乘,或者说要单独求得每一个条件所占有的概率,然后把这些概率再进行相乘运算,得到另一个值,在与贝叶斯概率进行一个融合。最后形成了朴素贝叶斯算法。朴素贝叶斯算法在实际的运用过程中准确性,一般情况下来讲,比贝叶斯算法准确性要高,因为在这里,它会单独生每一个条件所出现的概率。而这个每一个条件所出现的概率,会进行分别的求得,我们可以考虑成为一种拆分,这种拆分会导致每一个小的分类,它求得的概率的精准度相对来讲要高一些。从而最终的精准度相对来讲会要比这个贝叶斯算法的这个准确率相对来讲要高一些。

常用情景

文本分类、垃圾邮件过滤、多分类实施预测、拼写纠错

4、马尔可夫过程

  • 马尔科夫过程(Markov process)是一类随机过程。
  • 在已知目前状态(现在)的条件下,它未来的演变(将来)不依赖于它以往的演变(过去)。主要研究一个系统的状况及其转移的理论。它是通过对不同状态的初始概率以及状态之间的转移概率的研究,来确定状态的变化趋势,从而达到对预测未来的目的。

在现实生活中,有很多过程都是马尔科夫过程。比如说液体中的一些微粒子的运动,传染病传播感染的人数,车站的候车人数。

有两个基本的特性。一个是无后效性,一个叫做便利性。无后效性就是说,事物将来的状态,以及他出现的概率的大小,只取决于这个事物现在所处的状态,跟以前的状态无关,这也就是说,他未来的演变不依赖于他以往的演变,他只在已知目前状态的条件下来定成一个推算。便利性是指不管是出现在什么状态,在较长一段时间内,马尔科夫过程会逐渐趋于稳定的这么一个状态,而且他与初始状态无关。

  • 马尔科夫链 Markov chain是指具有马尔科夫性质的离散事件随机过程,即时间和状态参数都是离散的马尔科夫过程,是最简单的马尔科夫过程。

 5、隐马尔可夫模型

  • 隐马尔可夫模型(Hidden Markov Model,HMM)作为一种统计分析模型,创立于20世纪70年代。
  • 隐马尔可夫模型(Hidden Markov Model,HMM)是结构最简单的动态贝叶斯网,这是一种著名的有向图模型,主要用于时序数据建模(语音识别、自然语言处理等)。
  • 隐马尔可夫模型是马尔可夫链的一种,它的状态不能直接观察到,但能通过观测向量序列观察到,每个观测向量都是通过某些概率密度分布表现为各种状态,每一个观测向量是由一个具有相应概率密度分布的状态序列产生。

马尔科夫链是指只有马尔可夫性质的一种离散事件的一个随机过程。也就是说,他有时间和状态参数,并且这些参数都是离散的。他也是一个最简单的马尔可夫过程,一般来讲,马尔可夫过程,研究的时间是无限的,连续的变量,其值是连续不断的,相邻的两个值之间可以做无限的分割。这是正常的马尔科夫过程。马尔科夫链的时间是取离散数值。比如说,取月,季度,年等等。马尔科夫链是有限的,只有这个可列的一些状态。比如天气,它可以取晴下雨,这么两种。或者说描述一个物体可以去大中小等等,所以说它是有一定可列的状态。实际上,马尔科夫链描述了一种状态的一个序列。比如说他每一个状态只是他取决于前面的有限个状态。

那这个图就是隐马尔可夫模型示意图。在这个图中,我们给他做一个拆分,首先,我们看上面这一行z0-z7。他是一个状态的变量。这里面 z0-z7表示七个时间,七个时刻的时候这个系统的状态。通常上,我们会假定状态的变量是隐藏的,不可被接收到的。因此我们把这个状态变量的也称之为这个隐变量,也就是这个z可以称之为隐变量。那第二组下面这一个x0-xt,是表示第i个时刻所观察到的值。隐马尔可夫模型中,他系统通常有多个状态,他会在多个状态之间进行转换。因此说在状态变量,比如说在zi的取值范围内,它会有n个可能取值离散空间,这个n是他的状态数。我们观察到这个xi,它可以是离散型的,也可以是连续性的。但是一般来讲,我们为了研究方便,一般仅考虑这个离散性变量。取值范围就是x0-xt。在隐马尔可夫模型中,我们可以看到这个箭头,主要是表示了这个变量之间的一个依赖关系。也就是说,在任意一个时刻,我观测到变量的取值仅依赖于就是该时刻的这个状态变量。也就说比如说x1只是由z1来确定的,与其他变量的取值无关。同时在zt这一个时刻,仅依赖于t-1时刻的状态,就是说他只是一个链式的结构,他这个时刻的状态,仅取决于前一个时刻。跟其他的是无关的,也就是说,下一个时刻的状态底是由当前的时刻来决定的。他跟过往的以前的是没有任何关系的,也是不依赖的。

隐马尔可夫模型由五个要素组成,其中两个状态集合(N、M),三个概率矩阵(A、B、元):
1)N,表示模型中的状态数,状态之间可以相互转移。
2)M,表示每个状态不同的观察符号,即输出字符的个数。
3)A,状态转移概率分布。
4)B,观察符号在各个状态下的概率分布。
5)n,表示初始状态分布。

输入:HMMs的五元组(N, M,A, B, r)。
输出:一个观察符号的序列,这个序列的每个元素都是M中的元素。

应用场景:中文分词、机器翻译、语音识别、通信中的译码

6、运用隐马尔科夫模型进行命名实体识别

首先,来说一下这个训练部分。在进行任何机器学习或者深度学习的方法,在模型训练之前,首先第一步要做的就是准备训练的数据。在nlp一般把这种训练的数据叫做语料。一般使用隐马尔可夫模型进行命名实体识别,主要是利用词性来作为这个换它的值。一般有28种词性,那系统识别的这个命名实体呢?一般来讲有四个大类。第一个类是人名,第二个类是地名,第三个类是机构名,第四个类是专有名词。每一个类,就是根据他的组成部分在这个命名实体中出现的位置,位置的不同又可以分为,比如以命名实体开头的,或者命名实体在内部的,以及命名实体结尾的各种各样的就是类型。不属于任何命名实体的,这些我们不需要的,我们可以把它标注为成这个其他的类型。

这个就是使用隐马尔可夫模型来训练,我们要训练什么,要得到什么?在训练的时候,第一步就是进行参数训练,以及求得这个初始概率,转移概率,以及发生概率。那这三个概率又是什么呢?这是我们在上面说讲的转移概率,还有初始概率,以及状态下的分布概率,实际上这个也叫做发射概率。我们要知道我们要求什么了,要怎么做了,那接下来就是怎么做的问题。我们使用隐马尔可夫模型进行这个概率训练,所追寻的实际上也是追求的是贝叶斯的原则。我们通过使用贝叶斯理论,来求得每一个状态的概率。首先,我们假设状态只与前一个状态相关,那我们可以输出当前这一个状态的观测到的概率是多少,以此类推,我们就可以把整个一句话的概率求出来。这个是通过训练来得到概率。那么得到概率了之后,那我们把这概率作为输出放到命名实体识别中,进行分词且标注词性的句子。

在识别过程中,就是利用训练的参数为当前的输入的词性训练,标注他对应的状态的过程。在给定的那个模型和观测到的值的条件下,找出概率最大的状态,这个识别主要是用在这里。但是在这个识别的过程中,可能需要进行分词,需要标注词性。其实使用隐马尔可夫模型进行命名实体识别,它的系统实现起来相对来说比较简单,而且效率也比较高。但是,由于在训练的时候只考虑到了词性的序列,但对一些特定的一些词,可能就会有一些不是特别准确的地方,这些特定的词我们一般管它叫做专有名词。比如说北京大学,我们简称北大,但全称叫北京大学,或者说浙江大学。如果按照正常的分词来讲,我们可以把北京和大学这两个字给分开,但实际上,在一般来讲,比如说我所就读的学校是北京大学,这个时候,这个北京大学,它是一个整体,我们不能把它分开。这个时候,北京大学第四个字,就叫做专有名词。那么针对这些专有名词,我们就需要进行一个规则修正,比如说利用我们已有规则,对隐马尔可夫模型所识别出来的结果真修正。这样一来,我们就可以将词汇的信息作为特征加入到系统中。来去帮助他进行最终的识别,但是这个规则了一般必须得满足一些前提条件。

这个前提条件是以我们要识别出来的结果为基础或者以我们的结果为导向进行规则的修正。修正完了之后,再通过命名实体的内部结构的特征来进行提取。有了一个命名实体,一般来讲是由一个词或者多个词,它合起来而组成的,所以说我们需要根据一些规则,或者根据一些特征,来提取复合的命名实体的词性的一个序列,来找出该词性出现概率。之后再将这个词性进行标注。最后,将所标注的结果利用外部特征来进行转换。得到我们最后想要得到的命名实体的结果。这个就是用隐马尔可夫模型来实现命名实体识别的一整套流程。

三、朴素贝叶斯例子

1、使用朴素贝叶斯训练中文文本分类工具

首先我们会选两个类别的数据,比如说我选的是一个是旅游的,一个是跟宾馆相关的数据,把他作为训练样本进行训练,训练出一个分类器。接下来随便拿一批数据来进行测试,看是属于宾馆的还是属于这个旅游信息的。

2、环境

python、jieba(分词工具)、sklearn(机器学习工具包)、scipy(高级数学工具)

conda是一种python环境管理程序,conda和anaconda一起能解决很多环境、包管理的问题。而且安装anaconda的过程中会一并安装scipy,numpy等很多常用的包,可以说是用python进行科学计算和数据分析的必备神器

管理conda和anaconda

conda info 查询conda信息
conda update conda 升级conda
conda update anaconda 升级anaconda

管理环境

conda info -e 环境信息
conda create -n test python=3.6 创建环境test,并指定python版本,
source activate test 激活环境
source deactivate test 关闭环境
conda remove --name test --all 删除环境

包管理

conda list 列出所有安装的包的信息
conda search beautiful-soup 查询包
conda install -n test beautiful-soup 安装包,并指定安装环境,如果没有-n test,则安装到当前环境
conda update beautiful-soup 升级包
conda remove -n test beautiful-soup 移除包

python-关于pip install 安装慢的问题可以利用清华http源安装:
pip install -i https://pypi.doubanio.com/simple/ 包名

3、项目创建

conda create -n nlp python=3.6
activate nlp
pip3 install jieba --upgrade
pip3 install sklearn --upgrade
pip3 install scipy --upgrade

Pycharm软件中使用Anaconda环境

import os
import jieba
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
import joblib
import time


# 预处理文档
def pre_process(path):
    text_with_space = ""
    text_file = open(path, "r", encoding="utf8").read()
    # 使用jieba进行切分
    text_cute = jieba.cut(text_file)
    for word in text_cute:
        # 空格进行分词
        text_with_space += word + ""
    return text_with_space


# 将文件夹下文档批量切分后,载入成数据集,返回训练的数据集的每个文本的分类号
def load_train_set(path, class_tag):
    allfiles = os.listdir(path)
    processed_text_set = []
    all_class_tag = []
    for file in allfiles:
        print(file)
        path_name = path + "/" + file
        processed_text_set.append(pre_process(path_name))
        all_class_tag.append(class_tag)
    return processed_text_set, all_class_tag


# 将文件加载进来
processed_data1, class1 = load_train_set("/hotel", "宾馆")
processed_data2, class2 = load_train_set("/travel", "旅游")
train_data = processed_data1 + processed_data2
class_tag_list = class1 + class2

# 词向量
count_vector = CountVectorizer()
# 词语转换为词频
vector_matrix = count_vector.fit_transform(train_data)

# 特征工程 TFIDF度量模型,可以做特征提取统计
train_tfidf = TfidfTransformer(use_idf=False).fit_transform(vector_matrix)

# 把特征放到朴素贝叶斯训练
clf = MultinomialNB().fit(train_tfidf, class_tag_list)

# 测试集
test_set = []
path = "/hotel"
allfiles = os.listdir(path)
hotel = 0
travel = 0
for file in allfiles:
    path_name = path + "/" + file
    # 词向量和特征统计出来
    new_count_vector = count_vector.transform([pre_process(path_name)])
    new_tfdif = TfidfTransformer(use_idf=False).fit_transform(new_count_vector)
    # 预测
    predict_res = clf.predict(new_tfdif)
    print(predict_res)
    print(file)
    if (predict_res == "宾馆"):
        hotel += 1
    if (predict_res == "旅游"):
        travel += 1

print("宾馆" + str(hotel))
print("旅游" + str(travel))

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值