#python #scikit-learn #classification
#питон #scikit-учиться #классификация
Вопрос:
Я думаю, что в моих параметрах есть какая-то проблема, поскольку я получаю разные результаты. Поскольку объем кода огромен, я не смогу скопировать и вставить его весь, а только соответствующие части. Я использую разные модели, чтобы предсказать, является ли учетная запись поддельной или нет. Примером модели является следующее:
rf = Pipeline([
('rfCV',FeaturesSelection.countVect),
('rf_clf',RandomForestClassifier(n_estimators=200,n_jobs=3))
])
rf.fit(DataPreparation.train_acc['Acc'],DataPreparation.train_acc['Label'])
predicted_rf = rf.predict(DataPreparation.test_acc['Acc'])
np.mean(predicted_rf == DataPreparation.test_acc['Label'])
Then I use K-Fold cross validation:
def confusion_matrix(classifier):
k_fold = KFold(n_splits=5)
scores = []
confusion = np.array([[0,0],[0,0]])
for train_ind, test_ind in k_fold.split(DataPreparation.train_acc):
train_text = DataPreparation.train_acc.iloc[train_ind]['Acc']
train_y = DataPreparation.train_acc.iloc[train_ind]['Label']
test_text = DataPreparation.train_acc.iloc[test_ind]['Acc']
test_y = DataPreparation.train_acc.iloc[test_ind]['Label']
classifier.fit(train_text,train_y)
predictions = classifier.predict(test_text)
confusion = confusion_matrix(test_y,predictions)
score = f1_score(test_y,predictions)
scores.append(score)
return (print('Score:', sum(scores)/len(scores)))
Применение его ко всем классификаторам
build_confusion_matrix(nb_pipeline)
build_confusion_matrix(svm_pipeline)
build_confusion_matrix(rf)
Я получаю:
Score: 0.5697
Score: 0.5325
Score: 0.5857
Однако, если я хочу создавать отчеты о классификации следующим образом:
print(classification_report(DataPreparation.test_acc['Label'], predicted_nb))
print(classification_report(DataPreparation.test_acc['Label'], predicted_svm))
print(classification_report(DataPreparation.test_acc['Label'], predicted_rf))
Результат отличается. Например:
(ПРИМЕЧАНИЕ)
precision recall f1-score support
0.0 0.97 0.86 0.91 580
1.0 0.41 0.72 0.53 80
(SVM)
precision recall f1-score support
0.0 0.94 0.96 0.95 580
1.0 0.61 0.53 0.52 80
Если я создам сводный отчет следующим образом:
f1 = f1_score(DataPreparation.test_acc['Label'], predicted_rf)
pres = precision_score(DataPreparation.test_acc['Label'], predicted_rf)
rec = recall_score(DataPreparation.test_acc['Label'], predicted_rf)
acc = accuracy_score(DataPreparation.test_acc['Label'], predicted_rf)
res = res.append({'Precision': pres,
'Recall': rec, 'F1-score': f1, 'Accuracy': acc}, ignore_index = True)
Я получаю также разные результаты.
Я смотрю на результат f1. Я должен ожидать того же от всех отчетов о классификации.
Не могли бы вы сказать мне, заметили ли вы какую-либо ошибку в параметрах, которые я использую для построения отчетов о классификации, оценки и / или сводной таблицы?
Ответ №1:
Оценка F1 по своей сути связана с классом. Вот почему в ваших отчетах о классификации есть 2 оценки F1. Когда вы печатаете f1_score (true, прогнозируемый), он выдает вам только одно число, которое, согласно документации sklearn, по умолчанию соответствует показателю f1 из класса, который был присвоен как положительный (источник: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html , параметры> среднее значение). Отчет о классификации возвращает все виды средних значений, однако тот, который вы включили, — это оценка micro — f1, которая отличается от предыдущей оценки f1 и рассчитывается на основе общего количества истинных положительных результатов, ложных отрицательных результатов и ложных положительных результатов (если вы проверяете https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html , в приведенном примере micro f1 для класса 2 составляет 80%, потому что2 ‘2 были правильно классифицированы как 2, а 2 других экземпляра были правильно классифицированы без значения «2», а один «2» не был классифицирован как «2»). Теперь, если самая первая оценка, которую вы указали, отличается от последней оценки, несмотря на то, что они оба были вызваны одной и той же функцией sklearn, это потому, что первое число получено из схемы CV в ваших данных.
Комментарии:
1. Привет, Гауссовский приор, спасибо за ваш ответ. Так это неправильно, что я делаю? Какое значение я должен считать более надежным? Мне нужно было бы создать таблицу, которая включает все значения из отчета о классификации (например, точность, отзыв, точность и оценка f1) для всех моделей. Однако, если я получу результаты из classification_report, а затем вычислю f1, pres, … значения будут разными. Как я могу получить те же результаты?
2. На основании вашего вопроса нет никаких доказательств того, что вы делаете что-то не так. Нет четкого ответа на то, что является наиболее реальным. Кто-то может возразить, что, поскольку у вас 580 экземпляров в одном классе и только 80 в другом, вы можете выполнить f1_score(y_true, y_pred, average=’weighted’), просто укажите, что вы используете это и почему (из-за дисбаланса классов). Отчет о классификации включает взвешенную оценку f1 (последняя строка (взвешенное среднее значение)), которая должна быть равна f1_score при averate = ‘взвешенный’.