【问题标题】:ValueError in while predict where Test data is having different shape of word vector [duplicate]ValueError in while predict where Test data is have different shape of word vector [重复]
【发布时间】:2020-10-29 21:23:38
【问题描述】:

下面是我正在为文本分类模型尝试的代码;

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 时,它工作正常;

我不能按照我尝试的方式编码吗?

【问题讨论】:

    标签: python machine-learning scikit-learn text-classification


    【解决方案1】:

    错误在于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,则您替换了在训练数据中学习的向量并将它们替换为测试数据。鉴于您的测试数据小于您的训练数据,您可能会得到两种不同的向量化。

    更好的方法 最好的方法是使用 管道,这将使您的流程易于理解

    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 传递给您的矢量化器,然后再到达您的模型。

    【讨论】:

    • 谢谢 Prayson W. Daniel。我理解这个问题。我尝试了两种方式; x_test 和 sklean 管道的单独转换。然而,这引发了质疑;模型仅使用单词向量或训练数据的词汇,测试数据中不属于词汇一部分的任何单词都会被遗漏,不是吗?
    • 是的。您的初始模型是在测试数据标记上训练的。当您 fit_transform 测试数据时,将训练数据替换为测试数据。除非您非常幸运,因为训练和测试数据集包含相似的标记,否则您很可能会得到错误的形状矢量化器;)我们通常不使用测试数据来训练模型,而是评估模型如何在看不见的数据中执行。最后,您可以在所有数据上结合训练模型。
    【解决方案2】:

    您的代码失败,因为您再次在测试集X_test 上使用.fit_transform() 重新安装矢量化器。但是,您应该只使用矢量化器转换数据:

    X_test_tfidf = ifidf_vectorizer.transform(X_test) 
    
    

    现在它应该可以按预期工作了。您只根据X_train 拟合ifidf_vectorizer 并根据此转换所有数据。它确保使用相同的词汇表并获得相同形状的输出。

    【讨论】:

      猜你喜欢
      • 2022-09-24
      • 1970-01-01
      • 2022-01-03
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2020-08-25
      • 2023-03-23
      相关资源
      最近更新 更多