Python 为什么classifier.predict()方法期望测试数据中的特征数与训练数据中的特征数相同?
我正在尝试使用scikit learn构建一个简单的SVM文档分类器,并使用以下代码:Python 为什么classifier.predict()方法期望测试数据中的特征数与训练数据中的特征数相同?,python,machine-learning,scikit-learn,svm,Python,Machine Learning,Scikit Learn,Svm,我正在尝试使用scikit learn构建一个简单的SVM文档分类器,并使用以下代码: import os import numpy as np import scipy.sparse as sp from sklearn.metrics import accuracy_score from sklearn import svm from sklearn.metrics import classification_report from sklearn.feature_extract
import os
import numpy as np
import scipy.sparse as sp
from sklearn.metrics import accuracy_score
from sklearn import svm
from sklearn.metrics import classification_report
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn import cross_validation
from sklearn.datasets import load_svmlight_file
clf=svm.SVC()
path="C:\\Python27"
f1=[]
f2=[]
data2=['omg this is not a ship lol']
f=open(path+'\\mydata\\ACQ\\acqtot','r')
f=f.read()
f1=f.split(';',1085)
for i in range(0,1086):
f2.append('acq')
f1.append('shipping ship')
f2.append('crude')
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(min_df=1)
counter = CountVectorizer(min_df=1)
x_train=vectorizer.fit_transform(f1)
x_test=vectorizer.fit_transform(data2)
num_sample,num_features=x_train.shape
test_sample,test_features=x_test.shape
print("#samples: %d, #features: %d" % (num_sample, num_features)) #samples: 5, #features: 25
print("#samples: %d, #features: %d" % (test_sample, test_features))#samples: 2, #features: 37
y=['acq','crude']
#print x_test.n_features
clf.fit(x_train,f2)
#den= clf.score(x_test,y)
clf.predict(x_test)
它给出了以下错误:
(n_features, self.shape_fit_[1]))
ValueError: X.shape[1] = 6 should be equal to 9451, the number of features at training time
但我不明白的是,为什么它期望功能的数量是相同的?如果我将一个全新的文本数据输入到需要预测的机器中,显然不可能每个文档都具有与用于训练它的数据相同数量的特征。在这种情况下,我们是否必须明确地将测试数据的特征数设置为9451
在这种情况下,我们是否必须明确地将测试数据的特征数设置为9451
是的,你知道。SVM需要管理与训练集相同的维度。使用文档时,人们倾向于使用一袋单词的方法或选择前x个不太常见的单词。为了确保您具有相同的功能表示,您不应该调整或转换测试数据,而应该只转换它
x_train=vectorizer.fit_transform(f1)
x_test=vectorizer.transform(data2)
应将类似的同质特征转换应用于标签。SVM的工作原理是假设所有训练数据都存在于
n
维空间中,然后对该集合执行某种几何优化。为了使这一点具体化,如果n=2
,那么SVM选择一条线,将(+)
示例与(-)
示例最佳地分开
这意味着支持向量机的训练结果与它训练的维度有关。这个维度正好是您的特征集的大小(模核和其他转换,但在任何情况下,所有这些信息一起唯一地设置了问题空间)。因此,您不能仅将此经过训练的模型应用于存在于不同维度空间中的新数据
(您可能建议我们将培训空间投影或嵌入到测试空间中,这在某些情况下可能会起作用,但通常是无效的。)
然而,当你真正分析它时,这种情况变得更加棘手。不仅测试数据维度需要与训练数据维度相对应,而且每个维度的含义都需要保持不变。例如,在我们的n=2
示例中,假设我们正在对人们的情绪(快乐/悲伤)进行分类,x
维度是“享受生活”,而y
维度是“听悲伤音乐的时间”。我们预计,较大的x
值和较小的y
值会提高快乐的可能性,因此SVM可以找到的一个好的辨别边界是y=x
线,因为靠近x
轴的人倾向于快乐,而靠近y
轴的人倾向于悲伤
但是,假设有人在输入测试数据时将x
和y
维度弄混了。突然,你得到了一个非常不准确的预测
因此,测试数据的观测空间必须与训练数据的观测空间相匹配。维度是这方面的一个重要步骤,但匹配必须是完美的
这意味着你需要做一些功能工程,或者找到一个没有这种依赖关系的算法(这也会涉及一些功能工程)。可能重复和几个早期问题。@larsmans“几个早期问题”…比如?你提到的一个问题引出了一个答案,这个答案恰好与这个相同,但OP所描述的问题是不同的。相同的答案并不意味着问题是相同的。我找不到前面的那些问题,但我知道我以前给出的答案是“使用
transform
,而不是fit\u transform
”。问题实际上是一样的,在测试集中使用fit_transform
。@拉斯曼要么在标记为重复时提到你回答的问题,要么停止到处标记其他人的问题,尽管我没有具体回答。你似乎认为这是一种人身攻击,但事实并非如此;其中没有出现的单词的值为零。