对齐词嵌入的numpy数组

Posted

技术标签:

【中文标题】对齐词嵌入的numpy数组【英文标题】:aligning numpy arrays of word embedding 【发布时间】:2021-09-14 10:30:22 【问题描述】:

我想比较来自两个不同语料库的两个不同词嵌入。问题是向量没有与相同的坐标轴对齐。我想到的一种方法是通过重新排序其中一个向量来最小化常用术语之间差异的绝对和。但我不知道我应该如何计算出重新排序的步骤。

例如这是第一个向量:

array([ 0.10757965, -0.42568704,  0.98631775, -0.8689575 , -0.15464744,
        0.63064075, -0.7297094 ,  1.1489053 , -0.8563999 ,  3.0642095 ,
        2.7397413 , -0.46641126,  0.1275141 , -1.3700885 , -1.072934  ,
       -0.39100915, -1.671539  , -2.4915023 , -0.35404372, -0.43653855,
       -0.6003148 ,  0.4358256 , -0.9136539 , -1.4925014 ,  0.79358363,
       -1.667434  , -0.6276153 ,  0.3108001 ,  1.3591683 ,  1.759436  ,
        2.322402  ,  1.0543864 , -0.05373017,  0.9086741 , -0.6732362 ,
       -0.26082084, -0.74347293, -0.43117926,  1.5836681 ,  1.431517  ,
       -1.492048  , -0.60741377,  0.995547  ,  2.5840738 , -0.49356472,
       -1.298395  ,  0.9130318 , -0.49302715,  1.6769395 , -0.06804854,
        1.9372663 , -0.47315896, -0.54298705, -1.7971836 ,  0.2661831 ,
        2.8773577 ,  0.9101723 ,  0.8329754 , -0.9257539 , -1.486911  ,
        1.649872  , -0.5530765 ,  3.2154553 ,  1.0755832 ,  0.5363964 ,
       -1.6587971 ,  1.2707052 ,  0.03430567, -0.24029787, -0.9271764 ,
       -0.6114223 , -1.4572513 , -1.0918219 ,  1.7637787 , -0.9404495 ,
        0.0857285 , -0.36915302, -1.7384651 , -0.84735996, -0.8769372 ,
       -0.27842158,  0.03236938,  0.03284004,  0.57761943, -0.5666807 ,
        0.36499354,  3.0521092 ,  0.9019006 , -2.0668502 ,  0.6560068 ,
       -1.4445753 , -0.389482  , -0.47697067,  0.69996965,  2.4705417 ,
       -2.041891  , -0.44354537,  1.4558276 , -0.4295767 , -0.90321654],
      dtype=float32)

这是第二个:

array([ 1.1058452 , -2.2796783 ,  0.84442025, -1.4999441 , -2.3308396 ,
        1.4135216 , -0.29184476,  0.8679573 ,  0.42321455, -0.74537545,
        1.0027156 , -0.3483125 , -0.7295568 ,  0.6986356 ,  1.1127443 ,
       -1.1311445 ,  1.2409385 , -1.4786898 , -1.3950868 , -0.27554244,
        0.20782918,  1.6640444 , -0.5691695 , -1.4855943 ,  1.1672127 ,
       -1.2179123 ,  0.61364645,  2.5219076 ,  2.1517315 ,  1.0354927 ,
       -0.9716307 ,  1.5431366 , -1.1036105 , -0.18341443,  0.17259996,
       -2.1558301 ,  0.29899794, -0.5547018 , -0.5943715 ,  0.04390683,
        0.560267  ,  0.7034724 , -0.95176893,  2.8047779 ,  0.35110566,
       -0.7586705 ,  1.0484697 , -1.2169212 ,  1.1784345 , -0.35868016,
       -0.76162195,  0.48639485, -0.21598862, -3.1810286 , -0.40469247,
        0.37047744, -1.2177219 ,  1.0136344 , -0.71124744,  0.55197966,
        1.1838216 ,  0.36200544,  0.6969087 , -0.40792528,  0.9196224 ,
       -0.17401141,  1.9862353 ,  0.6656883 , -0.23861286,  1.0554594 ,
        1.9458885 ,  0.840771  , -2.2205007 , -0.10964899, -2.991086  ,
        2.0690446 , -0.01081265,  0.03285171,  0.6332232 ,  0.02735673,
       -2.4799051 ,  0.48361468,  0.4993206 , -1.5299852 , -0.1030245 ,
        2.4105816 , -0.3814318 , -0.14402314, -1.6633567 ,  2.5273507 ,
       -0.72380215,  2.1811585 ,  1.5535759 , -0.8867029 , -0.5552864 ,
       -1.0396701 ,  0.00605698, -0.37520123, -1.8625914 , -1.4351071 ],
      dtype=float32)

现在假设我有几十对这样的:

[(v1, v2), (v1, v2), ... (v1, v2)]

我想最小化:

np.sum(np.abs(v1 - reordered(v2))

在所有(v1, v2) 对上,其中reordered 是对第二个向量重新排序的函数。

【问题讨论】:

【参考方案1】:

实际上,对行和列进行重新排序是一种在不改变含义的情况下更好地对齐的方法。

这相当于翻转一张纸,使其上的标记与另一张纸上的标记对齐,证明两者都是通向同一个金箱的地图。

但是,如果地图有不同的比例尺,或者一个使用墨卡托投影而另一个不使用,这还不够。

将整个嵌入矩阵乘以一个常数,或者乘以嵌入维度的向量也可以保留信息内容,只要您不乘以 0。理论上,如果两个嵌入相同,您可以将它们粘在一起,从两个 300D 嵌入一个 600D,然后使用高斯算法将其作为方程组求解,冗余将导致一堆维度被消除为 0 列。

这实际上会结合信息。为了更好地对齐它们,请从一个嵌入中挑选一堆词向量,然后尝试找到最小化它们与第二个嵌入中相同词向量的距离的投影(乘法)。

考虑两个立方体,您可以旋转它们,如果需要,可以按比例放大或缩小它们。您总是可以在每个嵌入中获得两个点,使其位于完全相同的位置。如果嵌入相似,这也应该减少所有其他向量的成对距离之和。

但是,是的,您会想尝试使用一些更大的词向量样本来对齐,以尽量减少对特定特质的敏感性,并且不会有针对该问题的确切解决方案。不幸的是,这也是我不太记得使用了什么方法或算法的地方(如果有的话)。但即使是反复试验,或者一些梯度下降即兴创作也应该给你一些有意义的东西。

【讨论】:

以上是关于对齐词嵌入的numpy数组的主要内容,如果未能解决你的问题,请参考以下文章

论文泛读147ELMo 上下文嵌入的跨语言对齐

在 Google Cloud BigQuery 中存储句子嵌入

将张量变量(非常数)转换为 numpy 数组? [复制]

【嵌入式C】在Keil中结构体的字节对齐

如何将数组从 C 传递到嵌入式 python 脚本

上下文嵌入和词嵌入有啥区别