1

您好社区成员,

目前,我正在实现 Word2Vec 算法。

首先,我提取了数据(句子),将句子分解并拆分为标记(单词),删除标点符号并将标记存储在单个列表中。该列表基本上包含单词。然后我计算了单词的频率,然后根据频率计算它的出现次数。结果是一个列表。

接下来,我尝试使用 gensim 加载模型。但是,我面临一个问题。问题是关于the word is not in the vocabulary。代码片段,无论我尝试过什么,如下所示。

import nltk, re, gensim
import string
from collections import Counter
from string import punctuation
from nltk.tokenize import word_tokenize
from gensim.models import Word2Vec
from nltk.corpus import gutenberg, stopwords

def preprocessing():
    raw_data = (gutenberg.raw('shakespeare-hamlet.txt'))
    tokens = word_tokenize(raw_data)
    tokens = [w.lower() for w in tokens]
    table = str.maketrans('', '', string.punctuation)
    stripped = [w.translate(table) for w in tokens]
    global words
    words = [word for word in stripped if word.isalpha()]
    sw = (stopwords.words('english'))
    sw1= (['.', ',', '"', '?', '!', ':', ';', '(', ')', '[', ']', '{', '}'])
    sw2= (['for', 'on', 'ed', 'es', 'ing', 'of', 'd', 'is', 'has', 'have', 'been', 'had', 'was', 'are', 'were', 'a', 'an', 'the', 't', 's', 'than', 'that', 'it', '&', 'and', 'where', 'there', 'he', 'she', 'i', 'and', 'with', 'it', 'to', 'shall', 'why', 'ham'])
    stop=sw+sw1+sw2
    words = [w for w in words if not w in stop]
preprocessing()

def freq_count():
    fd = nltk.FreqDist(words)
    print(fd.most_common())
    freq_count()
def word_embedding():
    for i in range(len(words)):
        model = Word2Vec(words, size = 100, sg = 1, window = 3, min_count = 1, iter = 10, workers = 4)
        model.init_sims(replace = True)
        model.save('word2vec_model')
        model = Word2Vec.load('word2vec_model')
        similarities = model.wv.most_similar('hamlet')
        for word, score in similarities:
            print(word , score)
word_embedding()

注意:我在 Windows 操作系统中使用 Python 3.7。从 中syntax of gensim,建议使用句子并拆分为标记,并将其应用于构建和训练模型。我的问题是如何将其应用于仅包含单词的单个列表的语料库。在模型训练期间,我也使用列表指定了单词,即 [words]。

4

2 回答 2

2

传递给的第一个参数Word2Vec需要一个句子列表。你正在传递一个单词列表

import nltk
import re
import gensim
import string
from collections import Counter
from string import punctuation
from nltk.tokenize import word_tokenize
from gensim.models import Word2Vec
from nltk.corpus import gutenberg, stopwords


def preprocessing():
    raw_data = (gutenberg.raw('shakespeare-hamlet.txt'))
    tokens = word_tokenize(raw_data)
    tokens = [w.lower() for w in tokens]
    table = str.maketrans('', '', string.punctuation)
    stripped = [w.translate(table) for w in tokens]
    global words
    words = [word for word in stripped if word.isalpha()]
    sw = (stopwords.words('english'))
    sw1 = (['.', ',', '"', '?', '!', ':', ';', '(', ')', '[', ']', '{', '}'])
    sw2 = (['for', 'on', 'ed', 'es', 'ing', 'of', 'd', 'is', 'has', 'have', 'been', 'had', 'was', 'are', 'were', 'a', 'an', 'the', 't',
            's', 'than', 'that', 'it', '&', 'and', 'where', 'there', 'he', 'she', 'i', 'and', 'with', 'it', 'to', 'shall', 'why', 'ham'])
    stop = sw + sw1 + sw2
    words = [w for w in words if not w in stop]


preprocessing()


def freq_count():
    fd = nltk.FreqDist(words)
    print(fd.most_common())
    freq_count()


def word_embedding():
    for i in range(len(words)):
        print(type(words))
        #pass words as a list.
        model = Word2Vec([words], size=100, sg=1, window=3,
                        min_count=1, iter=10, workers=4)
        model.init_sims(replace=True)
        model.save('word2vec_model')
        model = Word2Vec.load('word2vec_model')
        similarities = model.wv.most_similar('hamlet')
        for word, score in similarities:
            print(word, score)


word_embedding()

希望这可以帮助 :)

于 2018-08-21T11:20:11.533 回答
2

Madhan Varadhodiyil 的回答确定了您的主要问题,传递了一个单词列表,其中Word2Vec需要一个句子序列(例如单词列表列表)。结果,每个单词被视为一个句子,然后每个字母被视为一个句子的一个单词——因此您的结果模型可能只有几十个单字符“单词”。

如果您在 INFO 级别启用了日志记录,并观察了输出——在尝试理解进程或调试问题时总是好主意——您可能已经注意到报告的句子/单词计数已关闭。

此外:

  • 'Hamlet' 有大约 30,000 个单词——但 gensimWord2Vec的优化代码的每个文本示例(句子)的实现限制为 10,000 个单词——因此将全文传递为单个文本将导致大约 2/3被默默无视。将其作为一系列较短的文本(例如句子、段落,甚至场景/行为)传递。

  • 对于好的词向量来说,30,000 个词非常、非常、非常小,它们通常基于数百万到数十亿个词的使用示例。在使用小型语料库时,有时比默认值更多的训练传递epochs=5会有所帮助,有时将向量的维数缩小到默认值以下vector_size=100会有所帮助,但您不会获得算法的全部价值,这实际上取决于大量不同文本示例以实现有意义的单词排列。

  • 通常只有 1 个或几个用法示例的单词无法从这几个(不一定具有代表性)示例中获得好的向量,而且大量此类单词在其他单词的训练中充当噪声/干扰(可能得到好的词向量)。因此,与完全丢弃稀有词的默认设置相比,在特定于任务的质量度量上,对于稀有词和常用词,设置min_count=1通常会导致更差的词向量。

于 2018-08-21T17:22:36.530 回答