为什么平均一个句子的词向量价值?

数据挖掘 词嵌入 多标签分类
2022-03-04 21:40:48

我正在使用来自https://www.cs.umb.edu/~smimarog/textmining/datasets/的 r8-train-all-terms.txt、r8-test-all-terms.txt 处理文本分类问题。目标是使用随机森林分类器预测标签。

每个文本句子都使用 GoogleNews 词向量进行了向量化。嵌入源可以在这里找到:https ://github.com/mmihaltz/word2vec-GoogleNews-vectors

在我正在遵循的示例中,有一个步骤让我感到厌烦 - 有一个步骤通过对令牌取均值将我的向量化令牌数组转换为单个向量,例如

def transform(self, data):
        v = self.word_vectors.get_vector('king')
        self.D = v.shape[0]

        X = np.zeros((len(data), self.D))
        n = 0
        emptycount = 0  
        for sentence in data:
            tokens = sentence.split()
            vecs = []
            m = 0
            for word in tokens:
                try:
                    vec = self.word_vectors.get_vector(word)
                    vecs.append(vec)
                    m += 1
                except KeyError:
                    pass
            if len(vecs) > 0:
                vecs = np.array(vecs)
                X[n] = vecs.mean(axis=0)    # take the mean of the vectors?  what does it mean?
            else:
                emptycount += 1
            n += 1
        print("Number of samples with no words found: %s / %s" % (emptycount, len(data)))
        return X

我省略了一些样板,但后来我运行了模型,结果出奇的好:

model = RandomForestClassifier(n_estimators = 200)
model.fit(XTrain, YTrain)
print("train score:", model.score(XTrain, YTrain))
print("test score:", model.score(XTest, YTest))

> train score: 0.9992707383773929
> test score: 0.9378711740520785

我知道随机森林模型希望每个示例有一行,因此它无法像 RNN 那样消耗一系列嵌入。因此,您需要转换为单行(一维数组)。

我的问题是:为什么它有效?在我看来,平均的词向量仅通过对编码进行平均就能够捕捉到任何关于上下文或句子含义的信息。

最好的情况我希望这种技术适用于更大的文本块,因为您倾向于将所有示例压缩到输入空间的同一邻域中。

对此进行一些澄清会很棒。

1个回答

它的工作原理与旧的词袋 + TF-IDF 工作的原因相同。尽管丢失了一些词序信息,文本仍然可以通过典型的关键字进行分类。由于不同主题的文本在使用的词汇方面存在很大差异,因此简单地将单词的嵌入放在一起可能会产生惊人的效果。

这是一篇论文,表明简单的句子嵌入方法优于复杂的监督方法,包括 RNN 和 LSTM。他们的方法只是词向量的加权平均,使用 PCA/SVD 进行了一些修改。第 4.3 节讲述了词序的作用,但并不过分。