【问题标题】:ValueError: cannot reshape array of size 3800 into shape (1,200)ValueError:无法将大小为 3800 的数组重塑为形状 (1,200)
【发布时间】:2019-11-29 04:57:48
【问题描述】:

我正在尝试在推文上应用词嵌入。我试图通过取推文中出现的单词向量的平均值来为每条推文创建一个向量,如下所示:

def word_vector(tokens, size):
    vec = np.zeros(size).reshape((1, size))
    count = 0.
    for word in tokens:
        try:
            vec += model_w2v[word].reshape((1, size))
            count += 1.
        except KeyError: # handling the case where the token is not in vocabulary

            continue
    if count != 0:
        vec /= count
    return vec

接下来,当我尝试准备 word2vec 功能集如下:

wordvec_arrays = np.zeros((len(tokenized_tweet), 200))
#the length of the vector is 200

for i in range(len(tokenized_tweet)):
    wordvec_arrays[i,:] = word_vector(tokenized_tweet[i], 200)

wordvec_df = pd.DataFrame(wordvec_arrays)
wordvec_df.shape

我在循环中得到以下错误:

ValueError                                Traceback (most recent call last)
<ipython-input-32-72aee891e885> in <module>
      4 # wordvec_arrays.reshape(1,200)
      5 for i in range(len(tokenized_tweet)):
----> 6     wordvec_arrays[i,:] = word_vector(tokenized_tweet[i], 200)
      7 
      8 wordvec_df = pd.DataFrame(wordvec_arrays)

<ipython-input-31-9e6501810162> in word_vector(tokens, size)
      4     for word in tokens:
      5         try:
----> 6             vec += model_w2v.wv.__getitem__(word).reshape((1, size))
      7             count += 1.
      8         except KeyError: # handling the case where the token is not in vocabulary

ValueError: cannot reshape array of size 3800 into shape (1,200)

我检查了 stackOverflow 中所有可用的帖子,但没有一个真的对我有帮助。

我尝试重塑数组,但它仍然给我同样的错误。

我的模型是:

tokenized_tweet = df['tweet'].apply(lambda x: x.split()) # tokenizing

model_w2v = gensim.models.Word2Vec(
            tokenized_tweet,
            size=200, # desired no. of features/independent variables 
            window=5, # context window size
            min_count=2,
            sg = 1, # 1 for skip-gram model
            hs = 0,
            negative = 10, # for negative sampling
            workers= 2, # no.of cores
            seed = 34)

model_w2v.train(tokenized_tweet, total_examples= len(df['tweet']), epochs=20)

有什么建议吗?

【问题讨论】:

  • 如果添加完整的异常消息(所有帧和行),会更清楚哪一行导致异常。而且,您可能会发现,通过在 gensim KeyedVectors 类中完成代码的方式对代码进行建模,计算多词向量的均值会更容易。例如,n_similarity() 方法在这行代码中对两组词的向量进行平均:github.com/RaRe-Technologies/gensim/blob/…
  • 我添加了完整的异常消息。
  • 感谢您提供更多详细信息! Stlll,我建议采用以我链接的示例代码为模型的更简单的方法。现在添加更多详细信息的答案..

标签: python deep-learning tokenize word2vec word-embedding


【解决方案1】:

看起来您的word_vector() 方法的意图是获取单词列表,然后针对给定的Word2Vec 模型,返回所有这些单词向量的平均值(如果存在)。

为此,您不需要对向量进行任何显式的重新整形,甚至不需要指定size,因为这是模型已经提供的强制要求。您可以使用numpy 中的实用方法来大大简化代码。例如,gensimn_similarity() 方法,作为它比较 两个 单词列表的一部分,已经像你正在尝试的那样进行平均,你可以看看它的作为模型的来源:

https://github.com/RaRe-Technologies/gensim/blob/f97d0e793faa57877a2bbedc15c287835463eaa9/gensim/models/keyedvectors.py#L996

所以,虽然我没有测试过这段代码,但我认为你的 word_vector() 方法基本上可以替换为:

import numpy as np

def average_words_vectors(tokens, wv_model):
    vectors = [wv_model[word] for word in tokens 
               if word in wv_model]  # avoiding KeyError
    return np.array(vectors).mean(axis=0)

(有时使用已归一化为单位长度的向量是有意义的 - 作为链接的gensim 代码,通过将gensim.matutils.unitvec() 应用于平均值。我在这里没有这样做,因为你的方法没有迈出这一步——但这是需要考虑的。)

单独观察您的Word2Vec 训练代码:

  • 通常只出现 1、2 或几次的词不会获得好的向量(由于示例的数量和种类有限),但会干扰 strong> 随着其他更常用词向量的改进。这就是为什么默认是min_count=5。所以请注意:如果您在此处使用默认(甚至更大)值,丢弃更多稀有词,您的幸存向量可能会变得更好。

  • 像 word2vec 向量这样的“密集嵌入”的维度并不是您的代码注释所暗示的真正的“自变量”(或独立的可单独解释的“特征”),即使它们看起来方式作为数据中的单独值/槽。例如,您不能选择一个维度并得出结论,“这就是这个样本的愚蠢”(如“冷”或“硬度”或“积极性”等)。相反,任何这些人类可描述的意义往往是组合空间中的其他方向,而不是与任何单个维度完美对齐。你可以通过比较向量来梳理一下,下游的机器学习算法可以利用那些复杂/纠缠的多维交互。但是,如果您将每个维度视为其自己的“特征”——除了是,它在技术上是与项目相关联的单个数字——您可能容易误解向量空间。

【讨论】:

    猜你喜欢
    • 2021-08-02
    • 2021-03-20
    • 2021-03-21
    • 2018-10-22
    • 2020-01-29
    • 2021-07-18
    • 1970-01-01
    相关资源
    最近更新 更多