浅谈意图识别各种实现&数学原理

\[ J_\alpha(x) = \sum_{m=0}^\infty \frac{(-1)^m}{m! \Gamma (m + \alpha + 1)} {\left({ \frac{x}{2} }\right)}^{2m + \alpha} \text {}
\]

目前的智能客服会话的难点是进行用户意图匹配,只有明确了意图,才能给出针对性的回答。如果匹配不了意图,再进入传统问答机器人到语料库,所有或者其他各种方式匹配得分最高预料答案进行回答。

所以下面将针对意图识别的一般性原理进行讲解和分析。

意图识别

对于在线机器人而言,就是判断用户此次咨询的问题分类。
例如,这张票不要了->退票,我的订单出票了没->催出票我要预订明天的机票->帮下单等等。一般会使用下面几种方式进行提取。

基于命名实体提取和词库

例如我的订单出票了没,使用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次,这个句子最终的向量为

\[\begin{bmatrix}1 \\ 0 \\0\end{bmatrix} + \begin{bmatrix}0 \\ 1 \\0\end{bmatrix} + \begin{bmatrix}0 \\ 1 \\0\end{bmatrix} =\begin{bmatrix}1 \\ 2 \\0\end{bmatrix}
\]

使用word2vec得到的结果类似。

针对意图识别,一般是多类分类。但多分类问题是从二分类问题进行扩展。

二元分类

对于二分问题,在对于未知概率分布条件下,一般假设为正态分布(高斯分布),多维高斯分布如下,也是多个高斯分布相乘得到的结果。

\[f_{u,\Sigma}(x)=\frac{1}{(2\pi)^{\frac{D}{2}}}\frac{1}{|\Sigma|^{\frac{1}{2}}}e^{-\frac{1}{2}(x-u)^T\Sigma^{-1}(x-u)}
\]

带入贝叶斯公式,最终得到是关于w,b的函数,也是sigmoid函数。

\[P(C_i|x)=\frac {P(C_i)P(x|C_i)}{\sum_{j=0}^n{P(C_i)P(x|C_i)}}
=\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

\[P(C_1|x) = f_{w,b}(x)>0.5
\]

代表数据分类属于\(C_1\),否则属于\(C_2\)。由于是二元分类,不必单独计算\(P(C_2|x)\)

但针对数据量较多的情况,一般使用判别模型(Discriminative Model),
针对二分类问题,根据最大拟然估算,Loss函数为

\[L(w,b) = f_{w,b}(x_1)f_{w,b}(x_2)…f{w,b}(x_n)
\]

所有就是要找到\(w,b\),使得

\[w^*,b^* = argmaxL(w,b)
\]

为了计算方便,将公式取对数

\[w^*,b^* = argmaxL(w,b)=argmin(-ln(L(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\),于是上式进一步改写成:

\[-ln(L(w,b))=[y_1*ln(f_{w,b}(x_1)) – (1-y_1)*ln(1-f_{w,b}(x_1))]\\
-[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))]
\]

这个形式其实就是两个分布的交叉熵

\[H(p,q) = -\sum_{x}p(x)ln(q(x))
\]

表示个概率分布有多接近。
下面就是对这个loss函数使用梯度下降求解最小值,对w,b微分最终得到每次更新的梯度,

\[w_i = w_{i-1}-\eta\sum_{n}-(y_n-f_{w,b}(x_n))x_n \\
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计算方式如下:

\[z_1=w_1 *x +b_1,z_2=w_2 *x +b_2,z_3=w_3 *x +b_3 \\
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编码的方式。

image

和二元分类求解一样,利用交叉熵,最终通过微分得到最优\(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[答案返回]
总结

上面是自己在机器学习中的一些总结,欢迎大家多多交流。