Результаты отчета о классификации

#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 = ‘взвешенный’.