ValueError:被动式积极分类器中的类标签数必须大于1

时间:2018-09-13 20:42:03

标签: python-3.x machine-learning scikit-learn multiclass-classification tfidfvectorizer

我正在尝试使用scikit学习中的“被动攻击分类器”和20个新闻搜索数据集来实现在线分类器。我对此很陌生,因此不确定是否已正确实施。话虽这么说,我开发了一个samll代码,但是当我执行它时,我不断收到错误消息:

  

回溯(最近一次通话最近):文件“ / 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”,   _fit中的第444行       类,sample_weight,coef_init,intercept_init)文件“ /home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/stochastic_gradient.py”,   _partial_fit中的第407行       提高ValueError(“类标签的数量必须为” ValueError:类标签的数量必须大于1。

我检查了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 :(得分:1)

问题出在这一行:

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

在您的for循环内,即在之后,您要求np.unique(labels)并轻松地发现确实拥有全部20个...

仔细观察,您将发现此行导致{strong>仅一个元素的XyX_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标签数据集并不是那么简单,因为您必须确保每次调用clf.fit()时都会显示 all 全部20个标签,否则最终将把苹果与橘子进行比较...

我强烈建议从简单开始:删除for循环,使分类器适合您的整个训练集(clf.fit(X_train, y_train)),并查看scikit-learn的文档以获取可用的性能指标。您可以使用...

编辑,我刚刚注意到了细节:

  

我正在尝试实现在线分类器

好吧,您尝试做的当然不是在线培训(em本身不是一个大话题),因为您的for循环只是简单地进行重新培训(至少尝试这样做) )在每次迭代过程中从头开始创建新的分类器。

正如我已经说过的,从简单开始;尝试先牢牢掌握简单的批量培训的原理,然后再转向更高级的在线培训主题,这绝对不是初学者的课程。