文本表示

Posted on By Jason Hao

宏观理解

我们在文本预处理完之后就要喂给机器进行学习了,那么肯定不能直接给,我们怎么让机器能学习这些文本呢?就要把这些文本进行 一些编码,我们要争取让这些编码所含的信息越多越好,比如相同含义的单词能不能在编码上的相似度也相近呢?一个单词如果是多义词的话,可不可以用多个向量来 分别表示不同的含义呢? 答案当然是肯定的。我们把词向量的表示分为两大类:上下文无关和上下文有关。

  • 上下文无关:比如常见的skip-gram、cbow。为什么称为上下文无关是因为他无法处理多义词的情况,我们在使用他们训练完模型之后,每个词的表示编码仅有对应的一个,好比“我们喜欢吃苹果”和“我喜欢用苹果”中的苹果只有一个固定的编码,但是很显然他们的词义并不一样。
  • 上下文有关:比如ELMO、Bert。他们可以根据不同的词义学习出不同的编码,这样就更好的理解了某个词在不同句子中的不同含义。

微观分析

文本表示的发展也是有一个路径的,从一开始的独热编码到现在的深度学习编码,下面介绍一些文本表示的发展路程。

独热编码

没啥好说的,现在也不会再有人去用这种表示方法了,它仅仅是把一个词表进行独热编码,也就是说每个单词的纬度就是这个词表的长度,然后除了在相应位置上设为1之外,其余都是0。那么就有了很多问题,最直观的两个就是这个编码太大了,一个词库的长度可能要有几万十几万,那么一篇文章有100个词就有一个100 x 100000的矩阵,如果是1000000篇文章进行学习呢?第二个是稀疏性,机器学习里面稀疏是很可怕的一个词,它会让所有内积为0,失去任何意义。还有就是这种编码体现不了单词的频率,出现频率越多的词也许在某篇文章中是关键词,那么怎么把词频也给加进去呢?

词袋模型 Bag of words

我们可以把所有的单词,也就是整个词表,打乱顺序后扔到一个大袋子里面。然后给一句话编码的时候,其纬度也一样是词表的长度,从index = 0开始,如果词表中的 这个词在句子中出现过几次,就标为几。

  • 词表 = 【我们,你们,他们,去,来,也,到,这里,想,不想,那里,哪里,公园,草坪,博物馆】
    句子 = 【我们,想,去,博物馆,也,想,去,公园】
    文本表示 = 【1,0,0,2,0,1,0,0,2,0,0,0,1,0,1】

我们在有每个句子的表示编码之后,可不可以求得两个句子的关系/相似度?最常用的有余弦相似度,欧式距离等。但是我们马上又发现了一个问题,就是在上例中的“去”是2, 而“公园”和“博物馆”却是1,那么可以说“去”比“公园”要更重要吗?当然不是,那我们就要想个办法怎么去把单词的重要程度表示出来呢?

TF-IDF

人们认为一个词的重要性体现在两个方面,一个是在这个单词在文本中出现了多少次,我们认为出现越多次可能会越重要,也就是由tf来衡量;另一个是这个词在多少个文本中出现过,如果这个词在几乎所有 的文本都出现过,那么我们就会降低它的重要程度,由idf来衡量。我们在idf中加入log是因为增加计算的稳定性,降低由于数量相差太大引起的巨大影响。

好的,我们目前解决了编码维度大的问题,也解决了词频重要程度的问题,但是还没有解决的是稀疏性和相同含义的词之间的编码相似度问题。 我们管以上介绍的所有表示方法称为“Local Representation”,也就是每个词的编码只和他自己有关,那么如果我们迫使它和别的词也有关,是不是相似度的问题可以解决?我们管这种非locally的编码叫做“Distributed Representation”,也就是说,某个词的编码,不仅仅和你自己有关,还和句子中别的词也有关了。

word2vec

word2vec是两个模型的统称,分别是skip-gram和CBOW,这两种模型及其类似。这种方法即上文中提到的distributed representation,全局泛化能力更强,使之前sparse的编码矩阵变得dense,这样就解决了相似度内积为0的问题。同样的因为是分布的,所以在词和词之间的相似度也有了更好的表示。 因为这个word2vec内容很多,就不继续在这篇文章里介绍了,请转移到《Word2Vec》