【问题标题】:Python sklearn OneVsRestClassifier : Score function gives ValueErrorPython sklearn OneVsRestClassifier:评分函数给出ValueError
【发布时间】:2016-03-21 21:08:15
【问题描述】:

我正在研究一个多标签分类问题

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 函数起作用?

我在这里做错了什么?

编辑

所以在我的标签列中,数据被读取为字符串。因此 y 中有两个额外的列。我试过了

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

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

【问题讨论】:

    标签: python machine-learning scikit-learn logistic-regression multilabel-classification


    【解决方案1】:

    当您调用fit_transform() 时,您首先将特征提取器调整为数据(拟合部分),然后转换数据(转换部分)。通过在同一个特征提取器(使用不同的数据)上多次调用fit_transform(),您正在执行不同的拟合,例如您的 TFIDF Vectorizer 可能会为您的训练集学习一个词汇,而为验证集学习一个完全不同的词汇,这会导致不同的列数(不同数量的唯一词)。您必须在Xy 首先 上调用fit_transform(),然后随后 拆分为训练和验证集(一次拟合,一次转换)。或者,您可以调用fit_transform() 来生成训练集,然后只需调用transform() 来生成验证集(一次拟合,多次转换)。

    【讨论】:

    • 成功了!没有错误,但现在我得到 0 准确度。是因为数据吗?
    • 但是等等,如果我的测试集包含一些看不见的术语怎么办?那我怎么预测呢?
    • 我认为 TFIDF 矢量化器只会在转换期间忽略在拟合期间没有看到的单词,因此它们不应该对结果产生任何影响。不确定准确性。如果您只有 8 个文档作为示例,那将是不够的数据。
    猜你喜欢
    • 2016-02-20
    • 2015-10-15
    • 2020-02-10
    • 2020-03-10
    • 2018-08-18
    • 2016-03-24
    • 1970-01-01
    • 2018-09-09
    • 2016-12-01
    相关资源
    最近更新 更多