Skip to content

Commit cfdb0ca

Browse files
Eval tab fix (#880)
* averaging method is now correctly selected for binary classification and thus not inflating the recall/precision values * added warning when prediction files have no matching annotations * ruff fixed * . * limited perch version for tests * .
1 parent 59ddce6 commit cfdb0ca

15 files changed

Lines changed: 47 additions & 7 deletions

File tree

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Install dependencies
2222
run: |
2323
python -m pip install --upgrade pip
24-
pip install ruff
24+
pip install .[dev]
2525
- name: Lint with Ruff
2626
run: |
2727
ruff check

birdnet_analyzer/evaluation/assessment/performance_assessor.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,7 @@ def calculate_metrics(
123123
raise ValueError(f"The number of columns in predictions ({predictions.shape[1]}) " + f"must match num_classes ({self.num_classes}).")
124124

125125
# Determine the averaging method for metrics
126-
if per_class_metrics and self.num_classes == 1:
127-
averaging_method = "macro"
128-
else:
129-
averaging_method = None if per_class_metrics else "macro"
126+
averaging_method = None if per_class_metrics or self.num_classes == 1 else "macro"
130127

131128
# Dictionary to store the results of each metric
132129
metrics_results = {}

birdnet_analyzer/evaluation/preprocessing/data_processor.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ def __init__(
100100
self.predictions_df: pd.DataFrame = pd.DataFrame()
101101
self.annotations_df: pd.DataFrame = pd.DataFrame()
102102

103+
# To track prediction files without matching annotation files
104+
self.umatched_prediction_files: set[str] = set()
105+
103106
# Placeholder for unique classes across predictions and annotations
104107
self.classes: tuple[str, ...] = ()
105108

@@ -173,6 +176,9 @@ def load_data(self) -> None:
173176
Raises:
174177
ValueError: If file reading fails or data preparation encounters issues.
175178
"""
179+
180+
self.umatched_prediction_files = set() # Reset unmatched prediction files
181+
176182
if self.prediction_file_name is None or self.annotation_file_name is None:
177183
# Case: No specific files provided; load all files in directories.
178184
self.predictions_df = read_and_concatenate_files_in_directory(self.prediction_directory_path)
@@ -193,6 +199,16 @@ def load_data(self) -> None:
193199
if self.class_mapping:
194200
class_col_pred = self.get_column_name("Class", prediction=True)
195201
self.predictions_df[class_col_pred] = self.predictions_df[class_col_pred].apply(lambda x: self.class_mapping.get(x, x))
202+
203+
prediction_filenames = self.predictions_df["recording_filename"].unique()
204+
annotation_filenames = self.annotations_df["recording_filename"].unique()
205+
self.umatched_prediction_files = set(prediction_filenames) - set(annotation_filenames)
206+
if self.umatched_prediction_files:
207+
warnings.warn(
208+
f"Prediction files without matching annotation files: {', '.join(self.umatched_prediction_files)}. "
209+
"These recordings will not be processed.",
210+
stacklevel=2,
211+
)
196212
else:
197213
# Case: Specific files are provided for predictions and annotations.
198214
# Ensure filenames correspond to the same recording (heuristic check).

birdnet_analyzer/gui/evaluation.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ def initialize_processor(
240240
avail_classes = list(proc.classes) # Ensure it's a list
241241
avail_recordings = proc.samples_df["filename"].unique().tolist()
242242

243+
if len(proc.umatched_prediction_files) > 0:
244+
gr.Warning(
245+
f"{loc.localize('eval-tab-warning-unmatched-predictions')}: "
246+
f"{', '.join(proc.umatched_prediction_files)}. "
247+
f"{loc.localize('eval-tab-warning-unmatched-predictions-info')}"
248+
)
249+
243250
return avail_classes, avail_recordings, proc, annotation_dir, prediction_dir
244251
except KeyError as e:
245252
print(f"Column missing in files: {e}")

birdnet_analyzer/lang/de.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
"eval-tab-title": "Auswertung",
118118
"eval-tab-upload-mapping-file-label": "Zuordnungsdatei hochladen",
119119
"eval-tab-warning-error-reading-file": "Fehler beim Lesen der Datei",
120+
"eval-tab-warning-unmatched-predictions": "Folgende Vorhersagedateien haben keine entsprechende Annotationsdatei",
121+
"eval-tab-warning-unmatched-predictions-info": "für diese Dateien werden die Annotationen als leer angenommen",
120122
"footer-help": "Dokumentation und Support finden Sie unter",
121123
"footer-support": "Unterstützen Sie unsere Arbeit",
122124
"inference-settings-accordion-label": "Inferenzeinstellungen",

birdnet_analyzer/lang/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
"eval-tab-title": "Evaluation",
118118
"eval-tab-upload-mapping-file-label": "Upload mapping file",
119119
"eval-tab-warning-error-reading-file": "Error reading file",
120+
"eval-tab-warning-unmatched-predictions": "Following prediction files do not have a corresponding annotation file",
121+
"eval-tab-warning-unmatched-predictions-info": "for these files, the annotations will assumed to be empty",
120122
"footer-help": "For docs and support visit",
121123
"footer-support": "Support our work",
122124
"inference-settings-accordion-label": "Inference settings",

birdnet_analyzer/lang/fi.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
"eval-tab-title": "Arviointi",
118118
"eval-tab-upload-mapping-file-label": "Lataa kartoitustiedosto",
119119
"eval-tab-warning-error-reading-file": "Virhe luettaessa tiedostoa",
120+
"eval-tab-warning-unmatched-predictions": "Seuraavilla ennustetiedostoilla ei ole vastaavaa annotaatiotiedostoa",
121+
"eval-tab-warning-unmatched-predictions-info": "näiden tiedostojen annotaatioiden oletetaan olevan tyhjiä",
120122
"footer-help": "Dokumentaatio ja tuki osoitteessa",
121123
"footer-support": "Tue työtämme",
122124
"inference-settings-accordion-label": "Päättelyasetukset",

birdnet_analyzer/lang/fr.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
"eval-tab-title": "Évaluation",
118118
"eval-tab-upload-mapping-file-label": "Téléverser le fichier de correspondance",
119119
"eval-tab-warning-error-reading-file": "Erreur lors de la lecture du fichier",
120+
"eval-tab-warning-unmatched-predictions": "Les fichiers de prédiction suivants n'ont pas de fichier d'annotation correspondant",
121+
"eval-tab-warning-unmatched-predictions-info": "pour ces fichiers, les annotations seront supposées vides",
120122
"footer-help": "Pour de la documentation, visiter",
121123
"footer-support": "Soutenez notre travail",
122124
"inference-settings-accordion-label": "Paramètres d'inférence",

birdnet_analyzer/lang/id.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
"eval-tab-title": "Evaluasi",
118118
"eval-tab-upload-mapping-file-label": "Unggah file pemetaan",
119119
"eval-tab-warning-error-reading-file": "Error saat membaca file",
120+
"eval-tab-warning-unmatched-predictions": "File prediksi berikut tidak memiliki file anotasi yang sesuai",
121+
"eval-tab-warning-unmatched-predictions-info": "untuk file-file ini, anotasi akan dianggap kosong",
120122
"footer-help": "Untuk dokumen dan dukungan kunjungi",
121123
"footer-support": "Dukung Pekerjaan Kami",
122124
"inference-settings-accordion-label": "Pengaturan inferensi",

birdnet_analyzer/lang/pt-br.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
"eval-tab-title": "Avaliação",
118118
"eval-tab-upload-mapping-file-label": "Carregar arquivo de mapeamento",
119119
"eval-tab-warning-error-reading-file": "Erro ao ler arquivo",
120+
"eval-tab-warning-unmatched-predictions": "Os seguintes arquivos de previsão não possuem arquivo de anotação correspondente",
121+
"eval-tab-warning-unmatched-predictions-info": "para esses arquivos, as anotações serão consideradas vazias",
120122
"footer-help": "Para documentos e suporte visite",
121123
"footer-support": "Apoie nosso trabalho",
122124
"inference-settings-accordion-label": "Configurações de inferência",

0 commit comments

Comments
 (0)