【问题标题】:Dimension mismatch when I try to apply tf-idf to test set当我尝试将 tf-idf 应用于测试集时尺寸不匹配
【发布时间】:2021-03-24 00:35:05
【问题描述】:

我正在尝试按照以下答案将新的预处理算法应用于我的数据集: Encoding text in ML classifier

我现在尝试的如下:

def test_tfidf(data, ngrams = 1):

    df_temp = data.copy(deep = True)
    df_temp = basic_preprocessing(df_temp)
    
    tfidf_vectorizer = TfidfVectorizer(ngram_range=(1, ngrams))
    tfidf_vectorizer.fit(df_temp['Text'])

    list_corpus = df_temp["Text"].tolist()
    list_labels = df_temp["Label"].tolist()

    X = tfidf_vectorizer.transform(list_corpus)
    
    return X, list_labels

(我建议参考我上面提到的所有代码的链接)。 当我尝试将后两个函数应用于我的数据集时:

train_x, train_y, count_vectorizer  = tfidf(undersample_train, ngrams = 1)
testing_set = pd.concat([X_test, y_test], axis=1)
test_x, test_y = test_tfidf(testing_set, ngrams = 1)

full_result = full_result.append(training_naive(train_x, test_x, train_y, test_y), ignore_index = True)

我收到此错误:

---> 12 full_result = full_result.append(training_naive(train_x, test_x, train_y, test_y, ), ignore_index = True) 
---> 14     y_pred = clf.predict(X_test_naive)

ValueError: dimension mismatch

错误中提到的函数是:

def training_naive(X_train_naive, X_test_naive, y_train_naive, y_test_naive, preproc):
    
    clf = MultinomialNB() 
    clf.fit(X_train_naive, y_train_naive)
    y_pred = clf.predict(X_test_naive)
        
    return 

任何有助于理解我的新定义和/或将 tf-idf 应用于我的数据集的任何帮助(请参阅此处以获取相关部分:Encoding text in ML classifier),我们将不胜感激。

更新:我认为这个问题/答案可能对帮助我解决问题也很有用:scikit-learn ValueError: dimension mismatch

如果我将test_x, test_y = test_tfidf(testing_set, ngrams = 1) 替换为test_x, test_y = test_tfidf(undersample_train, ngrams = 1),它不会返回任何错误。但是,我认为这是不对的,因为我得到的值非常非常高(所有统计数据中的 99%)

【问题讨论】:

  • 代码太多。请尝试将您指定的数量减少到可以轻松复制和测试的小子集(minimal reproproducable code
  • 我删除了一些代码。但是您需要参考其他答案以获得一些可重现的代码。在这种情况下,没有办法保留小代码并拥有可重现的代码

标签: python pandas scikit-learn


【解决方案1】:

当使用转换时(在这种情况下为TfidfVectorizer),您必须使用相同的对象来转换训练和测试数据。转换器通常仅使用训练数据进行拟合,然后重新用于转换测试数据。

在您的情况下执行此操作的正确方法:

def tfidf(data, ngrams = 1):

    df_temp = data.copy(deep = True)
    df_temp = basic_preprocessing(df_temp)
    
    tfidf_vectorizer = TfidfVectorizer(ngram_range=(1, ngrams))
    tfidf_vectorizer.fit(df_temp['Text'])

    list_corpus = df_temp["Text"].tolist()
    list_labels = df_temp["Label"].tolist()

    X = tfidf_vectorizer.transform(list_corpus)
    
    return X, list_labels, tfidf_vectorizer


def test_tfidf(data, vectorizer, ngrams = 1):

    df_temp = data.copy(deep = True)
    df_temp = basic_preprocessing(df_temp)

    # No need to create a new TfidfVectorizer here!

    list_corpus = df_temp["Text"].tolist()
    list_labels = df_temp["Label"].tolist()

    X = vectorizer.transform(list_corpus)
    
    return X, list_labels

# this method is copied from the other SO question
def training_naive(X_train_naive, X_test_naive, y_train_naive, y_test_naive, preproc):
    
    clf = MultinomialNB() # Gaussian Naive Bayes
    clf.fit(X_train_naive, y_train_naive)

    res = pd.DataFrame(columns = ['Preprocessing', 'Model', 'Precision', 'Recall', 'F1-score', 'Accuracy'])
    
    y_pred = clf.predict(X_test_naive)
    
    f1 = f1_score(y_pred, y_test_naive, average = 'weighted')
    pres = precision_score(y_pred, y_test_naive, average = 'weighted')
    rec = recall_score(y_pred, y_test_naive, average = 'weighted')
    acc = accuracy_score(y_pred, y_test_naive)
    
    res = res.append({'Preprocessing': preproc, 'Model': 'Naive Bayes', 'Precision': pres, 
                     'Recall': rec, 'F1-score': f1, 'Accuracy': acc}, ignore_index = True)

    return res 

train_x, train_y, count_vectorizer  = tfidf(undersample_train, ngrams = 1)
testing_set = pd.concat([X_test, y_test], axis=1)
test_x, test_y = test_tfidf(testing_set, count_vectorizer, ngrams = 1)

full_result = full_result.append(training_naive(train_x, test_x, train_y, test_y, count_vectorizer), ignore_index = True)

【讨论】:

  • 另外,作为旁注:代码可以大大改进,但这超出了这个问题的范围。我尽量保持原代码不变。
  • @LdM 我看了看并修复了training_naive 问题。至于ngrams参数错误,请务必先运行这个版本的代码。您可能仍在使用不需要 vectorizer 参数的旧代码。
  • @LdM 哎呀!那是一个复制粘贴错误。现已修复!
  • 非常感谢,曲赛!非常感谢您的帮助:)
猜你喜欢
  • 2019-05-08
  • 2012-04-23
  • 2018-10-05
  • 1970-01-01
  • 2021-06-01
  • 2018-11-11
  • 2014-07-04
  • 2017-11-26
  • 1970-01-01
相关资源
最近更新 更多