high F1 score and low values in confusion matrix

2024/10/11 8:26:58

consider I have 2 classes of data and I am using sklearn for classification,

def cv_classif_wrapper(classifier, X, y, n_splits=5, random_state=42, verbose=0):'''cross validation wrapper'''cv = StratifiedKFold(n_splits=n_splits, shuffle=True,random_state=random_state)scores = cross_validate(classifier, X, y, cv=cv, scoring=['f1_weighted', 'accuracy', 'recall_weighted', 'precision_weighted'])if verbose:print(f"=====================")print(f"Accuracy:    {scores['test_accuracy'].mean():.3f} (+/- {scores['test_accuracy'].std()*2:.3f})")print(f"Recall:      {scores['test_recall_weighted'].mean():.3f} (+/- {scores['test_recall_weighted'].std()*2:.3f})")print(f"Precision:   {scores['test_precision_weighted'].mean():.3f} (+/- {scores['test_precision_weighted'].std()*2:.3f})")print(f"F1:          {scores['test_f1_weighted'].mean():.3f} (+/- {scores['test_f1_weighted'].std()*2:.3f})")return scores

and I call it by

scores = cv_classif_wrapper(LogisticRegression(), Xs, y0, n_splits=5, verbose=1)

Then I calculate the confusion matrix with this:

model = LogisticRegression(random_state=42)
y_pred = cross_val_predict(model, Xs, y0, cv=5)
cm = sklearn.metrics.confusion_matrix(y0, y_pred) 

The question is I am getting 0.95 for F1 score but the confusion matrix is enter image description here

Is this consistent with F1 score=0.95? Where is wrong if there is? note that there is 35 subject in class 0 and 364 in class 1.

Accuracy:    0.952 (+/- 0.051)
Recall:      0.952 (+/- 0.051)
Precision:   0.948 (+/- 0.062)
F1:          0.947 (+/- 0.059)
Answer

Your data is imbalanced, i.e. the target classes are not equally distributed. As niid pointed out in their answer, the f1 score returned by default is the weighted f1 score, which can be misleading if not interpreted correctly, especially if your classes are not equally important. Think of customer churn or e-mail spam classification: Your model can be 99% correct (or have a very high f1 score) and still be useless.

We usually calcualte metrics to compare different models to each other. For this, often the area under the ROC curve (AUC-ROC) is used. It summarizes the information of the ROC, which shows True-Positive-Rate against False-Positive-Rate for different thresholds. By using this metric, you are using a metric which is independent of the threshold you choose — unlike accuracy, precision, recall and f1 score which all depend on the threshold you choose.

In the case of imbalanced data, the area under the precision recall curve (AUC-PR) is even more suitable for the comparison of different classifiers:

  1. AUC-ROC is less informative in imbalanced data due to its reliance on sensitivity and specificity, which become less meaningful with class imbalance.
  2. AUC-PR focuses on precision and recall, which are more sensitive to minority class performance and better suited for imbalanced datasets.
  3. AUC-PR is more sensitive to class imbalance, providing a more realistic assessment of classifier performance in imbalanced scenarios.

Consequently, you might want to rethink your metrics.

Additionally, LogisticRegression() is not the best classifier for imbalanced data as it might be biased towards the majority class, leading to poor performance on the minority class. You might consider applying strategies to handle imbalanced data.

https://en.xdnf.cn/q/118344.html

Related Q&A

Replace `\n` in html page with space in python LXML

I have an unclear xml and process it with python lxml module. I want replace all \n in content with space before any processing, how can I do this work for text of all elements.edit my xml example:<…

Basic python. Quick question regarding calling a function [duplicate]

This question already has answers here:How do I get ("return") a result (output) from a function? How can I use the result later?(4 answers)Closed 1 year ago.Ive got a basic problem in pyth…

Obtain the duration of a mp4 file [duplicate]

This question already has answers here:How to get the duration of a video in Python?(15 answers)Closed 10 years ago.I need to know the duration of a mp4 file with python 3.3. I search and try to do th…

Matplotlib.pyplot - Deactivate axes in figure. /Axis of figure overlap with axes of subplot

%load_ext autoreload %autoreload 2 %matplotlib inlineimport numpy as np import datetime as dt import pickle import pandas as pd import datetime from datetime import timedelta, date from datetime impor…

How to generate the captcha to train with Python

I would like to use deep learning program for recognizing the captcha using keras with python.But the big challenge is to generate massive captcha to train. I want to solve a captcha like thisHow can …

Convert PNG to a binary (base 2) string in Python

I Basically want to read a png file and convert it into binary(base 2) and store the converted base 2 value in a string. Ive tried so many things, but all of them are showing some error

Turbodbc installation on Windows 10

I tried installing turbodbc and it gives me the following error and not sure whats wrong here.My python version is 3.7My command line output from Windows 10 Pro. C:\Users\marunachalam\Downloads>pip …

how to convert a text into tuples in a list in python

I am a beginner in python and desperately need someones help.I am trying to convert a text into tuples in a list. The original text was already tokenized and each pos was tagged as below:The/DT Fulton/…

Trying to call a function within class but its not working [duplicate]

This question already has answers here:TypeError: attack() missing 1 required positional argument: self(2 answers)Closed 3 years ago.I am trying to call a function but its not working. here is the code…

Tkinter Label not showing Int variable

Im trying to make a simple RPG where as you collect gold it will be showed in a label, but it doesnt!! Here is the code:def start():Inv=Tk()gold = IntVar(value=78)EtkI2=Label(Inv, textvariable=gold).pa…