ValueError: количество меток классов должно быть больше единицы в пассивном агрессивном классификаторе - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь реализовать онлайновый классификатор с использованием «пассивного агрессивного классификатора» в scikit learn с набором данных 20 групп новостей.Я очень новичок в этом, поэтому я не уверен, правильно ли я это реализовал.При этом я разработал код samll, но при его выполнении я получаю сообщение об ошибке:

Traceback (последний вызов был последним): Файл "/ home / suleka / Documents / RNN models / passiveagressive.py ", строка 100, в файле clf.fit (X, y)" /home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/passive_aggressive.py ", строка 225, в подходящем coef_init= coef_init, intercept_init = intercept_init) Файл "/home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/stochastic_gradient.py", строка 444, в файле _fit классы, sample_weight, coef_init, файл intercept_init) "/home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/stochastic_gradient.py ", строка 407, в _partial_fit повысить ValueError (" Число меток классов должно быть "ValueError: Количество меток классовдолжно быть больше единицы.

Я проверил большинство сообщений в stackoverflow, и они предположили, что должен быть только один уникальный класс. Поэтому я сделал np.unique(labels), и он показал 20 (20 групп новостей):

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]

Может кто-нибудь помочь мне с этой ошибкой, и, пожалуйста, дайте мне знать, если я ее неправильно внедрил.

Мой код показан ниже:

from sklearn.linear_model import PassiveAggressiveClassifier
from sklearn.datasets import make_classification
from string import punctuation
import numpy as np
from sklearn.datasets import fetch_20newsgroups
from collections import Counter
from sklearn.preprocessing import MinMaxScaler, LabelBinarizer
from sklearn.utils import shuffle
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
import nltk
nltk.download('stopwords')



seed = 42
np.random.seed(seed)

def preProcess():

    newsgroups_data = fetch_20newsgroups(subset='all', remove=('headers', 'footers', 'quotes'))

    vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5,
                                 stop_words='english')

    features = vectorizer.fit_transform(newsgroups_data.data)
    labels= newsgroups_data.target

    return features, labels


if __name__ == '__main__':

    features, labels = preProcess()

    X_train, y_train = shuffle(features, labels, random_state=seed)

    clf = PassiveAggressiveClassifier(random_state=seed)

    n, d =X_train.shape

    print(np.unique(labels))

    error = 0
    iteration = 0
    for i in range(n):
        print(iteration)
        X, y = X_train[i:i + 1], y_train[i:i + 1]

        clf.fit(X, y)
        pred = clf.predict(X)

        print(pred)
        print(y)

        if y - pred != 0:
            error += 1
        iteration += iteration


    print(error)
    print(np.divide(error, n, dtype=np.float))

Заранее спасибо!

1 Ответ

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

Проблема заключается в этой строке:

X, y = X_train[i:i + 1], y_train[i:i + 1]

, которая находится внутри вашей петли for, т.е. после , которую вы запросили np.unique(labels), и вы с комфортом обнаружили, что действительно у вас естьвсе 20 единиц ...

Если присмотреться, вы поймете, что эта строка приводит к X и y из только одному элементу каждый (X_train[i] и y_train[i]соответственно - фактически, поскольку ошибка, вероятно, возникает в самой первой итерации для i=0, в итоге вы получите только X_train[0] и y_train[0]), что, конечно, не должно иметь место при подборе модели;следовательно, сообщение об ошибке правильно указывает, что у вас есть только одна метка в вашем наборе (потому что у вас есть только один образец, то есть) ...

Чтобы убедиться, что это действительно так, просто вставьтеprint(np.unique(y)) перед вашим clf.fit() - он напечатает только одну этикетку.

Совершенно неясно, чего именно вы пытаетесь достичь с помощью петли for;если вы пытаетесь обучить свой классификатор последовательным частям вашего набора данных, вы можете попробовать изменить индексы [i:i+1] на [i:i+k] для некоторого достаточно большого k, но для набора данных с 20 метками это не так просто, так какВы должны убедиться, что все 20 меток будут присутствовать для каждого звонка на clf.fit(), в противном случае вы в конечном итоге будете сравнивать яблоки с апельсинами ...

Я настоятельно рекомендую начать с простого:удалите цикл for, поместите ваш классификатор на весь ваш тренировочный набор (clf.fit(X_train, y_train)) и проверьте документацию scikit-learn для доступных метрик производительности, которые вы можете использовать ...

РЕДАКТИРОВАТЬ Я только что заметил детали:

Я пытаюсь реализовать онлайн-классификатор

Ну, то, что вы пытаетесь сделать, это, безусловно, не онлайн-обучение (что само по себе является огромной темой), поскольку ваш цикл for просто переобучает (по крайней мере, пытается) новый классификатор с нуля во время каждой итерации.

Как я уже сказалсказал, начать среали;прежде чем перейти к гораздо более продвинутой теме онлайн-обучения, которая, безусловно, не новичка ...

постарайтесь твердо понять принципы простого пакетного обучения.
...