Gensim word2vec 模型输出 1000 维 ndarray 但 ndarray 维数的最大数量是 32 - 怎么样?

Gensim word2vec model outputs 1000 dimension ndarray but the maximum number of ndarray dimensions is 32 - how?

我正在尝试使用 this 1000 维维基百科 word2vec 模型来分析一些文档。

通过自省,我发现单词的向量表示是 1000 维 numpy.ndarray,但是每当我尝试创建一个 ndarray 来查找最近的单词时,我都会得到一个值错误:

ValueError: maximum supported dimension for an ndarray is 32, found 1000

根据我在网上查看所知道的情况,32 确实是 ndarray 支持的最大维数 - 那么给出了什么? gensim如何输出1000维的ndarray?

这是一些示例代码:

doc = [model[word] for word in text if word in model.vocab]
out = []
n = len(doc[0])
print(n)
print(len(model["hello"]))
print(type(doc[0]))
for i in range(n):
    sum = 0
    for d in doc:
        sum += d[i]
    out.append(sum/n)
out = np.ndarray(out)

输出:

1000
1000
<class 'numpy.ndarray'>
ValueError: maximum supported dimension for an ndarray is 32, found 1000

此处的目标是计算语料库中所有单词的平均向量,其格式可用于在模型中查找附近的单词,因此欢迎提出任何替代建议。

您正在调用 numpyndarray() 构造函数,其中包含一个包含 1000 个数字的列表——您手动计算的 1000 个维度中每个维度的平均值。

ndarray() 函数期望它的参数是所构造矩阵的 形状 ,因此它试图创建一个形状为 (d[0], d[1], ..., d[999]) 的新矩阵 –然后该矩阵中的每个单独值都将使用一组 1000 整数的坐标进行寻址。而且,确实 numpy 数组只能有 32 个独立维度。

但是,即使您将提供给 ndarray() 的列表减少到只有 32 个数字,您仍然会遇到问题,因为您的 32 个数字是浮点值,并且 ndarray() 期待整数计数。 (你会得到一个 TypeError。)

按照您尝试采用的方法——这不是我们将在下面介绍的最佳方法——您确实想要创建一个 单个向量 的 1000 浮动- 点维度。也就是说,1000 个类似单元格的值 – not d[0] * d[1] * ... * d[999] 分隔类似单元格的值。

因此,按照您最初的方法进行的粗略修复可能是将您的最后一行替换为:

result = np.ndarray(len(d))
for i in range(len(d)):
    result[i] = d[i]

但是有很多方法可以逐步使它更高效、更紧凑、更惯用——我将在下面提到其中的一些方法,尽管 最好的 方法在底部, 使得大多数这些临时步骤变得不必要。

首先,您可以使用 Python 的括号索引赋值选项,而不是上面代码中的赋值循环:

result = np.ndarray(len(d))
result[:] = d  # same result as previous 3-lines w/ loop

但事实上,numpyarray() 函数本质上可以从给定的列表中创建必要的 numpy-native ndarray,所以不用 ndarray(),你可以只使用 array():

result = np.array(d)  # same result as previous 2-lines

但更进一步,numpy 的许多原生处理数组(和类似数组的列表)的函数已经包含了在单个步骤中对多个向量进行平均的操作(甚至循环隐藏在非常高效的编译代码或 CPU 批量向量操作中)。例如,有一个 mean() 函数可以对数字列表、多维数字数组或对齐的向量集等进行平均。

这允许更快、更清晰的单行方法,可以用类似的东西替换整个原始代码:

# get a list of available word-vetors
doc = [model[word] for word in text if word in model.vocab]
# average all those vectors
out = np.mean(doc, axis=0)

(如果没有 axis 参数,它会将所有插槽中的所有单独的维度值一起平均为一个最终平均数。)