ValueError: 被动攻击分类器中的类别标签数量必须大于1

我在尝试使用scikit-learn中的’被动攻击分类器’和20新闻组数据集来实现一个在线分类器。我对此非常新手,因此不确定我是否正确地实现了它。尽管如此,我开发了一个小的代码,但当我执行它时,我不断遇到以下错误:

Traceback (most recent call last): File “/home/suleka/Documents/RNN models/passiveagressive.py”, line 100, in clf.fit(X, y) File “/home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/passive_aggressive.py”, line 225, in fit coef_init=coef_init, intercept_init=intercept_init) File “/home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/stochastic_gradient.py”, line 444, in _fit classes, sample_weight, coef_init, intercept_init) File “/home/suleka/anaconda3/lib/python3.6/site-packages/sklearn/linear_model/stochastic_gradient.py”, line 407, in _partial_fit raise ValueError(“The number of class labels must be ” ValueError: The number of class labels must be greater than one.

我在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 PassiveAggressiveClassifierfrom sklearn.datasets import make_classificationfrom string import punctuationimport numpy as npfrom sklearn.datasets import fetch_20newsgroupsfrom collections import Counterfrom sklearn.preprocessing import MinMaxScaler, LabelBinarizerfrom sklearn.utils import shufflefrom nltk.corpus import stopwordsfrom sklearn.feature_extraction.text import TfidfVectorizerimport nltknltk.download('stopwords')seed = 42np.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, labelsif __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))

提前感谢!


回答:

问题出在这一行:

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

它在你的for循环内,即在你执行np.unique(labels)并确认确实有20个类别之后…

仔细观察,你会发现这一行导致Xy各只有一个元素(分别是X_train[i]y_train[i] – 实际上,由于错误可能发生在第一次迭代,即i=0时,你最终得到的只是X_train[0]y_train[0]),这显然不适合模型拟合;因此,错误消息正确地指出你的集合中只有一个标签(因为你只有一个样本)…

为了确认确实如此,只需在clf.fit()之前插入一个print(np.unique(y)) – 它会只打印一个标签。

你的for循环具体试图实现什么并不清楚;如果你试图训练你的分类器以处理数据集的连续片段,你可以尝试将[i:i+1]索引改为[i:i+k],其中k是一个足够大的数,但对于一个20个标签的数据集,这并不简单,因为你必须确保每次调用clf.fit()时,所有20个标签都存在,否则你会将苹果与橙子进行比较…

我强烈建议从简单开始:删除for循环,将你的分类器拟合到整个训练集上(clf.fit(X_train, y_train)),并查看scikit-learn的文档,了解可用的性能指标…

编辑 我刚刚注意到这个细节:

我在尝试实现一个在线分类器

嗯,你试图做的事情显然不是在线训练(这本身就是一个巨大的话题),因为你的for循环只是在每次迭代中从头开始重新训练一个新的分类器(至少是尝试)。

正如我所说,从简单开始;先牢牢掌握简单批量训练的原则,然后再转向更高级的在线训练主题,这绝对不是初学者应该尝试的…

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注