- Understand doc2vec
- Data introduction
- Train a model
- Test the model
- Cluster all the lyrics
- Filter out the duplicates
1. Understand doc2vec [1]
doc2vec是基于word2vec演化而来,其本质是要学出文档的一个表示,模型由谷歌科学家Quoc Le 和 Tomas Mikolov 2014年提出,并将论文发表在International Conference on Machine Learning上。由于word2vec的训练一般有两种策略:(1) 已知上下文,推测下一个词;就是本文中的CBOW (2) 已知当前词,推测上下文,也就是常说的skip-gram。
1.1 基于CBOW的word2vec
给定一条文本包含文字:w1,w2,w3,…wT, 那么word2vec的目标函数就是最大化概率函数
目标函数很好理解,本质上是给定窗口大小的n-gram。那么用什么数据训练模型呢?模型的输入和输出其实就是一个二元组[上下文,预测词]。就是用很多这样的二元组来训练模型。例如,给定句子:秋天傍晚小街路面湿润。假定分词结果为[秋天,傍晚, 小街, 路面, 湿润],现在要预测小街,窗口大小为2, 那么用来训练模型的数据集包括[秋天,小街],[傍晚,小街], [路面,小街], [湿润,小街]。
那么预测词的取值空间其实是整个词袋,因此预测某一个词可以被视为一个多分类问题,假如词袋一共有1000个词,那么其实wordvec的训练过程就是一个1000-类 分类问题。因此一般来说,词预测,也就是在神经网络的最后一层,使用softmax。
由于1000-类这样的分类问题显然直接用线性模型效率会非常低,何况一般的词袋都会有上万词,因此目前比较常用的方法是最后的输出层采用层次softmax将时间效率缩减到O(logn),其本质是一棵霍夫曼树。详细的解释以及负采样可以看一下这篇:
https://blog.youkuaiyun.com/zhangxb35/article/details/74716245。
其实word2vec要求的并不是output layer,而是为了得到hidden layer,在训练结束后,隐层的权重矩阵其实是一个NxM的矩阵,N是词的个数,M是embedding的维度,这个矩阵才是我们想要训练出来的。word2vec的训练保证了相近词义的词在向量空间中的距离更近。这也避免了词袋模型不考虑语序和语义的问题。
1.2 基于CBOW的doc2vec
为了得到文档的向量表示,科学家给原来的模型增加了一个输入向量,即文档id。其背后的思想可以解释为,预测一个词与文档本身整体的含义是分不开的,这等于是我们阅读理解以前只考虑近距离上下文,现在需要加入文章的主题来理解一个词。模型图如下
该算法包括两个步骤:
- 在已有的文档上,训练词向量W, softmax 权重 U, b 以及文档向量 D。
- 如果有新的文档加入,那么推断环节就是保持W, U, b不变,只训练D。
2. Data introduction.
本文所用数据集为歌词数据,包含约14万条中文歌词,目的是为了不同歌手间的相同歌词去重(比如翻唱改编等)。因此采用先训练doc2vec,再将文本聚类,最终在类中进行歌词比对去重的方式。
数据格式为json,其中一条数据:
{
"artist_id": 1,
"author": "李宇春",
"title": "Dance To The Music",
"song_id": 119548568,
"album_title": "1987我不知会遇见你",
"album_id": 117854447,
"language": "国语",
"versions": NaN,
"country": "内地",
"area": 0.0,
"file_duration": 215,
"publishtime": "2014-7-30",
"year": 2014.0,
"month": 7.0,
"date": 30.0,
"publish_time": "2014/7/30",
"hot": 2011,
"listen_total": 378.0,
"lyrics": {
"status": "OK",
"content": {
"[00:02.00]": "Dance To The Music",
"[00:04.00]": "作曲 张亚东",
"[00:05.00]": "作词:李宇春",
"[00:06.00]": "演唱:李宇春",
"[00:08.00]": "",
"[00:16.57]": "Dance to the music",
"[00:20.64]": "Dance to the music",
"[00:24.64]": "Dance to the music",
"[00:28.78]": "Dance to the music",
"[00:33.11]": "音乐要开最大声才够酷",
"[00:36.65]": "酷毙那些熏陶出的严肃",
"[00:41.20]": "跳级跳槽不如先跳个舞",
"[00:45.20]": "踩着节奏慢半拍也挺态度",
"[00:49.17]"<