Python TfidfVectorizer throwing: пустой словарь; возможно, документы содержат только стоп-слова "

Я пытаюсь использовать Python Tfidf для преобразования корпуса текста. Однако, когда я пытаюсь выполнить fit_transform, я получаю ошибку значения ValueError: empty dictionary; возможно, документы содержат только стоп-слова.

In [69]: TfidfVectorizer().fit_transform(smallcorp)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-69-ac16344f3129> in <module>()
----> 1 TfidfVectorizer().fit_transform(smallcorp)

/Users/maxsong/anaconda/lib/python2.7/site-packages/sklearn/feature_extraction/text.pyc in fit_transform(self, raw_documents, y)
   1217         vectors : array, [n_samples, n_features]
   1218         """
-> 1219         X = super(TfidfVectorizer, self).fit_transform(raw_documents)
   1220         self._tfidf.fit(X)
   1221         # X is already a transformed view of raw_documents so

/Users/maxsong/anaconda/lib/python2.7/site-packages/sklearn/feature_extraction/text.pyc in fit_transform(self, raw_documents, y)
    778         max_features = self.max_features
    779 
--> 780         vocabulary, X = self._count_vocab(raw_documents, self.fixed_vocabulary)
    781         X = X.tocsc()
    782 

/Users/maxsong/anaconda/lib/python2.7/site-packages/sklearn/feature_extraction/text.pyc in _count_vocab(self, raw_documents, fixed_vocab)
    725             vocabulary = dict(vocabulary)
    726             if not vocabulary:
--> 727                 raise ValueError("empty vocabulary; perhaps the documents only"
    728                                  " contain stop words")
    729 

ValueError: empty vocabulary; perhaps the documents only contain stop words

Я прочитал здесь вопрос SO: Проблемы с использованием специального словаря для TfidfVectorizer scikit-learn и попробовал предложение ogrisel об использовании TfidfVectorizer (** params) .build_analyzer () (dataset2) для проверки результатов этапа анализа текста, который, похоже, работает как ожидается: фрагмент ниже:

In [68]: TfidfVectorizer().build_analyzer()(smallcorp)
Out[68]: 
[u'due',
 u'to',
 u'lack',
 u'of',
 u'personal',
 u'biggest',
 u'education',
 u'and',
 u'husband',
 u'to',

Есть еще что-то, что я делаю не так? Корпус, который я кормлю, представляет собой одну гигантскую длинную строку, перемежающуюся новыми строками.

Спасибо!


person Max Song    schedule 05.01.2014    source источник
comment
У меня была такая же проблема, и я понизил версию с v0.19 до 0.18   -  person Nacho    schedule 28.04.2018


Ответы (5)


Я думаю, это потому, что у тебя всего одна струна. Попробуйте разделить его на список строк, например:

In [51]: smallcorp
Out[51]: 'Ah! Now I have done Philosophy,\nI have finished Law and Medicine,\nAnd sadly even Theology:\nTaken fierce pains, from end to end.\nNow here I am, a fool for sure!\nNo wiser than I was before:'

In [52]: tf = TfidfVectorizer()

In [53]: tf.fit_transform(smallcorp.split('\n'))
Out[53]: 
<6x28 sparse matrix of type '<type 'numpy.float64'>'
    with 31 stored elements in Compressed Sparse Row format>
person herrfz    schedule 05.01.2014
comment
Это должен быть правильный ответ. Любая ссылка на документацию по этому поводу? Нигде не могу найти - person Goodword; 21.09.2015
comment
В этом документе есть пример. scikit-learn.org/stable/modules/ (В разделе 4.2.3.3 - переменная корпуса) - person satojkovic; 03.05.2016

В версии 0.12 мы установили минимальную частоту документа равной 2, что означает, что будут учитываться только слова, которые встречаются не менее двух раз. Чтобы ваш пример работал, вам нужно установить min_df=1. Начиная с версии 0.13, это настройка по умолчанию. Полагаю, вы используете 0,12, верно?

person Andreas Mueller    schedule 06.01.2014

В качестве альтернативы вы можете поместить свою единственную строку в виде кортежа, если вы настаиваете на том, чтобы была только одна строка. Вместо того, чтобы иметь:

smallcorp = "your text"

вы бы предпочли поместить его в кортеж.

In [22]: smallcorp = ("your text",)
In [23]: tf.fit_transform(smallcorp)
Out[23]: 
<1x2 sparse matrix of type '<type 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>
person iparjono    schedule 28.04.2016

Я столкнулся с аналогичной ошибкой при запуске скрипта TF-IDF Python 3 над большим корпусом. В некоторых небольших файлах (по-видимому) не хватало ключевых слов, что вызывало сообщение об ошибке.

Я пробовал несколько решений (добавление фиктивных строк в мой список filtered, если len(filtered = 0, ...), которые не помогли. Самым простым решением было добавить выражение try: ... except ... continue.

pattern = "(?u)\\b[\\w-]+\\b"
cv = CountVectorizer(token_pattern=pattern)

# filtered is a list
filtered = [w for w in filtered if not w in my_stopwords and not w.isdigit()]

# ValueError:
# cv.fit(text)
# File "tfidf-sklearn.py", line 1675, in tfidf
#   cv.fit(filtered)
#   File "/home/victoria/venv/py37/lib/python3.7/site-packages/sklearn/feature_extraction/text.py", line 1024, in fit
#   self.fit_transform(raw_documents)
#   ...
#   ValueError: empty vocabulary; perhaps the documents only contain stop words

# Did not help:
# https://stackoverflow.com/a/20933883/1904943
#
# if len(filtered) == 0:
#     filtered = ['xxx', 'yyy', 'zzz']

# Solution:
try:
    cv.fit(filtered)
    cv.fit_transform(filtered)
    doc_freq_term_matrix = cv.transform(filtered)
except ValueError:
    continue
person Victoria Stuart    schedule 01.11.2019
comment
Привет, @Victoria, мне кажется, что в этом случае вы просто избегаете выполнения той операции, которую хотели (векторизация). Что вы здесь понимаете? - person Aleksander Molak; 24.06.2020

У меня тоже была такая же проблема. Преобразование списка int (nums) в список str (nums) не помогло. Но я преобразовался в:

['d'+str(nums) for nums in set] #where d is some letter which mention, we work with strings

Это помогло.

person Alex Ivanov    schedule 03.11.2020