前言

从规则模板到统计方法,再到机器学习方法,最后到深度学习算法,一起回顾NLP之意图识别的历程。


作用

1、在搜索中会用到意图
比如在baidu中搜索“怎么做龙虾馅饺子”,意图是“做饺子”,而不是“做龙虾”,搜索时以饺子为核心。

2、在问答系统中会用到意图
比如用户问“我要买从深圳到上海的机票”,意图是“买机票”,然后再在“买机票”这个领域继续去做语义识别。


进化史

一、规则模板方法

通过专家手工编写规则模板来识别意图。
比如:
     买 .* 《地名》 .* 《地名》.* 机票 =》 买机票
模板构成: 字符串、词性、正则表达式
通过匹配上述模板,即可识别出对应的意图

  • 缺点:
    1、人工编写工作量大,易冲突
    2、规则模板覆盖面较小,使用通配符可以解决一部分问题,但带来了匹配优先级的问题
    3、适用于垂直领域,在通用领域则无法推广

二、基于统计的方法

使用意图词典做词频统计,取词频最大的就是对应的意图

  • 缺点
    1、覆盖面比规则模板广,但容易误识别

三、基于语法的方法

先对句子做语法分析,找到中心动词及名词,再根据意图词典即可识别出意图来。

如:
     我要买从深圳到上海的机票

1、语法分析结果(调用哈工大的ltp:http://ltp.ai/demo.html):

NLP意图训练 nlp 意图分类_数据

2、再根据意图词典即可识别出“买机票”意图

  • 缺点:
    1、使用语法分析使得准确度更高了,但增加了语法识别的难点,日常口语的语法识别不是那么高,比如:
  • 我要买个去从深圳到上海的机票 语法分析结果:
  • NLP意图训练 nlp 意图分类_数据_02

  • 显然不是我们需要的

四、基于机器学习的方法

  • 核心步骤
  • 1、数据标注
    如:
    我要买个去从深圳到上海的机票 => 买机票
    我要买从深圳到上海的机票 => 买机票
  • 2、数据预处理
    1)对数据进行分词,推荐使用jieba分词工具
    2)去停用词,如:“的”、“个”。。。
    3)增加同义词词条,如:“机票”=“飞机票”、“买”=“购买”。。。
  • 3、训练集拆分
    通常取90%作为训练数据,10%作为测试数据
  • 4、特征提取
    用卡方检验提取每个词的特征,从而得到每一个词与当前意图类别的相关程度
    核心代码(python3):
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
 
'''
输入语料格式:
我要买去从深圳到上海的机票   0
我要买从深圳到上海的机票    0
我要去上海旅游 1
上海是个旅游的地方,我准备去  1
'''

#数据分词及去停用词之后,得到如下(padding后的结果):

data = [
['要', '买', '去', '从', '深圳', '到', '上海', '机票'], 
['要', '买', '从', '深圳', '到', '上海', '机票', ''], 
['要', '去', '上海', '旅游', '', '', '', ''], 
['上海', '是', '旅游', '地方', '准备', '去', '', '']
]


#生成word2index(过程略)
word2index = {'要':1, '买':2, '去':3, '从':4, '深圳':5, '到':6, '上海':7, '机票':8, '旅游':9, '是':10, '地方':11, '准备':12, '':0}

#word转为index表示
data = [
[1, 2, 3, 4, 5, 6, 7, 8], 
[1, 2, 4, 5, 6, 7, 8, 0], 
[1, 3, 7, 9, 0, 0, 0, 0], 
[7, 10, 9, 11, 12, 3, 0, 0]
]

lable_list = [0 , 0, 1, 1]


#使用卡方检验来选择特征
model = SelectKBest(chi2, k=5)#选择5个最佳特征
featrue = model.fit_transform(data, lable_list)

print(featrue)#最佳特征
print(model.scores_)
print(model.pvalues_)
  • 运行输出结果:
[[ 2  4  6  7  8]
 [ 2  5  7  8  0]
 [ 3  9  0  0  0]
 [10 11  3  0  0]]
[ 3.6   4.76470588  3.52173913  4.17241379  0.04347826  6.25  15.      8.        ]
[5.77795711e-02 2.90490222e-02 6.05688602e-02 4.10872245e-02  8.34827329e-01 1.24193307e-02 1.07511177e-04 4.67773498e-03]
  • 5、特征向量化
    在上述代码中一共有12个词,故特征维度设置为12.
    对应的特征转向量示例:
    featur_array = [ 2 4 6 7 8]
    =》
    featur_vector = [0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0]
    说明:featur_array中对应的数值n就是表示featur_vector[n-1]为1,其他的值为0
  • 6 使用支持向量机svm训练模型
    核心代码:
#####################svm
import sys
from sklearn import svm

#通过步骤5转换得到的特征向量
featur_vector = [
[0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0], 
[0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0], 
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], 
[0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0]
]

# SVM分类
clf = svm.SVC(C=2.0, probability=True)
clf.fit(featur_vector, lable_list)
print('Test Accuracy is: %.2f' % clf.score(featur_vector, lable_list))

可以看到输出结果是:
Test Accuracy is: 1.00

  • 特别说明:
    在步骤4中,可以加一些人工特征,比如把地点都使用词性ns表示,同义词使用相同的index表示等

五、基于深度学习方法

  • 核心思想
    把意图识别看成是文本分类任务。
  • 核心步骤
  • 1、预料标注
    同上
  • 2、分词
    同上
  • 3、搭建模型
  • 优点:
    1、数据标注比较容易
    2、在有充足的数据下,模型的准确率最高,无需人工特征