Токенизатор тензорного потока: максимальное количество сохраняемых слов

#tensorflow #tensorflow2.0 #tokenize

#tensorflow #tensorflow2.0 #токенизация

Вопрос:

Попытка токенизировать обзоры фильмов IMDB с помощью токенизатора тензорного потока. Я хочу иметь словарный запас не более 10000 слов. Для невидимых слов я использую токен по умолчанию.

 type(X), X.shape, X[:3]

(pandas.core.series.Series,(25000,),
 0    first think another disney movie might good it...
 1    put aside dr house repeat missed desperate hou...
 2    big fan stephen king s work film made even gre...
 Name: SentimentText, dtype: object)

from tensorflow.keras.preprocessing.text import Tokenizer

tokenizer=Tokenizer(num_words=10000,oov_token='xxxxxxx')
# fit on the input data 
tokenizer.fit_on_texts(X)
  

Когда я проверяю количество слов в словаре токенизатора, я получаю:

 X_dict=tokenizer.word_index

list(enumerate(X_dict.items()))[:10]
[(0, ('xxxxxxx', 1)),
 (1, ('s', 2)),
 (2, ('movie', 3)),
 (3, ('film', 4)),
 (4, ('not', 5)),
 (5, ('it', 6)),
 (6, ('one', 7)),
 (7, ('like', 8)),
 (8, ('i', 9)),
 (9, ('good', 10))]

print(len(X_dict))

Out: 74120
  

Почему я получаю 74120 слов вместо 10000 слов?

Ответ №1:

Потому что словарь слов всегда сохраняется. Когда вы смотрите на исходный код, вы видите, что в функции fit_on_texts() параметр num_words игнорируется. Однако, когда вы преобразуете свой текст в последовательности с texts_to_sequences() помощью, вы можете увидеть вызов texts_to_sequences_generator() , который затем содержит следующий фрагмент кода:

 for w in seq:
    i = self.word_index.get(w)
    if i is not None:
         if num_words and i >= num_words:
              if oov_token_index is not None:
                  vect.append(oov_token_index)
              else:
                  vect.append(i)
         elif self.oov_token is not None:
            vect.append(oov_token_index)
    yield vect
  

Там вы можете видеть, что num_words замечен и используется для дальнейшей генерации последовательностей. Это полезно, поскольку вы можете легко изменять количество слов, не повторяя весь текст заново, поэтому поэкспериментируйте, хорошо ли это соответствует вашим потребностям или вам нужно больше слов для успешной работы над вашей задачей, как утверждает nicolewhite в своем ответе на github.

Итак, в принципе, то, что вы наблюдаете, соответствует ожиданиям, когда вы запускаете np.unique() все свои последовательности, у вас не будет более 10000 значений.

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

1. Из документа Temsorflow о токенизаторе: <qoute> num_words: максимальное количество сохраняемых слов в зависимости от частоты слов. Будут сохранены только самые распространенные num_words-1 слова. </quote> Зачем предоставлять документацию по параметрам ( num_words ), которая не соответствует тому, как она работает? Это очень вводит в заблуждение.

2. Вы можете открыть проблему Github, спрашивая, является ли это описание правильным или нет. Тем не менее, я нахожу это довольно полезным, поскольку вам не нужно каждый раз умещаться в вашем тексте для разных max_words, что в противном случае было бы очень сложно. Это действительно вводит в заблуждение, что вы получаете> 74k by print(len(X_dict)) , но я думаю, что это лучше, чем каждый раз подгонять текст к различным параметрам num_words, что может занять много времени, в зависимости от размера вашего текста, и, поскольку это общий гиперпараметр, вы простоне хочу тратить на это время