Я пытаюсь применить новый алгоритм предварительной обработки к моему набору данных, следуя этому ответу: Кодирование текста в классификаторе ML
Сейчас я пробовал следующее:
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 к моему набору данных (пожалуйста, обратитесь сюда за соответствующими частями: Кодирование текста в классификаторе ML).
Обновление: я думаю, что этот вопрос / ответ также может быть полезен, чтобы помочь мне разобраться в проблеме: scikit-learn ValueError: несоответствие размеров
если я заменю test_x, test_y = test_tfidf(testing_set, ngrams = 1)
на test_x, test_y = test_tfidf(undersample_train, ngrams = 1)
, он не вернет никакой ошибки. Однако я не думаю, что это правильно, так как я получаю очень высокие значения (99% по всей статистике).
Я удалил часть кода. Но вам нужно обратиться к другому ответу, чтобы получить воспроизводимый код. В этом случае нет возможности сохранить небольшой код и воспроизвести его.
При использовании преобразований (в данном случае 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 Ой! Это была ошибка копирования-вставки. Исправлено сейчас!
Большое спасибо, Кусай! Очень ценю вашу помощь :)
слишком много кода. пожалуйста, попробуйте уменьшить количество, которое вы указываете, до небольшого подмножества, которое можно легко скопировать и протестировать (минимальный воспроизводимый код)