¿Hay alguna manera de usar la incrustación preentrenada con Tf-Idf en

¿Hay alguna manera de usar la incrustación preentrenada con Tf-Idf en tensorflow?

Estoy usando la implementación básica y predeterminada de Clasificación de texto como:


 

  tokenizer = Tokenizer(num_words=vocab_size, filters = filters)
  tokenizer.fit_on_texts(list(train_X))
  train_X = tokenizer.texts_to_sequences(train_X)
  val_X = tokenizer.texts_to_sequences(val_X)
  train_X = pad_sequences(train_X, maxlen=maxlen)
  val_X = pad_sequences(val_X, maxlen=maxlen)

 def get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32') # For loading Embedding

  embeddings_index = dict(get_coefs(*o.split(" ")) for o in open(EMBEDDING_FILE))
  all_embs = np.stack(embeddings_index.values())
  emb_mean,emb_std = all_embs.mean(), all_embs.std()
  embed_dim = all_embs.shape[1]

  word_index = tokenizer.word_index
  vocab_size = min(vocab_size, len(word_index))

  embedding_matrix = np.random.normal(emb_mean, emb_std, (vocab_size, embed_dim)) # vocab_size was nb_words
  for word, i in word_index.items():
      if i >= vocab_size: continue
      embedding_vector = embeddings_index.get(word)
      if embedding_vector is not None: embedding_matrix[i] = embedding_vector

Funciona bien, pero ¿hay alguna forma de texts_to_matrix, donde hay opciones como binart, tfidf, count etc. ¿Es posible que pueda usarlas con incrustaciones existentes?

Una forma posible podría ser usar un modelo de entrada múltiple y luego concatenar dos entradas en un solo lugar. Aparte de eso, ¿hay alguno?

Mostrar la mejor respuesta

El enfoque más común es multiplicar cada vector de palabra por su puntuación de tf_idf correspondiente. A menudo se ve este enfoque en trabajos académicos. Podrías hacer algo como esto:

Crear partituras tfidf:

import tensorflow as tf
import numpy as np
import gensim.downloader as api
from sklearn.feature_extraction.text import TfidfVectorizer
import collections

def td_idf_word2weight(text):
    print("Creating TfidfVectorizer...")
    tfidf = TfidfVectorizer(preprocessor=' '.join)
    tfidf.fit(text)

    # if a word was never seen - it is considered to be at least as infrequent as any of the known words
    max_idf = max(tfidf.idf_)
    return collections.defaultdict(
        lambda: max_idf,
        [(w, tfidf.idf_[i]) for w, i in tfidf.vocabulary_.items()])

text = [['she let the balloon float up into the air with her hopes and dreams'],
        ['the old rusted farm equipment surrounded the house predicting its demise'],
        ['he was so preoccupied with whether or not he could that he failed to stop to consider if he should']]

td_idf = td_idf_word2weight(text)

text = np.concatenate(text)
tokenizer = tf.keras.preprocessing.text.Tokenizer()
tokenizer.fit_on_texts(text)
text_sequences = tokenizer.texts_to_sequences(text)
text_sequences = tf.keras.preprocessing.sequence.pad_sequences(text_sequences, padding='post')
vocab_size = len(tokenizer.word_index) + 1
print(td_idf.items())
print(vocab_size)
Creating TfidfVectorizer...
dict_items([('she', 1.6931471805599454), ('let', 1.6931471805599454), ('the', 1.2876820724517808), ('balloon', 1.6931471805599454), ('float', 1.6931471805599454), ('up', 1.6931471805599454), ('into', 1.6931471805599454), ('air', 1.6931471805599454), ('with', 1.2876820724517808), ('her', 1.6931471805599454), ('hopes', 1.6931471805599454), ('and', 1.6931471805599454), ('dreams', 1.6931471805599454), ('old', 1.6931471805599454), ('rusted', 1.6931471805599454), ('farm', 1.6931471805599454), ('equipment', 1.6931471805599454), ('surrounded', 1.6931471805599454), ('house', 1.6931471805599454), ('predicting', 1.6931471805599454), ('its', 1.6931471805599454), ('demise', 1.6931471805599454), ('he', 1.6931471805599454), ('was', 1.6931471805599454), ('so', 1.6931471805599454), ('preoccupied', 1.6931471805599454), ('whether', 1.6931471805599454), ('or', 1.6931471805599454), ('not', 1.6931471805599454), ('could', 1.6931471805599454), ('that', 1.6931471805599454), ('failed', 1.6931471805599454), ('to', 1.6931471805599454), ('stop', 1.6931471805599454), ('consider', 1.6931471805599454), ('if', 1.6931471805599454), ('should', 1.6931471805599454)])
38

Crear tf_idf-matriz de incorporaciones ponderadas:

model = api.load("glove-twitter-25")
embedding_dim = 25
weight_matrix = np.zeros((vocab_size, embedding_dim))
for word, i in tokenizer.word_index.items():
  try:
    embedding_vector = model[word] * td_idf[word]
    weight_matrix[i] = embedding_vector 
  except KeyError:
    weight_matrix[i] = np.random.uniform(-5, 5, embedding_dim)
print(weight_matrix.shape)
(38, 25)

Tiene sentido. Como no entendí eso. Multiplicar tf-idf por Embedding tiene sentido. Muchas gracias.

¿Puede explicar la lógica de max_idf = max(tfidf.idf_) . Quiero decir OOV no debería ser mínimo?

Es solo una opción ... eche un vistazo a los documentos ... también puede resolverlo de manera diferente.

¿De qué documentos estás hablando? No entendí esa parte lambda. ¿Puede explicar cómo funciona eso en términos de Laymen?

Estos documentos scikit-learn.org/stable/modules/ generado/…. En la parte lambda, solo está creando un diccionario donde cada palabra representa una clave en el dict y la puntuación tfidf correspondiente representa el valor de esa clave. Imprime los valores si te ayuda.

No, estaba buscando el uso de lambda pero es solo un atajo para if word in dict o some value como max en nuestro caso. Gracias

Solo una pregunta aquí. Yo también he escrito mal las palabras. que quiero quitar. Así que supongamos que he usado vocab_size como 10. ¿Cómo sincronizaría TfIdfVectorizer: min_df y Keras: Tokenizer en ese caso?