浅谈意图识别各种实现&数学原理
\]
目前的智能客服会话的难点是进行用户意图匹配,只有明确了意图,才能给出针对性的回答。如果匹配不了意图,再进入传统问答机器人到语料库,所有或者其他各种方式匹配得分最高预料答案进行回答。
所以下面将针对意图识别的一般性原理进行讲解和分析。
意图识别
对于在线机器人而言,就是判断用户此次咨询的问题分类。
例如,这张票不要了
->退票
,我的订单出票了没
->催出票
,我要预订明天的机票
->帮下单
等等。一般会使用下面几种方式进行提取。
基于命名实体提取和词库
例如我的订单出票了没
,使用HanLp
自然语言处理工具包, 会抽取以下2个词语
订单
、出票
,根据停用词词典去除掉订单
,然后根据出票
到词库中进行匹配对应的分类,找到对应意图催出票
。对于复杂的句子,可以统计词频,根据频率最高的找到对应的分类意图。
使用这种方式优点是操作方便,用搜索的方式很快找出对应的意图。但缺点也很明显,比如 这个订单还没出票,没出票不要了
,意图是退票,很明显提取出来的是错误。准确率很难做到较高。
所以此种方式一般作为机器学习意图槽位数据提取。
基于模板的匹配
查询非常符合规则的类别,通过规则解析的方式来获取查询的意图。
帮我预订明天的苏州到北京的机票,可以使用规则模板,进行如下提取
[苏州]到[北京][明天][机票]。
这种方使用需要借助命名实体提取,词性标准,语义分析才能完成,对于规则性比较强的咨询有较好的准确率。但此种方式对于研发和训练师需要做大量的工作,较难进行扩展。
基于机器学习
逻辑回归
意图识别在机器学习中的分类问题,也就是使用逻辑回归进行分类。
在使用逻辑回归之前,首先要对词语进行分词,向量化。 分词可以比较各个分词的效果,最常用是jieba
分词。支持配置专业名词及停用词。
分词完成后,需要将词与进行向量化。
一般有2种方式,一种是使用One-Hot编码,这种方式一般针对专业性比较强的领域使用,另一种是word2vec,这种编码方式可以很好的标识词之间的关系。
one-hot编码一半般将所有词行列进行排列,相同的地方记做1,比如分词完成后,按照词频排序结果如下:
– | 订单 | 出票 | 取消 |
---|---|---|---|
订单 | 1 | 0 | 0 |
出票 | 0 | 1 | 0 |
取消 | 0 | 0 | 1 |
那么[订单,出票,取消]得到的词向量为[[1,0,0],[0,1,0],[0,0,1]]
假如一个句子是这个订单还没出票,没出票不要了
,订单出现一次,出票出现2次,这个句子最终的向量为
\]
使用word2vec得到的结果类似。
针对意图识别,一般是多类分类。但多分类问题是从二分类问题进行扩展。
二元分类
对于二分问题,在对于未知概率分布条件下,一般假设为正态分布(高斯分布),多维高斯分布如下,也是多个高斯分布相乘得到的结果。
\]
带入贝叶斯公式,最终得到是关于w,b的函数,也是sigmoid
函数。
=\frac{1}{1+e^{-z}}=\frac{1}{1+e^{-(b+\sum\limits_k w_k x_k)}}=f(w,b)=\sigma(z)
\]
对于数据量较少的分类,可以使用生成模型(Generative Model),计算\(P(C_1),P(C_2)\)和各个分类样本数据的均值 \(u\) 和共用协方差矩阵\(\Sigma\),即可得到w,b,对于任意输入x
\]
代表数据分类属于\(C_1\),否则属于\(C_2\)。由于是二元分类,不必单独计算\(P(C_2|x)\)。
但针对数据量较多的情况,一般使用判别模型(Discriminative Model),
针对二分类问题,根据最大拟然估算,Loss函数为
\]
所有就是要找到\(w,b\),使得
\]
为了计算方便,将公式取对数
-ln(L(w,b))=-ln(f_{w,b}(x_1))-ln(f_{w,b}(x_2))-….-ln(f_{w,b}(x_n)
\]
由于C1和C2的概率表达式不统一,上面的式子无法写成统一的形式,为了统一格式,这里将所有Training data都打上0和1的标签, y = 1代表 \(C_1\), y= 0代表\(C_2\),于是上式进一步改写成:
-[y_2*ln(f_{w,b}(x_2)) – (1-y^2)*ln(1-f_{w,b}(x_2)]
-….\\
= \sum_{n=0}^m-[y^nlnf_{w,b}(x_n)-(1-y)^nln(1-f_{w,b}(x_n))]
\]
这个形式其实就是两个分布的交叉熵
\]
表示个概率分布有多接近。
下面就是对这个loss函数使用梯度下降求解最小值,对w,b微分最终得到每次更新的梯度,
b_i = b_{i-1} – \eta \sum_{n}-(y_n-f_{w,b}(x_n)) \\
\]
最终得到w,b,带入sigmoid
函数即可得到结果。
另外,一般情况下判别模型比生成模型要高。
以上二元分类的情况,对于多元分类问题,其原理的推导过程与二元分类基本一致。
多分类
假设我们用的是高斯分布,共用协方差矩阵,经过一般推导,也就是各种变换后,可以得到一个softmax函数。
假设有三个分类:\(C_1,C_2,C_3\),每一个\(C_i\)都有自己的\(w_i\)和\(b_i\),\(w_1,w_2,w_3\)分布代表三个向量,\(b_1,b_2,b_3\)分别代表三个常量,输入 x也是一个向量。
用softmax
进行输出正则化。softmax
计算方式如下:
sum = \sum_{j=1}^3 e^{z_j} \\
y^1 = \frac {e^{z_1}}{sum} 、y^2 = \frac {e^{z_2}}{sum} 、y^3 = \frac {e^{z_3}}{sum}
\]
z可以是任何值,但是做完softmax之后,输出 的值一定是介于0~1之间,并且它们的和一定是1。
多分类任务中输出的是目标属于每个类别的概率,所有类别概率的和为1,其中概率最大的类别就是目标所属的分类。
即二分类使用sigmoid
函数输出得到结果,而多分类使用softmax得到结果。
如下图所示,input x经过三个式子分别生成,经过softmax转化成output ,它们分别是这三个 分类的概率,由于sum=1,因此做完softmax之后就可以把y的分布当做是一个概率分布。
我们在训练的时候还需要有一个输出,因为是三个分类,输出是三维的,对应的输出也是三维的,为了满足交叉熵的条件,输出也必须是概率分布,这里我们不能使用1,2,3作为分类的区分,为了保证所有分类之间的关系是一样的,这里使用类似于one-hot编码的方式。
和二元分类求解一样,利用交叉熵,最终通过微分得到最优\(w_1,w_2,w_3\),\(b_1,b_2,b_3\)。
神经网络
对于输入参数比较复杂,比如对于word2vec,输入的可能是一个100*100的矩阵,这个时候就需要对数据进行处理。或者输入的特征无法在数据源上进行数据处理。这个时候就需要在逻辑回归之前再接上一个逻辑回归,对数据源做处理。
多个逻辑回归就构成了一个类神经网络,也就是深度学习,如(CNN,LTSM)。
对于分类问题,深度学习的最后输出函数也就是sigmoid
或者softmax
函数。
对话管理
通过上一次的语义抽取和意图识别,对话会进入后续对话树模块。
根据前一模块抽取数据和用户本身数据,将数据填充到对话树的对应部分,对话数节点也可以根据条件拉取其他数据,最终这些数据最终都会在当前会话中保存。
可以根据用户问题,如果条件满足,通过NLG模块生成对应话术返回。
最终一次用户会话的完整的流程
graph LR
A[用户提问]-->B[语义分析&实体抽取]
B--> C[意图识别]
C-->D[对话树数据填充]
D-->E[NL生成]
E-->F[数据处理]
F-->G[答案返回]
总结
上面是自己在机器学习中的一些总结,欢迎大家多多交流。