【问题标题】:Deal with Out of vocabulary word with Gensim pretrained GloVe使用 Gensim 预训练的 GloVe 处理词汇表外的单词
【发布时间】:2020-12-19 16:35:40
【问题描述】:

我正在处理一项 NLP 任务并加载了 Gensim 提供的 GloVe 向量:

import gensim.downloader
glove_vectors = gensim.downloader.load('glove-twitter-25')

我正在尝试获取句子中每个单词的单词嵌入,但其中一些不在词汇表中。

使用 Gensim API 处理它的最佳方法是什么?

谢谢!

【问题讨论】:

  • Afaik 处理 OOV 单词的常用方法是简单地忽略它们。否则,您将不得不从自己的语料库中训练自己的嵌入。
  • 如何有效地忽略它们?那么问题来了,因为我有文本并且必须使用vectors.word_vec(WORD)进行转换,如果WORD不在词汇中,那么我会收到错误。
  • 我不熟悉 Gensim,但肯定有一种方法可以检查模型中是否存在单词。我想可能是like this: if (word in model.wv.key_to_index) ...
  • 你能使用其他词嵌入(fastText、BERT...),它们也可以表示 OOV 词吗?
  • 谢谢,是的,有办法检查它,但运行起来需要很多时间。又名,非常低效(至少到目前为止我一直在做的事情)。其他 WordEmbeddings 的替代方案很有吸引力,但我相信 Gensim 的 KeyedVector 仍然无法从中获利

标签: nlp stanford-nlp gensim word-embedding


【解决方案1】:

加载model:

import gensim.downloader as api
model = api.load("glove-twitter-25")  # load glove vectors
# model.most_similar("cat")  # show words that similar to word 'cat'

有一种非常简单的方法可以找出模型词汇表中是否存在单词。

result = print('Word exists') if word in model.wv.vocab else print('Word does not exist")

除此之外,我还使用以下逻辑创建带有 N 个标记的句子嵌入(25 暗淡):

from __future__ import print_function, division
import os
import re
import sys
import regex
import numpy as np
from functools import partial

from fuzzywuzzy import process
from Levenshtein import ratio as lev_ratio

import gensim
import tempfile


def vocab_check(model, word):
    similar_words = model.most_similar(word)
    match_ratio = 0.
    match_word = ''
    for sim_word, sim_score in similar_words:
        ratio = lev_ratio(word, sim_word)
        if ratio > match_ratio:
            match_word = sim_word
    if match_word == '':
        return similar_words[0][1]
    return model.similarity(word, match_word)


def sentence2vector(model, sent, dim=25):
    words = sent.split(' ')
    emb = [model[w.strip()] for w in words]
    weights = [1. if w in model.wv.vocab else vocab_check(model, w) for w in words]
    
    if len(emb) == 0:
        sent_vec = np.zeros(dim, dtype=np.float16)
    else:
        sent_vec = np.dot(weights, emb)

    sent_vec = sent_vec.astype("float16")
    return sent_vec   

【讨论】:

  • 谢谢,我仍然想让它与 GloVe 预训练嵌入一起使用,但它绝对是一个很好的选择。感谢分享。
  • 我已将代码更新为通用方法。让我知道这是否适合您。
猜你喜欢
  • 2022-01-03
  • 2020-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 2016-06-11
  • 2020-06-02
  • 1970-01-01
相关资源
最近更新 更多