【问题标题】:How to evaluate text based models with scikit-learn?如何使用 scikit-learn 评估基于文本的模型?
【发布时间】:2019-04-27 08:35:30
【问题描述】:

我有以下带有数据的数据框:

index   field1      field2            field3
1079    COMPUTER    long text....     3

field1 是一个类别,field2 是描述,field3 只是 field1 的整数表示。

我正在使用以下代码通过 sklearn 学习 field2 到类别的映射:

from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import MultinomialNB

X_train, X_test, y_train, y_test = train_test_split(df['Text'], df['category_id'], random_state = 0)
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(X_train)
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
clf = MultinomialNB().fit(X_train_tfidf, y_train)

训练完模型后,我可以用它来预测一个类别,而且效果很好。但是,我想使用测试集评估模型。

X_test_counts = count_vect.fit_transform(X_test)
X_test_tfidf = tfidf_transformer.fit_transform(X_test_counts)
clf.score(X_test_tfidf, y_test) 

它会抛出以下错误:

ValueError: dimension mismatch

有没有办法测试模型并使用此类数据集获得分数或准确度?

更新:向测试集添加类似的转换。

【问题讨论】:

  • 注意:对文本数据进行类似的转换并不意味着fit_tranform,而只是transform。 ;) 这就是你得到那个错误的原因。请参阅下面的答案。

标签: python scikit-learn nlp


【解决方案1】:

MultinomialNB 分类器适用于具有离散特征的分类(例如,文本分类的字数)。多项分布通常需要整数特征计数。 TFIDF 转换以将文档编码为连续值特征。但是,在实践中,诸如 tf-idf 之类的小数计数也可以工作 [reference]

要解决您的问题,请将您的代码更改为以下内容:

count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(df['Text'].values.tolist())
X_train, X_test, y_train, y_test = train_test_split(X_train_counts, df['category_id'], random_state = 0)

clf = MultinomialNB().fit(X_train, y_train)
clf.predict(X_test)

要增强您的代码,请使用 Pipeline:

from sklearn.pipeline import Pipeline
X_train, X_test, y_train, y_test = train_test_split(df['Text'], df['category_id'], random_state = 0)
text_clf = Pipeline([('vect', CountVectorizer()),
                    ('tfidf', TfidfTransformer()),
                    ('clf', MultinomialNB())])
text_clf.fit(X_train, y_train)
text_clf.predict(X_test)

【讨论】:

    【解决方案2】:

    从您提供的代码看来,您可能忘记转换/转换X_test,就像您对X_train 所做的那样。

    更新:
    至于问题中现在显示的新错误:

    ValueError: dimension mismatch
    

    由于变压器已经安装到训练集,你应该在测试集上调用.transform()

    tfidf_transformer.transform(X_test_counts)

    更多信息here

    【讨论】:

    • 很公平。我已经相应地更新了我的答案。但是可以安全地假设您更改了问题中的错误这一事实意味着我的回答解决了原始错误吗?
    【解决方案3】:

    您应该只转换您的测试数据。不适合变换。 您 fit_transform 训练数据并仅转换测试数据。 因此,如果您在测试数据上删除“fit_”,它应该可以工作。

    最好使用能够进行转换然后训练/评分/预测的管道。例如

    from sklearn.pipeline import Pipeline
    from sklearn.model_selection import train_test_split
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.naive_bayes import MultinomialNB
    
    model = Pipeline(steps = [    
                ('word_vec', CountVectorizer()),
                ('word_tdf',  TfidfTransformer()),
                ('mnb',MultinomialNB()),
            ])
    
    simple_model.fit(X_train,y_train)
    simple_model.score(X_test,y_test)
    

    这使您可以编写更简单的代码,并且不太可能 fit_transform 您的测试数据。

    【讨论】:

      猜你喜欢
      • 2014-06-13
      • 2016-06-27
      • 2018-05-26
      • 2020-06-27
      • 2013-06-04
      • 2020-06-13
      • 2016-08-07
      • 2014-10-03
      相关资源
      最近更新 更多