ValueError 在 while 预测测试数据在哪里具有不同的词向量形状
ValueError in while predict where Test data is having different shape of word vector
下面是我尝试用于文本分类模型的代码;
from sklearn.feature_extraction.text import TfidfVectorizer
ifidf_vectorizer = TfidfVectorizer()
X_train_tfidf = ifidf_vectorizer.fit_transform(X_train)
X_train_tfidf.shape
(3, 16)
from sklearn.svm import LinearSVC
clf = LinearSVC()
clf.fit(X_train_tfidf,y_train)
到目前为止,只有训练集被向量化为完整的词汇表。为了对测试集进行分析,我需要将其提交给相同的程序。
所以我做了
X_test_tfidf = ifidf_vectorizer.fit_transform(X_test)
X_test_tfidf.shape
(2, 12)
最后在尝试预测其显示错误时;
predictions = clf.predict(X_test_tfidf)
ValueError: X has 12 features per sample; expecting 16
但是当我使用管道时 from sklearn.pipeline import Pipeline
然后它工作正常;
我不能按照我尝试的方式编写代码吗?
您的代码失败,因为您再次在测试集 X_test
上用 .fit_transform()
重新安装矢量化器。但是,您应该只使用向量化器转换数据:
X_test_tfidf = ifidf_vectorizer.transform(X_test)
现在它应该可以正常工作了。你只需要根据X_train
拟合ifidf_vectorizer
,所有的数据都按照这个进行变换。它确保使用相同的词汇表并获得相同形状的输出。
错误是 fit_transform
的测试数据。你 fit_transform
训练数据和只有 transform
测试数据:
# change this
X_test_tfidf = ifidf_vectorizer.fit_transform(X_test)
X_test_tfidf.shape
(2, 12)
# to
X_test_tfidf = ifidf_vectorizer.transform(X_test)
X_test_tfidf.shape
原因:
当你做 fit_transform
时,你用 fit
教你的模型向量。该模型学习用于将数据转换为的向量。您使用训练数据来学习向量,然后将它们应用到训练和测试 transform
如果您对测试数据执行 fit_transform
,则您替换了在训练数据中学习的向量,并将它们替换为测试数据。鉴于您的测试数据小于您的训练数据,您可能会得到两种不同的向量化。
更好的方法
最好的方法是使用 Pipelines,这将使您的流程易于理解
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
clf = Pipeline(steps=[
('vectorizer', TfidfVectorizer()),
('model', LinearSVC()),
])
# train
clf.fit(X_train,y_train)
# predict
clf.predict(X_test)
这更容易,因为转换会照顾到您。您不必在拟合模型时担心 fit_transform
或在预测或评分时担心 transform
。
如果您使用 with
,您可以独立访问这些功能
clf.named_steps('vectorizer') # or 'model'
在后台,当您执行 clf.fit
时,您的数据将使用 fit_transform
传递给矢量化器,然后传递给 model
。当您预测或评分时,您的数据将在到达您的模型之前通过 transform
抛出您的矢量化器。
下面是我尝试用于文本分类模型的代码;
from sklearn.feature_extraction.text import TfidfVectorizer
ifidf_vectorizer = TfidfVectorizer()
X_train_tfidf = ifidf_vectorizer.fit_transform(X_train)
X_train_tfidf.shape
(3, 16)
from sklearn.svm import LinearSVC
clf = LinearSVC()
clf.fit(X_train_tfidf,y_train)
到目前为止,只有训练集被向量化为完整的词汇表。为了对测试集进行分析,我需要将其提交给相同的程序。 所以我做了
X_test_tfidf = ifidf_vectorizer.fit_transform(X_test)
X_test_tfidf.shape
(2, 12)
最后在尝试预测其显示错误时;
predictions = clf.predict(X_test_tfidf)
ValueError: X has 12 features per sample; expecting 16
但是当我使用管道时 from sklearn.pipeline import Pipeline
然后它工作正常;
我不能按照我尝试的方式编写代码吗?
您的代码失败,因为您再次在测试集 X_test
上用 .fit_transform()
重新安装矢量化器。但是,您应该只使用向量化器转换数据:
X_test_tfidf = ifidf_vectorizer.transform(X_test)
现在它应该可以正常工作了。你只需要根据X_train
拟合ifidf_vectorizer
,所有的数据都按照这个进行变换。它确保使用相同的词汇表并获得相同形状的输出。
错误是 fit_transform
的测试数据。你 fit_transform
训练数据和只有 transform
测试数据:
# change this
X_test_tfidf = ifidf_vectorizer.fit_transform(X_test)
X_test_tfidf.shape
(2, 12)
# to
X_test_tfidf = ifidf_vectorizer.transform(X_test)
X_test_tfidf.shape
原因:
当你做 fit_transform
时,你用 fit
教你的模型向量。该模型学习用于将数据转换为的向量。您使用训练数据来学习向量,然后将它们应用到训练和测试 transform
如果您对测试数据执行 fit_transform
,则您替换了在训练数据中学习的向量,并将它们替换为测试数据。鉴于您的测试数据小于您的训练数据,您可能会得到两种不同的向量化。
更好的方法 最好的方法是使用 Pipelines,这将使您的流程易于理解
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
clf = Pipeline(steps=[
('vectorizer', TfidfVectorizer()),
('model', LinearSVC()),
])
# train
clf.fit(X_train,y_train)
# predict
clf.predict(X_test)
这更容易,因为转换会照顾到您。您不必在拟合模型时担心 fit_transform
或在预测或评分时担心 transform
。
如果您使用 with
,您可以独立访问这些功能
clf.named_steps('vectorizer') # or 'model'
在后台,当您执行 clf.fit
时,您的数据将使用 fit_transform
传递给矢量化器,然后传递给 model
。当您预测或评分时,您的数据将在到达您的模型之前通过 transform
抛出您的矢量化器。