使用PCA对word2vec嵌入进行降维处理

27

我正在尝试复现这篇论文的结果:https://arxiv.org/pdf/1607.06520.pdf

具体来说,是这个部分:

为了确定性别子空间,我们取了十个性别对差向量并计算其主成分(PCs)。如图6所示,有一个方向能够解释这些向量中大部分的变化。第一个特征值明显比其他的大。

进入图像描述

我使用与作者相同的词向量集(Google News Corpus,300维),将其加载到word2vec中。

作者所指的“十个性别对差向量”是从以下单词对计算出来的:

进入图像描述

我已按以下方式计算每个标准化向量之间的差异:

model = gensim.models.KeyedVectors.load_word2vec_format('GoogleNews-vectors-
negative300.bin', binary = True)
model.init_sims()

pairs = [('she', 'he'),
('her', 'his'),
('woman', 'man'),
('Mary', 'John'),
('herself', 'himself'),
('daughter', 'son'),
('mother', 'father'),
('gal', 'guy'),
('girl', 'boy'),
('female', 'male')]

difference_matrix = np.array([model.word_vec(a[0], use_norm=True) - model.word_vec(a[1], use_norm=True) for a in pairs])

接下来我将按照论文中的做法,对得出的矩阵进行PCA处理,并选择10个主成分:

from sklearn.decomposition import PCA
pca = PCA(n_components=10)
pca.fit(difference_matrix)

然而,当我查看pca.explained_variance_ratio_时,结果却截然不同:

Translated sentence:

However 当我查看 pca.explained_variance_ratio_ 时,结果却截然不同:

array([  2.83391436e-01,   2.48616155e-01,   1.90642492e-01,
         9.98411858e-02,   5.61260498e-02,   5.29706681e-02,
         2.75670634e-02,   2.21957722e-02,   1.86491774e-02,
         1.99108478e-32])

或者用图表呈现:

在此输入图片描述

第一个成分解释的方差不到30%,但应该超过60%!

我的结果与随机选择向量时得到的结果类似,所以我一定做错了什么,但我找不出问题在哪里。

注意:我尝试过不对向量进行正规化,但是得到了相同的结果。


1
你的意思是对差分矩阵向量进行了归一化处理吗?如果这样做,方差会更加均匀...奇怪的是,如果我计算平均值的方差而不是差异,我得到的结果更接近我们想要的。 - Ritwik Bose
1
“通过'计算方差',我是指在PCA之后查看explained_variance_ratio_。” - Ritwik Bose
1
阅读图形描述,它们似乎计算差异,然后归一化结果向量。在您的代码中,您首先归一化两个向量,然后再进行减法运算。通过这样做,您基本上阻止了嵌入算术的工作,并且您的PCA输入将不会被归一化,因为单位向量的差异不必具有单位范数。 - Jan K
只是出于好奇 - 你能找到答案吗?我已经尝试了你的代码,包括差异规范化和不规范化 - 它并没有显著改变图片。 - mikalai
2个回答

13
他们在GitHub上发布了该论文的代码:https://github.com/tolga-b/debiaswe。具体来说,您可以在此文件中查看他们创建PCA图的代码。以下是该文件中相关的代码片段:
def doPCA(pairs, embedding, num_components = 10):
    matrix = []
    for a, b in pairs:
        center = (embedding.v(a) + embedding.v(b))/2
        matrix.append(embedding.v(a) - center)
        matrix.append(embedding.v(b) - center)
    matrix = np.array(matrix)
    pca = PCA(n_components = num_components)
    pca.fit(matrix)
    # bar(range(num_components), pca.explained_variance_ratio_)
    return pca

根据代码,看起来他们正在取每一对单词与该对的平均向量之间的差异。对我而言,不清楚这是否是论文中所指的。然而,我使用他们的配对运行了此代码,并能够重新创建论文中的图表:

输入图片描述


5

对 oregano 的回答进行补充:

对于每一对 a 和 b,它们计算中心点 c = (a + b) / 2,然后包含指向两个方向的向量,即 a - c 和 b - c。

这样做的原因是PCA给出了最大方差所在的向量。所有向量都指向同一个方向,因此在你试图揭示的精确方向上方差极小。

他们的集合包括指向性别子空间两个方向的向量,因此PCA清晰地显示了性别变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接