我正在尝试使用this 1000维Wikipedia 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
这里的目标是以一种可以用来在模型中查找附近单词的格式来计算语料库中所有单词的平均向量,因此欢迎对此提出任何其他建议。
您正在调用numpy
的ndarray()
构造函数,该函数带有一个包含1000个数字的列表-您手工计算的1000个维度的平均值。
ndarray()
函数期望其参数为所构造矩阵的shape,因此它试图创建一个新的形状为(d[0], d[1], ..., d[999])
的矩阵–然后该矩阵中的每个单个值都将以一个1000-int坐标集。而且,实际上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]
但是有很多方法可以使这种方法更加高效,紧凑和惯用–尽管下面的best方法使大多数这些临时步骤变得不必要,但我将在下文中提及其中的许多方法。
例如,您可以使用Python的括号索引分配选项,而不是上面的代码中的那个分配循环:
result = np.ndarray(len(d))
result[:] = d # same result as previous 3-lines w/ loop
但是实际上,numpy
的array()
函数实际上可以从给定列表中创建必要的numpy
-本机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
参数,它将所有插槽中的所有单个维度值平均在一起,成为一个单一的最终平均值。)