使用 Word2Vec 后如何在一组文档中查找肯定词的位置?
How to find where a positive word is in a set of documents after using Word2Vec?
我正在使用 Word2Vec 进行测试以查找具有相同含义的单词,到目前为止它进展顺利,因为正面单词列表是准确的。但是,我想知道每个肯定词是在哪里找到的,比如在哪个文档中。
我尝试遍历每个文档并将每个词与肯定词列表进行比较,如下所示:
for i in documents: # iterating the documents
for j in i: # iterating the words in the document
for k in similar_words: # iterating the positive words
if k[0] in j: # k[0] is the positive word, k[1] is the positive value
print('found word')
这很好用。然而,这样一来,积极的词实际上就被减少了,这就是我使用 "in" 的原因。那么假设词干下降的正词是'ice',很多词中都包含短语'ice',并且文档中可能不止一个,其中只有一个是真正的正词。
有没有办法在使用 Word2Vec 时避免词干化?或者有没有办法找到找到的每个肯定词的文档编号?
更新
这是我训练模型和使用 'most_similar()'
的代码
def remove_stopwords(texts):
# Removes stopwords in a text
return [[word for word in simple_preprocess(str(doc)) if word not in stop_words] for doc in texts]
def sent_to_words(sentences):
# Tokenize each sentence into a list of words and remove unwanted characters
for sentence in sentences:
yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
df = pd.read_excel('my_file.xlsx')
df.columns = map(str.lower, df.columns)
data = df['Comment Section'].values.tolist()
# Remove the new line character and single quotes
data = [re.sub(r'\s+', ' ', str(sent)) for sent in data]
data = [re.sub("\'", "", str(sent)) for sent in data]
# Convert our data to a list of words. Now, data_words is a 2D array,
# each index contains a list of words
data_words = list(sent_to_words(data))
# Remove the stop words
data_words_nostops = remove_stopwords(data_words)
model = gensim.models.Word2Vec(
data_words_nostops,
alpha=0.1,
min_alpha=0.001,
size=250,
window=1,
min_count=2,
workers=10)
model.train(data_words_nostops, total_examples=len(data_words_nostops), epochs=10)
print(model.wv.vocab) # At this step, the words are not stemmed
positive = ['injuries', 'fail', 'dangerous', 'oil']
negative = ['train', 'westward', 'goods', 'calgary', 'car', 'automobile', 'appliance']
similar_words_size = array_length(model.wv.most_similar(positive=positive, negative=negative, topn=0))
for i in model.wv.most_similar(positive=positive, negative=negative, topn=similar_words_size):
if len(i[0]) > 2:
risks.append(i)
print(risks) # At this step, the words are stemmed
在 word2vec 模型训练期间可以使用未提取词干的词。但在实践中,这样做通常会显着降低生成向量的质量。
如果您使用的是预训练向量,则必须使用与训练期间相同的词干提取器函数。
当你得到一个后,你可以用 similar_words
制作字典,然后使用 stem(word) in similar_words
匹配单词
许多已发表的 Word2Vec
作品,包括来自 Google 的原始论文,都没有使用词干提取。如果你有一个足够大的语料库,每个词的每个形式都有很多不同的例子,那么每个形式都会得到一个很好的向量(并且与其他形式紧密定位),即使是原始的无词干词。 (另一方面,在较小的语料库中,词干提取更有可能提供帮助,因为它允许一个词的所有不同形式将它们的出现贡献给一个单一的好向量。)
在训练期间,Word2Vec
只是观察训练文本以获取它需要的邻近词信息:它不会记住单个文档的内容。如果您需要该信息,则需要在您自己的代码中将其保留在 Word2Vec
之外。
您可以遍历所有文档以查找出现的单个单词,就像在您的代码中一样。 (而且,正如@alexey 的回答说明,您应该将词干词与词干词进行比较,而不仅仅是检查子字符串包含。)
用于全文搜索的另一种选择是构建一个 "reverse index" 来记住每个单词出现在哪些文档中(并且可能在每个文档中的位置)。然后,您基本上有一个字典,您可以在其中查找 "iced",并返回一个文档列表,如 "doc1, doc17, doc42"。 (或者可能是文档加位置列表,如 "doc2:pos11,pos91; doc17:pos22, doc42:pos77"。)这需要更多的前期工作,并存储反向索引(取决于保留的详细程度,可能几乎一样大与原始文本一样),但随后找到包含单词的文档比对每个单词进行完全迭代搜索要快得多。
我正在使用 Word2Vec 进行测试以查找具有相同含义的单词,到目前为止它进展顺利,因为正面单词列表是准确的。但是,我想知道每个肯定词是在哪里找到的,比如在哪个文档中。
我尝试遍历每个文档并将每个词与肯定词列表进行比较,如下所示:
for i in documents: # iterating the documents
for j in i: # iterating the words in the document
for k in similar_words: # iterating the positive words
if k[0] in j: # k[0] is the positive word, k[1] is the positive value
print('found word')
这很好用。然而,这样一来,积极的词实际上就被减少了,这就是我使用 "in" 的原因。那么假设词干下降的正词是'ice',很多词中都包含短语'ice',并且文档中可能不止一个,其中只有一个是真正的正词。
有没有办法在使用 Word2Vec 时避免词干化?或者有没有办法找到找到的每个肯定词的文档编号?
更新
这是我训练模型和使用 'most_similar()'
的代码def remove_stopwords(texts):
# Removes stopwords in a text
return [[word for word in simple_preprocess(str(doc)) if word not in stop_words] for doc in texts]
def sent_to_words(sentences):
# Tokenize each sentence into a list of words and remove unwanted characters
for sentence in sentences:
yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
df = pd.read_excel('my_file.xlsx')
df.columns = map(str.lower, df.columns)
data = df['Comment Section'].values.tolist()
# Remove the new line character and single quotes
data = [re.sub(r'\s+', ' ', str(sent)) for sent in data]
data = [re.sub("\'", "", str(sent)) for sent in data]
# Convert our data to a list of words. Now, data_words is a 2D array,
# each index contains a list of words
data_words = list(sent_to_words(data))
# Remove the stop words
data_words_nostops = remove_stopwords(data_words)
model = gensim.models.Word2Vec(
data_words_nostops,
alpha=0.1,
min_alpha=0.001,
size=250,
window=1,
min_count=2,
workers=10)
model.train(data_words_nostops, total_examples=len(data_words_nostops), epochs=10)
print(model.wv.vocab) # At this step, the words are not stemmed
positive = ['injuries', 'fail', 'dangerous', 'oil']
negative = ['train', 'westward', 'goods', 'calgary', 'car', 'automobile', 'appliance']
similar_words_size = array_length(model.wv.most_similar(positive=positive, negative=negative, topn=0))
for i in model.wv.most_similar(positive=positive, negative=negative, topn=similar_words_size):
if len(i[0]) > 2:
risks.append(i)
print(risks) # At this step, the words are stemmed
在 word2vec 模型训练期间可以使用未提取词干的词。但在实践中,这样做通常会显着降低生成向量的质量。
如果您使用的是预训练向量,则必须使用与训练期间相同的词干提取器函数。
当你得到一个后,你可以用 similar_words
制作字典,然后使用 stem(word) in similar_words
许多已发表的 Word2Vec
作品,包括来自 Google 的原始论文,都没有使用词干提取。如果你有一个足够大的语料库,每个词的每个形式都有很多不同的例子,那么每个形式都会得到一个很好的向量(并且与其他形式紧密定位),即使是原始的无词干词。 (另一方面,在较小的语料库中,词干提取更有可能提供帮助,因为它允许一个词的所有不同形式将它们的出现贡献给一个单一的好向量。)
在训练期间,Word2Vec
只是观察训练文本以获取它需要的邻近词信息:它不会记住单个文档的内容。如果您需要该信息,则需要在您自己的代码中将其保留在 Word2Vec
之外。
您可以遍历所有文档以查找出现的单个单词,就像在您的代码中一样。 (而且,正如@alexey 的回答说明,您应该将词干词与词干词进行比较,而不仅仅是检查子字符串包含。)
用于全文搜索的另一种选择是构建一个 "reverse index" 来记住每个单词出现在哪些文档中(并且可能在每个文档中的位置)。然后,您基本上有一个字典,您可以在其中查找 "iced",并返回一个文档列表,如 "doc1, doc17, doc42"。 (或者可能是文档加位置列表,如 "doc2:pos11,pos91; doc17:pos22, doc42:pos77"。)这需要更多的前期工作,并存储反向索引(取决于保留的详细程度,可能几乎一样大与原始文本一样),但随后找到包含单词的文档比对每个单词进行完全迭代搜索要快得多。