文章目录
笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP
13. 深度学习与自然语言处理
13.1 传统方法的局限
前面已经讲过了隐马尔可夫模型、感知机、条件随机场、朴素贝叶斯模型、支持向量机等传统机器学习模型,同时,为了将这些机器学习模型应用于 NLP,我们掌握了特征模板、TF-IDF、词袋向量等特征提取方法。而这些方法的局限性表现为如下:
-
数据稀疏
首先,传统的机器学习方法不善于处理数据稀疏问题,这在自然语言处理领域显得尤为突出,语言是离散的符号系统,每个字符、单词都是离散型随机变量。我们通常使用独热向量(one-hot)来将文本转化为向量表示,指的是只有一个元素为1,其他元素全部为 0 的二进制向量。例如:
祖国特征: [“中国”,“美国”,“法国”] (这里 N=3)
中国 => 100
美国 => 010
法国 => 001
上面的祖国特征只有 3 个还好,那如果是成千上万个呢?就会有很多的 0 出现,表现为数据的稀疏性。
-
特征模板
语言具有高度的复合型。对于中文而言,偏旁部首构成汉字,汉字构成单词,单词构成短语,短语构成句子,句子构成段落,段落构成文章,随着层级的递进与颗粒度的增大,所表达的含义越来越复杂。
这样的特征模板同样带来数据稀疏的困扰: 一个特定单词很常见,但两个单词的特定组合则很少见,三个单词更是如此。许多特征在训练集中仅仅出现一次,仅仅出现一次的特征在统计学上毫无意义。
-
误差传播
现实世界中的项目,往往涉及多个自然语言处理模块的组合。比如在情感分析中,需要先进行分词,然后进行词性标注,根据词性标注过滤掉一些不重要的词,最后送入到朴素贝叶斯或者支持向量机等机器学习模块进行分类预测。
这种流水线式的作业方式存在严重的误差传播问题,亦即前一个模块产生的错误被输入到下一个模块中产生更大的错误,最终导致了整个系统的脆弱性。
13.2 深度学习与优势
为了解决传统机器学习与自然语言处理中的数据稀疏、人工特征模板和误差传播等问题,人们将注意力转向了另一种机器学习潮流的研究–深度学习。
-
深度学习
深度学习(Deep Leaming, DL )属于表示学习( Representation Learning )的范畴,指的是利用具有一定“深度”的模型来自动学习事物的向量表示(vectorial rpresenation)的一种学习范式。目前,深度学习所采用的模型主要是层数在一层以上的神经网络。如果说在传统机器学习中,事物的向量表示是利用手工特征模板来提取稀疏的二进制向量的话,那么在深度学习中,特征模板被多层感知机替代。而一旦问题被表达为向量,接下来的分类器一样可以使用单层感知机等模型,此刻深度学习与传统手法毫无二致,殊途同归。所以说深度学习并不神秘,通过多层感知机提取向量才是深度学习的精髓。
对于深度学习原理,在之前我的博客中已经介绍了,详细请点击:
http://mantchs.com/2019/08/04/DL/Neural%20Network/
-
用稠密向量解决数据稀疏
神经网络的输出为样本 x 的一个特征向量 h。由于我们可以自由控制神经网络隐藏层的大小,所以在隐藏层得到的 h 的长度也可以控制。即便输人层是词表大小的独热向量、维度高达数十万,隐藏层得到的特征向量依然可以控制在很小的体积,比如100维。
这样的 100 维向量是对词语乃至其他样本的抽象表示,含有高度浓缩的信息。正因为这些向量位于同一个低维空间,我们可以很轻松地训练分类器去学习单词与单词、文档与文档、图片与图片之间的相似度,甚至可以训练分类器来学习图片与文档之间的相似度。由表示学习带来的这一切, 都是传统机器学习方法难以实现的。
-
用多层网络自动提取特征表示
神经网络两层之间一般全部连接(全连接层),并不需要人们根据具体问题具体设计连接方式。这些隐藏层会根据损失函数的梯度自动调整多层感知机的权重矩阵,从而自动学习到隐陬层的特征表示。
该过程完全不需要人工干预,也就是说深度学习从理论上剥夺了特征模板的用武之地。
-
端到端的设计
由于神经网络各层之间、各个神经网络之间的“交流语言”为向量,所以深度学习工程师可以轻松地将多个神经网络组合起来,形成一种端到端的设计。比如之前谈到的情感分析案例中,一种最简单的方案是将文档的每个字符的独热向量按顺序输入到神经网络中,得到整个文档的特征向量。然后将该特征向量输入到多项逻辑斯谛回归分类器中,就可以分类出文档的情感极性了。
整个过程既不需要中文分词,也不需要停用词过滤。因为神经网络按照字符顺序模拟了人类阅读整篇文章的过程,已经获取到了全部的输人。
13.3 word2vec
作为连接传统机器学习与深度学习的桥梁,词向量一直是入门深度学习的第一站。词向量的训练方法有很多种,word2vec 是其中最著名的一种,还有 fastText、Glove、BERT和最近很流行的 XLNet 等。
-
word2vec 的原理在我博客里已经讲解过了,详细介绍见:
-
训练词向量
了解了词向量的基本原理之后,本节介绍如何调用 HanLP 中实现的词向量模块,该模块接受的训练语料格式为以空格分词的纯文本格式,此处以 MSR 语料库为例。训练代码如下(自动下载语料库):
from pyhanlp import * import zipfile import os from pyhanlp.static import download, remove_file, HANLP_DATA_PATH def test_data_path(): """ 获取测试数据路径,位于$root/data/test,根目录由配置文件指定。 :return: """ data_path = os.path.join(HANLP_DATA_PATH, 'test') if not os.path.isdir(data_path): os.mkdir(data_path) return data_path ## 验证是否存在语料库,如果没有自动下载 def ensure_data(data_name, data_url): root_path = test_data_path() dest_path = os.path.join(root_path, data_name) if os.path.exists(dest_path): return dest_path if data_url.endswith('.zip'): dest_path += '.zip' download(data_url, dest_path) if data_url.endswith('.zip'): with zipfile.ZipFile(dest_path, "r") as archive: archive.extractall(root_path) remove_file(dest_path) dest_path = dest_path[:-len('.zip')] return dest_path sighan05 = ensure_data('icwb2-data', 'http://sighan.cs.uchicago.edu/bakeoff2005/data/icwb2-data.zip') msr_train = os.path.join(sighan05, 'training', 'msr_training.utf8') ## =============================================== ## 以下开始 word2vec IOUtil = JClass('com.hankcs.hanlp.corpus.io.IOUtil') DocVectorModel = JClass('com.hankcs.hanlp.mining.word2vec.DocVectorModel'