Python sklearn OneVsRestClassifier : Score函数引发ValueError

我正在处理一个多标签分类问题,如下所示:

import pandas as pd
import pickle
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier 
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.cross_validation import train_test_split
tdf = pd.read_csv("data.csv", index_col="DocID",error_bad_lines=False)[:8]
print tdf

结果显示如下:

DocID   Content             Tags           
1       some text here...   [70]
2       some text here...   [59]
3       some text here...  [183]
4       some text here...  [173]
5       some text here...   [71]
6       some text here...   [98]
7       some text here...  [211]
8       some text here...  [188]

然后我根据需要识别并转换列:

X=tdf["Content"]
y=tdf["Tags"]
t=TfidfVectorizer()
print t.fit_transform(X).toarray()
print MultiLabelBinarizer().fit_transform(y)

结果显示如下:

[[ 0.          0.01058315  0.         ...,  0.00529157  0.          0.        ]
 [ 0.          0.00947091  0.         ...,  0.00473545  0.          0.        ]
 [ 0.01190602  0.00950931  0.         ...,  0.00475465  0.          0.        ]
 ...,
 [ 0.          0.01314373  0.         ...,  0.00657187  0.          0.        ]
 [ 0.          0.01200425  0.37574455 ...,  0.00600212  0.01502978  0.        ]
 [ 0.          0.02206688  0.         ...,  0.01103344  0.          0.        ]]
[[1 0 0 0 0 1 0 0 1 1]
 [0 0 0 0 1 0 0 1 1 1]
 [0 1 0 1 0 0 1 0 1 1]
 [0 1 0 1 0 1 0 0 1 1]
 [0 1 0 0 0 1 0 0 1 1]
 [0 0 0 0 0 0 1 1 1 1]
 [0 1 1 0 0 0 0 0 1 1]
 [0 1 0 0 0 0 1 0 1 1]]

查看我的数据,y这里应该只有8列,为什么会有10列

然后我进行分割、转换、拟合和评分:

Xtrain, Xvalidate, ytrain, yvalidate = train_test_split(X, y, test_size=.5)
Xtrain=t.fit_transform(Xtrain).toarray()
Xvalidate=t.fit_transform(Xvalidate).toarray()
ytrain=MultiLabelBinarizer().fit_transform(ytrain)
yvalidate=MultiLabelBinarizer().fit_transform(yvalidate)
clf = OneVsRestClassifier(LogisticRegression(penalty='l2', C=0.01)).fit(Xtrain, ytrain)
print "One vs rest accuracy: %.3f"  % clf.score(Xvalidate,yvalidate)

但我得到了以下错误:

print "One vs rest accuracy: %.3f"  % clf.score(Xvalidate,yvalidate)
  File "X:\Anaconda2\lib\site-packages\sklearn\base.py", line 310, in score
    return accuracy_score(y, self.predict(X), sample_weight=sample_weight)
  File "X:\Anaconda2\lib\site-packages\sklearn\multiclass.py", line 325, in predict
    indices.extend(np.where(_predict_binary(e, X) > thresh)[0])
  File "X:\Anaconda2\lib\site-packages\sklearn\multiclass.py", line 83, in _predict_binary
    score = np.ravel(estimator.decision_function(X))
  File "X:\Anaconda2\lib\site-packages\sklearn\linear_model\base.py", line 249, in decision_function
    % (X.shape[1], n_features))
ValueError: X has 1546 features per sample; expecting 1354

这个错误是什么意思?可能是数据的问题吗?我之前用完全相同的算法处理过类似格式(相同列格式和数据格式)的数据,没有遇到问题。此外,为什么fit函数能正常工作?

我在这里做错了什么?

编辑

所以在我的Tags列中,数据被读取为字符串。因此y中多出了两列。我尝试了

X=tdf["Content"]
y=tdf["Tags"]
y = [map(int, list(_y.replace(',','').replace('[','').replace(']',''))) for _y in y]

以适应多个值,但仍然得到相同的错误。至少我得到了y的正确列数。


回答:

当你调用fit_transform()时,你首先调整特征提取器以适应数据(fit部分),然后转换数据(transform部分)。在同一个特征提取器上多次调用fit_transform()(使用不同的数据)会进行不同的拟合,例如,你的TFIDF Vectorizer可能会为训练集学习一个词汇表,而为验证集学习一个完全不同的词汇表,这会导致列数不同(不同数量的唯一词)。你必须先对Xy调用fit_transform(),然后再分割成训练集和验证集(一次拟合,一次转换)。或者,你可以调用fit_transform()生成训练集,然后只调用transform()生成验证集(一次拟合,多次转换)。

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中创建了一个多类分类项目。该项目可以对…

发表回复

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