深度学习在诸多方面,如图像分割、时序预测和自然语言处理,都优于其他机器学习方法。嵌入(embedding),即用连续向量表示离散变量的方法,在其中起到了不可或缺的作用。像机器翻译中的词嵌入和分类变量中的实体嵌入,都是嵌入的成功应用。
本文将围绕什么是神经网络嵌入、为什么要使用神经网络嵌入以及神经网络嵌入如何学习这三方面进行详细地讲解。相关概念已在之前的工作——将Wikipedia中所有图书转变为向量并构建图书推荐系统中进行了详细讲解。
Neural Network Embedding of all books on Wikipedia. (From Jupyter Notebook on GitHub).
嵌入(Embeddings)
在神经网络中,嵌入后的数据维度较低,它能将离散的序列映射为连续的向量。
神经网络嵌入的主要用途有三种:
在嵌入空间中找到最近邻。
作为有监督的机器学习模型的输入。
挖掘变量间的关系。
利用神经网络嵌入,我们能将Wikipedia中的37000多本书转换为至多包含50个数值的向量。
神经网络嵌入还克服了独热编码的局限性。
独热编码(One-Hot Encoding)的局限性
独热编码用于处理类别变量的最简单的嵌入方法,能够将不同的类别映射为不同的向量。独热编码保证了每一个取值只会使得一种状态处于“激活态”,也就是说这N种状态中只有一个状态位值为1,其他状态位都是0。
独热编码有两大缺陷:
当类别的数量很多时,特征空间会变得非常大。映射后的向量容易产生维数灾难。
“相似”的类别映射在嵌入空间后并不相邻。
第一个问题很容易理解:多一个类别,在进行独热编码的时候就会多一维向量。Wikipedia中共包含37000本书,对于每本书来说,向量的维度都为37000,这将无法对任何机器学习模型进行训练。
第二个问题同样带来了很大的局限性:独热编码并没有让相似的类别在嵌入空间中相邻。在进行独热编码后,利用余弦相似度计算出的向量间的相似度均为0。
也就是说,如果使用独热编码,电影《战争与和平》和《安娜卡列尼娜》之间的相似性并不会比《战争与和平》和《银河系漫游指南》相似性强,但这与实际不符。
考虑到上述局限性,在类别变量不多的情况下,可优先考虑独热编码。
为了更好的处理类别变量,我们将使用嵌入神经网络和有监督的方法来学习嵌入。
学习嵌入(Learning Embeddings)
独热编码的主要问题是转换不受任何监督。通过在有监督的任务中使用神经网络学习嵌入,可以大大提高嵌入能力。权重是学习嵌入过程中的重要参数,起调节作用以最小化损失函数。
举个例子,在电影评论中收集到50000个单词,每一个单词我们都可以使用100维的向量对其进行表示,进而使用嵌入神经网络对其进行训练以获取评论的情感倾向。如“brilliant”或“excellent”均与“positive”评价有很强的关联,在嵌入空间的位置便会更为邻近。
Movie Sentiment Word Embeddings (source)
在上述图书推荐的示例中,有监督的任务可以是“确定一本书是否由列夫托尔斯泰撰写”,在嵌入空间上,托尔斯泰所写的书彼此更为邻近。嵌入中最为棘手的问题是:如何创建有监督的任务模型并得出通用单词或句子的表征。
实现(Implementation)
在Wikipedia图书推荐项目中,有监督的学习任务是:预测某个Wikipedia页面的链接是否出现在一本书的某一章节中。输入成对的训练示例,格式为(book title,link),其中的匹配有positive-true以及negative-false两种形式。初始化设置基于这样的假设:链接到相似的Wikipedia页面的两本书也是相似的,并且相似的书目在向量空间上更为邻近。
我们使用包含两个并行嵌入层的神经网络,它能够将书和wikilink映射为50维向量,还有一个点积层,将嵌入结果整合为单个数字以实现预测。
部分代码如下:
# Both inputs are 1-dimensional book = Input(name = 'book', shape = [1]) link = Input(name = 'link', shape = [1]) # Embedding the book (shape will be (None, 1, 50)) book_embedding = Embedding(name = 'book_embedding', input_dim = len(book_index), output_dim = embedding_size)(book) # Embedding the link (shape will be (None, 1, 50)) link_embedding = Embedding(name = 'link_embedding', input_dim = len(link_index), output_dim = embedding_size)(link) # Merge the layers with a dot product along the second axis (shape will be (None, 1, 1)) merged = Dot(name = 'dot_product', normalize = True, axes = 2)([book_embedding, link_embedding]) # Reshape to be a single number (shape will be (None, 1)) merged = Reshape(target_shape = [1])(merged) # Output neuron out = Dense(1, activation = 'sigmoid')(merged) model = Model(inputs = [book, link], outputs = out) # Minimize binary cross entropy model.compile(optimizer = 'Adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
尽管有监督的机器学习任务的目的在于训练模型后能运用于新的数据集,在本文的嵌入模型中,这些预测只是达到目的的一种手段。我们想要的是那些能够将书本和链接转化为连续向量的权重。
嵌入本身并不是那么有趣,它们只是一些向量:
对于这个项目,我们探究的是如何根据最近邻推荐书籍。为了计算相似度,我们选择一本书,计算它与所有书目的点积。(如果我们的嵌入是标准化的,点积为向量之间的余弦距离从-1,即最不相似,到+1,即最相似。此外还可以使用欧几里德距离来测量相似度)。
下图是我所构建的图书推荐系统的结果:
下图为图书降低维度后的结果:
Embedding Books with Closest Neighbors
Wikipedia上的每一本书都能用50位数字进行表示,相似图书彼此之间更接近。
嵌入可视化(Embedding Visualizations)
嵌入的优点是可以将所学到的嵌入进行可视化,以显示哪些类别是相似的。将这些权重的维度降低为 2-D 或 3-D。然后,在散点图上可视化这些点,以查看它们在空间中的分离情况。目前最流行的降维方法是——t-Distributed Stochastic Neighbor Embedding (TSNE)。
我们将37000维的图书通过神经网络嵌入映射为50维,接着使用TSNE将维数将至为2。
Embedding of all 37,000 books on Wikipedia
TSNE是一种流形学习方法,用来降低高维数据的维度,进而对数据可视化,了解数据的分布,发现可能存在的规律。除了TSNE,UMAP(Uniform Manifold Approximation and Projection)也是目前较为流行的降维方法。
下图展示了降维后图书在向量空间中的分布情况:
通过颜色对书本类型进行区分,可以快速的找出相似流派的书籍。
Wikipedia图书推荐的示例说明了神经网络嵌入的价值:能够以低维向量的形式表示分类对象,并且在嵌入空间中相似的实体彼此相邻。
交互式可视化(Interactive Visualizations)
刚才所展示的图片均为静态效果,为了更好的查看变量之间的关系,点击此处以获取动态效果。
总结
神经网络嵌入能够将离散的数据表示为连续的低维向量,克服了传统编码方法的局限性,能查找最近邻,作为另一个模型的输入以及进行可视化,是处理离散变量的有效工具,也是深度学习的有效应用。
文章原标题《Neural Network Embeddings Explained》,作者:William Koehrsen,译者:云栖社区 Elaine,审校:袁虎。