紧急通知:因骑士官方网站改版升级,部分介绍页面重新整理,给您带来的不便敬请谅解,我们正在紧急恢复中,请您耐心等待。
算法有没有价值观?知乎从技术维度给出了解释 2

词向量

将词用「词向量」表示是深度学习模型处理 NLP 问题的关键一步,我们的系统中使用 Google 提出的 word2vec 词向量模型,训练数据采用来自知乎社区 300 多万条真实的提问、评论、回答数据,内容涉及娱乐、政治、新闻、科学等各个领域,词向量维度采用 128 维,训练模型窗口大小 5。

Word2vec 的原理和使用方法这里就不做过多介绍了,有兴趣的可以阅读文献[1],Python 版本实现的可以参考 gensim官方文档。

text-cnn

TextCNN 是利用卷积神经网络对文本进行分类的算法,2014 年由 Yoon Kim 提出(见参考[3])。 TextCNN 的结构比较简单,其模型的结构如下图:

ext-cnn 网络结构

Embedding Layer——该层将输入的自然语言编码成 distributed representation,我们的模型该层使用 word2vec 预先训练好的词向量,同时该层设置为 trainable。

Convolution Layer——这一层主要是通过卷积,提取文本的 n-gram 特征,输入文本通过 embedding layer 后,会转变成一个二维矩阵,假设文本的长度为 |T|,词向量的大小为 |d|,则该二维矩阵的大小为 |T|x|d|,接下的卷积工作就是对这一个 |T|x|d| 的二维矩阵进行的。卷积核的大小一般设为 n x |d|,n 是卷积核的长度,|d| 是卷积核的宽度(LP 中通常取词向量的维度)。我们的模型中 n 取 [2,3,4,5]4 个值,每个值固定取 128 个 filter。

Max Pooling Layer——最大池化层,对卷积后得到的若干个一维向量取最大值,然后拼接在一块,作为本层的输出值。如果卷积核的 size=2,3,4,5 每个 size 有 128 个 filter,则经过卷积层后会得到 4×128 个一维的向量,再经过 max-pooling 之后,会得到 4×128 个 scalar 值,拼接在一块,最终得到一个 512×1 的向量。max-pooling 层的意义在于对卷积提取的 n-gram 特征,提取激活程度最大的特征。

Fully-connected Layer——将 max-pooling layer 后再拼接一层,作为输出结果。实际中为了提高网络的学习能力,可以拼接多个全连接层。

Softmax——根据类别数目设定节点数,我们不友善文本识别项目是二分类问题,设置一个节点,激活函数选择 sigmoid。

Bi-LSTM

CNN 最大问题是固定 filter_size 的视野,无法建模更长的序列信息,自然语言处理中更常用的是 RNN,因为 RNN 能够更好的表达上下文信息。在文本分类任务中,由于语句过长,会出现梯度消失或梯度爆炸的问题,基本的RNN网络难于处理语言中的长程依赖问题,为了解决这个问题,人们提出了 LSTM 模型。我们在对比 LSTM 和 Bi-LSTM 效果后选择了 Bi-LSTM,Bi-LSTM 从某种意义上可以理解为可以捕获变长且双向的「n-gram」信息。图 3 是 Bi-LSTM 用于分类问题的网络结构,黄色的节点分别是前向和后向RNN的输出,示例中的是利用最后一个词的结果直接接全连接层 softmax 输出了。我们的实际使用的网络结构在全联接层之后加了一层 dropout 层,dropout 输出接 sigmoid 二元分类层。RNN、LSTM、BI-LSTM 可以参考文献[4]。

用于文本分类的双向 LSTM 网络结构

我们参考论文 A C-LSTM Neural Network for Text Classification 来实现 CNN-LSTM 文本分类模型,模型的网络结构如下所示(该图直接来自论文)

CNN-ISTM 网络结构

效果

举报的内容

知友举报内容不管是直接删除还是直接忽略,都要求算法有较高的准确率(本文准确率没有特别说明的情况下指 precision),经过对比不同模型的评测效果,目前线上选用模型和准确率、召回率如下:

全量内容

经过模型调优和对比不同模型的评测效果,目前线上使用的模型和准确率、召回率如下:

后续工作

我们会利用更多数据模型,尝试更复杂定神经网络并进行语义分析。通过分析实际操作中的 bad case 可以发现,有些文本带有脏字、脏词但并不属于不友善类别,同时也存在一些很隐晦的不友善内容,主要有以下三类:

  • 影视、社会热点事件讨论中,评价影视作品中的人物或者热点事件当事人,例如:这个视频难道不是货车司机的错,有时候又想去延安路龙翔桥附近斑马线前停一天车,MDZZ 规定。

  • 陈述自己等经历,例如:我当时竟然信了,觉得当时的自己就是 FJ 。

  • 诙谐词语或反语,例如:你真聪明,连这都不会;有哪些人工 ZZ 发明。

我们会继续尝试用深度学习做语义分析,对文本进行语义角色标注(见参考文献[6]),抽取句子的施事者(Agent)、受事者(Patient)、客体及其对应的描述词;通过语义相似度构建语义词典;将语义信息融合到我们的不友善文本识别模型中。

参考文献:

  • [1]https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf

  • [2] https://radimrehurek.com/gensim/models/word2vec.html

  • [3]https://arxiv.org/abs/1408.5882

  • [4]https://blog.csdn.net/zzulp/article/details/79379960

  • [5]https://arxiv.org/pdf/1511.08630.pdf

  • [6] Chinese semantic role labeling with shallow parsing

  • 算法在社区氛围的应用(三): 机器学习在答非所问识别上的运用

    跳绳的好处有哪些?可以锻炼哪些肌肉?

    A:心肺功能比之前有提高。

    B:有助于提高身体的乳酸阈值。

    C:有助于提高身体的协调性。

    D:谢谢,我去买了跳绳。

    请问,以上哪个答案是答非所问?

    现在,瓦力可直接识别并处理该题中的答非所问内容。

    我们鼓励认真、专业的分享,期待每一次讨论都能碰撞出更多有价值的信息,并希望每一个用心的回答都能够得到好的展示,为他人带来更多帮助。但是,我们也发现在社区中出现了答非所问类的内容,影响知友们获取有价值内容的效率。

    为了更好地识别答非所问类内容,我们采用了多种模型,包括传统的机器学习模型和比较新的深度学习模型。通过前期对语料的分析,我们发现语言用词、作者历史行为、知友对内容的反馈信息等都具有比较明显的区分度,因而我们尝试使用特征工程和传统机器学习方法实现了瓦力识别答非所问的第一版模型,并达到了一个相对不错的效果。

    Random Forest

    随机森林 (Random Forest) 是树模型里两个常用模型之一(另一个是 Gradient Boosting Decision Tree)。顾名思义,就是用随机的机制建立一个森林,森林由多棵分类树构成。当新样本进入时,我们需要将样本输入到每棵树中进行分类。打个形象的比喻,知乎森林召开议会,讨论@刘看山

    到底是狗还是北极狐(看山,我知道你是北极狐的,手动捂脸逃…),森林中的每棵树都独立发表了自己对这个问题的观点,做出了自己的判断。最终刘看山是狗还是北极狐,要依据投票情况来确定,获得票数最多的类别就是这片森林对其的分类结果。如同图一所示意境。

    森林会议

    样本

    通过训练语料和业务数据,进行特征工程,提取出了以下三类特征:

    • 回答和问题的文本特征:如二者的词向量、词向量相似度、关键词相似度、话题相似度等;

    • 回答的统计特征:如回答的赞同、反对、评论、举报等是用户对其的交互特征;

    • 回答作者的统计特征:正向行为,如关注、回答、提问、评论、举报等,负向行为,如回答被赞同、被反对、被感谢、被举报等。

    同时,通过历史积累、用户标注、策略生成产生出了训练样本集,然后用以上特征类别表示出每条样本。

    分类树

    使用随机有放回抽样选取每棵树的训练样本,随机选取 m 个特征 (m < 总特征数) 进行无限分裂生长,成长为能独立决策的树。

    投票决策

    通过建好的多棵分类树,对新的样本进行决策投票,获得最终的分类结果。

    对于 Random Forest 的实现,有很多优秀开源的实现,在实际中我们封装了 Spark 中的 Random Forest 完成了模型的迭代。最终取得了 Precision 97%,Recall 58% 左右的不错结果。

    细心的知友可能注意到了,我们的特征里有一类特征是与时间和回答的暴光有关的,即回答和作者的统计特征。为此我们在现有模型的基础上分析了这类特征的时间累积效果,如图二所示。从图中可以看到,经过一天的统计特征累积,Precision 达到了 90%,但 Recall 只有 40%,可以说这一天时间对于 40% 的答非所问有了比较充分的特征积累以支撑对其的准确判断。而随时间的增加,基本上 Precision 和 Recall 都有提升。但并不是时间越长,提升越多。

    最终我们结合产品应用层面和算法阈值,分别选出两个时间点,一方面牺牲 Recall 快速识别处理一部分答非所问的回答,另一方面允许一定的处理延时,保证了大量的 Recall,大大净化了回答区域的无关内容。

    统计特征累积周期(天)对 Precision 和 Recall 的影响

    传统机器学习的一个核心内容就是特征工程,包括特征提取、特征选择等。

    • 特征提取:从原始数据出发构造出特征,通常包括业务和对语料的统计分析。

    • 特征选择:从提取出的候选特征中挑选出有用的特征。

    但特征工程总是会耗费比较多的时间,而且在答非所问的识别中一些时间相关的特征,还延长了处理周期,不利于快速处理。而广为流传的深度学习,能自动对输入的低阶特征进行组合、变换,映射到高阶的特征,这也促使我们转向深度学习进行答非所问的识别。

    深度学习兴起于图像识别,其过程可以引用图三[1] 大致描绘,输入特征,经隐藏层逐层抽象、组合,最后经输出层得出识别结果。

    深度学习示意

    相较于图片天然的像素表征,可以直接输入到深度神经网络里,文本需要进行向量化后方可作为网络的输入。关于「词向量化」的精彩描述可以参考[2]。此处我们抽取了知乎社区 1000 多万真实的文本信息,包括问题、回答、文章、评论等数据,利用 Facebook 开源的 FastText 训练了 256 维的词向量和字向量。对于 FastText 的原理和用法此处不作详细阐述,感兴趣的朋友可以参考[3]。

    CNN 网络 (Convolutional Neural Network)

    我们模型的网络结构基本上采用了 Severyn[4] 提出的网络结构,但在一些细节上做了些改动,比如图四中的 CNN-answer/question, 我们结合了 Wide & Deep[5] 的思想,以提取更为丰富的语义信息。

    模型结构

    Embedding Layer——该层利用预训练好的 FastText 词向量将原始词序列表达成词向量序列

    Convolutional Layer——此层主要通过卷积操作,同时捕获类似于 N-Gram 特征(但同 N-Gram 还是有差异的)。我们的模型选取了 [2, 3, 4, 5, 6] 5 个卷积核宽度,为每个卷积核配置了 64 个 filter

    Pooling Layer——池化层,对经过卷积操作提取的特征进行 Sampling。此处我们采用了 K-Max-Average pooling,对卷积层提取的特征,选择出激活程度 top-K 的特征值的平均值作为 pooling 的结果

    Feature Join & Fully connected Layer——将前述几层获得的特征,以及额外信息进行融合,作为最终的特征输出,以便于最后的决策判断。实际上,我们在 Fully Connection 后面加了 3 层 Dense Layer,以提高网络的表达能力。

    Softmax——将最后的特征转换成二分类决策概率。

    最终训练好该模型,在验证集上达到了 Precision 78%, Recall 80% 的效果。Recall 虽有比较大的提升,但 Precision 并没有前文描述的 Random Forest 的方法好。

    效果

    目前,答非所问几个模型都上线到了知乎产品的诸多场景下,如反对、举报、专项清理等。每天清理约 5000 条新产生的「答非所问」内容,以及此前现存的 115 万条「答非所问」内容。

    参考文献:

    • [1] Breaking it down: A Q&A on machine learning

    • [2] 词向量和语言模型

    • [3] FastText

    • [4] Learning to rank short text pairs with convolutional deep neural networks

    • [5] Wide & Deep Learning for Recommender Systems

    关于作者

    吴怼怼,微信公众号:吴怼怼(esnql520),站长之家专栏作者。资深媒体人,专注互联网内容、品牌与公关领域个性解读。