ошибка пустого документа: scikit learn - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь приспособить модель SVM для классификации текста, но строка x = text_clf_svm.fit(file_name, target_file) дает ошибку. Я пробовал разные способы, но не смог решить.

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from io import StringIO
import numpy as np


count_vect = CountVectorizer(stop_words=None, input='file')
file_name = open('./svmtest.txt', 'r').read().splitlines()
target_file = open('./target.txt', 'r').read().splitlines()

file_name = [StringIO(x) for x in file_name]
X_train_counts = count_vect.fit_transform(file_name)
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
text_clf_svm = Pipeline([('vect', CountVectorizer(stop_words=None, 
input='file')),
                  ('tfidf', TfidfTransformer()),
                  ('clf-svm', SGDClassifier(loss='hinge', penalty='l2',
                                        alpha=1e-3, n_iter=5, 
              random_state=42)),
          ])
 x = text_clf_svm.fit(file_name, target_file)

Отслеживание ошибок Python:

  File "/Users/aravind/PycharmProjects/PycharmProjects!/minorproject/src/svmClassifier.py", line 27, in <module>
x = text_clf_svm.fit(file_name, target_file)
File "/Users/aravind/venv/PycharmProjects!/lib/python3.6/site- 
packages/sklearn/pipeline.py", line 248, in fit
Xt, fit_params = self._fit(X, y, **fit_params)
File "/Users/aravind/venv/PycharmProjects!/lib/python3.6/site- 
packages/sklearn/pipeline.py", line 213, in _fit
 **fit_params_steps[name])
 File "/Users/aravind/venv/PycharmProjects!/lib/python3.6/site- 
packages/sklearn/externals/joblib/memory.py", line 362, in __call__
return self.func(*args, **kwargs)
File "/Users/aravind/venv/PycharmProjects!/lib/python3.6/site- 
packages/sklearn/pipeline.py", line 581, in _fit_transform_one
res = transformer.fit_transform(X, y, **fit_params)
File "/Users/aravind/venv/PycharmProjects!/lib/python3.6/site- 
packages/sklearn/feature_extraction/text.py", line 869, in 
fit_transform
  self.fixed_vocabulary_)
File "/Users/aravind/venv/PycharmProjects!/lib/python3.6/site- 
packages/sklearn/feature_extraction/text.py", line 811, in _count_vocab
raise ValueError("empty vocabulary; perhaps the documents only"
ValueError: empty vocabulary; perhaps the documents only contain stop 
 words

Содержимое моего svmtest.txt:

train is so bad it is very dirty

great and awesome train

Содержимое My target.txt:

0

1

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

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Несколько баллов:

  • Вы даете только два предложения во входных данных. Я могу только предположить, что на самом деле это не так, но на всякий случай стоит упомянуть, что слова с высокой частотой документа могут считаться «стоп-словами». Например, так как "поезд" появляется в обоих ваших предложениях выше, он имеет частоту документа 1,0, и, следовательно, будет игнорироваться вашим векторизатором. Если у вас есть набор данных разумного размера, это не должно быть проблемой.
  • Подумайте об использовании стандартного словаря стоп-слов в векторизаторе: ('vect', CountVectorizer(stopwords='english')). Значение по умолчанию None НЕ эквивалентно no stop words, а скорее означает «сделайте свою лучшую догадку». Если вы хотите, чтобы не было стоп-слов, используйте stop_words=[].
  • Непонятно, должен ли данный файл быть списком имен файлов, которые содержат ваши данные, или списком строк, которые являются вашими данными. Конечно, нет необходимости преобразовывать строки в StringIO объекты.
  • Либо используйте имя файла входных данных и используйте input='filename', либо загрузите его в память и используйте input='content'. Преобразование их в StringIO объекты только для использования input='file' не имеет смысла.

Рассмотрим следующую версию вашего кода (я решил использовать input='filename', но при необходимости измените):

file_name = './svmtest.txt'
targets = [int(line.strip()) for line in open('./target.txt', 'r').read().splitlines()]

text_clf_svm = Pipeline([
    # consider using stop_words='english'
    ('vect', CountVectorizer(stop_words=None, input='filename')),
    ('tfidf', TfidfTransformer()),
    ('clf-svm', SGDClassifier(loss='hinge', penalty='l2', alpha=1e-3, n_iter=5, random_state=42)),
])
text_clf_svm.fit(file_name, targets)
x = text_clf_svm.predict(file_name)
0 голосов
/ 01 мая 2018

В линии

count_vect = CountVectorizer(stop_words=None, input='file')

Вы установили input параметр в «файл». Из документов

If ‘file’, the sequence items must have a ‘read’ method (file-like object) that is called to fetch the bytes in memory.

Вы можете:
1. Перейдите к fit_transform объекту файла метода

count_vect = CountVectorizer(stop_words=None, input='file')
file_name = open('./svmtest.txt', 'r')
X_train_counts = count_vect.fit_transform(file_name)
  1. Использовать опцию 'content'
count_vect = CountVectorizer(stop_words=None, input='content')
file_name = open('./svmtest.txt', 'r').read().splitlines()
target_file = open('./target.txt', 'r').read().splitlines()
file_name = [StringIO(x) for x in file_name]
X_train_counts = count_vect.fit_transform(file_name)
...