Как предварительно обработать набор данных tensorflow imdb_review

#python #pandas #tensorflow

#python #панды #тензорный поток

Вопрос:

Я использую набор данных tensorflow imdb_review и хочу предварительно обработать его с помощью Tokenizer и pad_sequences

Когда я использую экземпляр Tokenizer и использую следующий код:

 tokenizer=Tokenizer(num_words=100)
tokenizer.fit_on_texts(df['text'])
word_index = tokenizer.word_index
sequences=tokenizer.texts_to_sequences(df['text'])

print(word_index)
print(sequences)
 

Я получаю ошибку TypeError: требуется объект, подобный байтам, а не «dict»

Что я пробовал

сохраните dataset как dataframe, а затем выполните итерацию по текстовому столбцу и сохраните его в списке, а затем маркируйте его.

 df = tfds.as_dataframe(ds.take(4), info)
# list to store corpus
corpus = []
for sentences in df['text'].iteritems():
  corpus.append(sentences)

tokenizer=Tokenizer(num_words=100)
tokenizer.fit_on_texts(corpus)
word_index=tokenizer.word_index
print(word_index)
 

Но я получаю ошибку AttributeError: объект ‘tuple’ не имеет атрибута ‘lower’

Как я могу использовать столбец «текст» и предварительно обработать его, чтобы передать его в мою нейронную сеть?

Ответ №1:

Все, что вам нужно, это преобразовать ['text'] столбец в numpy первый с последующей необходимой маркировкой и заполнением. Ниже приведен полный рабочий код. Наслаждайтесь.

Набор данных

 import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# get the data first
imdb = tfds.load('imdb_reviews', as_supervised=True)
 

Подготовка данных

 # we will only take train_data (for demonstration purpose)
# do the same for test_data in your case 
train_data, test_data = imdb['train'], imdb['test']

training_sentences = []
training_labels = []

for sentence, label in train_data:
    training_sentences.append(str(sentence.numpy()))
    training_labels.append(str(label.numpy()))

training_labels_final = np.array(training_labels).astype(np.float)
print(training_sentences[0])    # first samples
print(training_labels_final[0]) # first label 

# b"This was an absolutely terrible movie. ...."
# 0.0
 

Предварительная обработка — токенизатор заполнение

 vocab_size = 2000 # The maximum number of words to keep, based on word frequency. 
embed_size = 30   # Dimension of the dense embedding.
max_len = 100     # Length of input sequences, when it is constant.

# https://keras.io/api/preprocessing/text/
tokenizer = Tokenizer(num_words=vocab_size, 
                      filters='!"#$%amp;()* ,-./:;<=>?@[\]^_`{|}~tn',
                      lower=True,
                      split=" ",
                      oov_token="<OOV>")
tokenizer.fit_on_texts(training_sentences)
print(tokenizer.word_index) 
# {'<OOV>': 1, 'the': 2, 'and': 3, 'a': 4, 'of': 5, 'to': 6, 'is': 7, ...

# tokenized and padding 
training_sequences = tokenizer.texts_to_sequences(training_sentences)
training_padded = pad_sequences(training_sequences, maxlen=max_len, truncating='post')
print(training_sentences[0])
print()
print(training_padded[0])

# b"This was an absolutely terrible movie. ...."
#
[  59   12   14   35  439  400   18  174   29    1    9   33 1378    1
   42  496    1  197   25   88  156   19   12  211  340   29   70  248
  213    9  486   62   70   88  116   99   24    1   12    1  657  777
   12   18    7   35  406    1  178    1  426    2   92 1253  140   72
  149   55    2    1    1   72  229   70    1   16    1    1    1    1
 1506    1    3   40    1  119 1608   17    1   14  163   19    4 1253
  927    1    9    4   18   13   14    1    5  102  148 1237   11  240
  692   13]
 

Модель

Пример модели.

 # Input for variable-length sequences of integers
inputs = tf.keras.Input(shape=(None,), dtype="int32")
# Embed each integer 
x = tf.keras.layers.Embedding(input_dim = vocab_size, 
                              output_dim = embed_size,
                              input_length=max_len)(inputs)
# Add 2 bidirectional LSTMs
x = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, return_sequences=True))(x)
x = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64))(x)
# Add a classifier
outputs = tf.keras.layers.Dense(1, activation="sigmoid")(x)
model = tf.keras.Model(inputs, outputs)

# Compile and Run 
model.compile(loss='binary_crossentropy',
                      optimizer='adam',
                      metrics=['accuracy'])
model.fit(training_padded,
          training_labels_final,
          epochs=10,
          verbose=1)

Epoch 1/10
782/782 [==============================] - 25s 18ms/step - loss: 0.5548 - accuracy: 0.6915
Epoch 2/10
782/782 [==============================] - 14s 18ms/step - loss: 0.3921 - accuracy: 0.8248
...
782/782 [==============================] - 14s 18ms/step - loss: 0.2171 - accuracy: 0.9121
Epoch 9/10
782/782 [==============================] - 14s 17ms/step - loss: 0.1807 - accuracy: 0.9275
Epoch 10/10
782/782 [==============================] - 14s 18ms/step - loss: 0.1486 - accuracy: 0.9428
 

Комментарии:

1. Спасибо! У меня была проблема с частью подготовки данных, которая была очень полезной.

Ответ №2:

Вы можете преобразовать df[ 'text' ] столбец в массив NumPy, вызвав to_numpy() метод. Смотрите документы здесь. Кроме того, рассмотрите документы Tokenizer.fit_on_texts отсюда.

 corpus = df[ 'text' ].to_numpy()
tokenizer = Tokenizer( num_words=100 )
tokenizer.fit_on_texts(corpus)
 

Tokenizer.fit_on_texts Метод вызывается text_elem.lower() внутренне. Но поскольку вы не предоставляете ему список String , вы получаете исключение. Вот фрагмент из исходного кода.

   ...
  for text in texts:
            self.document_count  = 1
            if self.char_level or isinstance(text, list):
                if self.lower:
                    if isinstance(text, list):
                        text = [text_elem.lower() for text_elem in text]
                    else:
   ...
 

Комментарии:

1. Я попытался использовать .to_numpy() после прочтения вашего ответа, но все равно получаю ту же ошибку, что странно, потому что, когда я проверял тип корпуса, это o / p равно dtype=obj , и в соответствии с ошибкой должен использоваться объект. Я даже попытался использовать список строк, как показано в документации tf. Я попытаюсь использовать набор данных извне, загрузив его, я обновлю, когда найду решение.