Sklearn Pipeline ValueError: не удалось преобразовать строку в число с плавающей точкой - PullRequest
0 голосов
/ 01 сентября 2018

Я впервые играю со sklearn и NLP и думал, что понял все, что делал, до тех пор, пока не знал, как исправить эту ошибку. Вот соответствующий код (в значительной степени адаптированный от http://zacstewart.com/2015/04/28/document-classification-with-scikit-learn.html):

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import TruncatedSVD
from sgboost import XGBClassifier
from pandas import DataFrame

def read_files(path):
    for article in os.listdir(path):
        with open(os.path.join(path, doc)) as f:
            text = f.read()
        yield os.path.join(path, article), text

def build_data_frame(path, classification)
    rows = []
    index = []
    for filename, text in read_files(path):
        rows.append({'text': text, 'class': classification})
        index.append(filename)
    df = DataFrame(rows, index=index)
    return df

data = DataFrame({'text': [], 'class': []})
for path, classification in SOURCES: # SOURCES is a list of tuples
    data = data.append(build_data_frame(path, classification))
data = data.reindex(np.random.permutation(data.index))

classifier = Pipeline([
    ('features', FeatureUnion([
        ('text', Pipeline([
            ('tfidf', TfidfVectorizer()),
            ('svd', TruncatedSVD(algorithm='randomized', n_components=300)
            ])),
        ('words', Pipeline([('wscaler', StandardScaler())])),
    ])),
    ('clf, XGBClassifier(silent=False)),
])
classifier.fit(data['text'].values, data['class'].values)

Данные, загруженные в DataFrame, представляют собой предварительно обработанный текст со всеми стоп-словами, пунктуацией, юникодом, прописными буквами и т. Д. Это ошибка, которую я получаю, как только я назову «fit» в классификаторе, где ... представляет один из документов, которые должны были быть проверены в конвейере:

ValueError: could not convert string to float: ...

Сначала я подумал, что TfidfVectorizer () не работает, вызывая ошибку в алгоритме SVD, но после того, как я извлек каждый шаг из конвейера и реализовал их последовательно, та же ошибка возникла только в XGBClassifer.fit ().

Еще больше меня смущает, я пытался пошагово разбить этот скрипт на части в интерпретаторе, но когда я попытался импортировать read_files или build_data_frame, то же ValueError придумала одну из моих строк, но это было только после:

from classifier import read_files

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

1 Ответ

0 голосов
/ 01 сентября 2018

Первая часть вашего конвейера - FeatureUnion. FeatureUnion будет передавать все полученные данные параллельно всем внутренним частям. Вторая часть вашего FeatureUnion - это конвейер, содержащий один StandardScaler. Это источник ошибки.

Это ваш поток данных:

X --> classifier, Pipeline
            |
            |  <== X is passed to FeatureUnion
            \/
      features, FeatureUnion
                      |
                      |  <== X is duplicated and passed to both parts
        ______________|__________________
       |                                 |
       |  <===   X contains text  ===>   |                         
       \/                               \/
   text, Pipeline                   words, Pipeline
           |                                  |   
           |  <===    Text is passed  ===>    |
          \/                                 \/ 
       tfidf, TfidfVectorizer            wscaler, StandardScaler  <== Error
                 |                                   |
                 | <==Text converted to floats       |
                \/                                   |
              svd, TruncatedSVD                      |
                       |                             |
                       |                             |
                      \/____________________________\/
                                      |
                                      |
                                     \/
                                   clf, XGBClassifier

Поскольку текст передается на StandardScaler, выдается ошибка, StandardScaler может работать только с числовыми функциями.

Точно так же, как вы конвертируете текст в числа с помощью TfidfVectorizer, перед отправкой его в TruncatedSVD вам нужно сделать то же самое до StandardScaler, или же предоставить ему только числовые функции.

Глядя на рассматриваемое описание, намеревались ли вы сохранить StandardScaler после результатов TruncatedSVD?

...