Skip to main content

Behavior Annotation Score (BANOS)

PyPI PyPI Downloads License: MIT Python 3.11+ CI MATLAB File Exchange

What is BANOS?

BANOS is a set of metrics for evaluating algorithmic behavior annotations against a ground truth (typically human annotations). It is designed for ethology and computer vision workflows where researchers annotate behaviors in video data.

Traditional frame-based metrics (precision/recall/F1) capture detection accuracy but miss important temporal qualities: does the predicted segment overlap well with the ground-truth bout? Does the prediction start and end at the right time? Is the prediction internally consistent, or does it flicker on and off inside the bout?

BANOS addresses these questions with four complementary metrics.

The 4 BANOS Metrics

  1. Detection Accuracy (DA) — Precision, Recall, and F1 score over matched behavioral segments (TP/FP/FN at the bout level).

  2. Segment Overlap (SO) — Temporal Intersection over Union (tIoU) between each matched predicted segment and its ground-truth counterpart.

  3. Temporal Precision (TP) — Penalizes start/end time errors: 1 / (1 + |start deviation| + |end deviation|).

  4. Intra-bout Continuity (IC) — Measures label stability inside each ground-truth bout: 1 - (label switches / bout length).

Installation

pip install banos

Requires Python 3.11+. Core dependency: pandas. Optional: scipy (for matching='optimal').

Quick Start

import banos
import pandas as pd

# Load annotations as DataFrames (rows=frames, columns=behaviors, values=0/1)
pred = pd.read_csv("machine_annotations.csv")
gt   = pd.read_csv("human_annotations.csv")

# Score a single recording
metrics = banos.score(pred, gt)
# {'behavior1': {'precision': 0.9, 'recall': 0.85, 'f1_score': 0.87,
#                'so': 0.76, 'tp': 0.82, 'ic': 0.91}, ...}

# Score multiple recordings
group_metrics, overall_metrics = banos.score({
    'recording_1': (pred_1, gt_1),
    'recording_2': (pred_2, gt_2),
})

banos.score() returns:

  • Single recording: dict[behavior → dict[metric → float]]
  • Multiple recordings: (per-recording metrics, overall averaged metrics)

Absent-behavior scoring (v0.2.0): when a behavior has no ground-truth bouts, BANOS checks whether the machine also predicted nothing — if so, all metrics = 1.0 (correct absence); if the machine predicted bouts that don't exist in GT, all metrics = 0.0 (false detection). This is excluded from NaN-averaging correctly.

Examples & Tutorials

Resource Description
demo/quickstart.py Minimal Python example — score annotations in two lines
demo/quickstart.m Minimal MATLAB example
demo/tutorial_python.ipynb Full Python tutorial: classic BANOS usage + frame F1 vs BANOS comparison
demo/tutorial_matlab.m Full MATLAB tutorial mirroring the Python notebook
demo/tutorial_calms21_task1.ipynb Human vs machine: CalMS21 Task 1 baseline, F1 + BANOS (Python only)

Advanced Usage

Optimal Matching

By default, predicted segments are matched to ground-truth bouts greedily (by overlap). For a globally optimal assignment, use the Hungarian algorithm:

metrics = banos.score(pred, gt, matching='optimal')

Requires scipy (pip install scipy).

Lower-level API

from banos import preprocess_data, calculate_banos_for_each_file, aggregate_metrics

data_dict = {
    'file1': (pred_df_1, gt_df_1),
    'file2': (pred_df_2, gt_df_2),
}

preprocessed, dropped = preprocess_data(data_dict)
per_file_metrics      = calculate_banos_for_each_file(preprocessed)
group_metrics, overall = aggregate_metrics(per_file_metrics)

MATLAB

A MATLAB implementation is provided in matlab/BANOS/. Usage mirrors the Python API.

% Add toolbox to path
run('matlab/BANOS/setup.m');

% Score a single recording (pred/gt = cell arrays: row 1 = headers, rows 2+ = binary data)
metrics = BANOS_score(pred, gt);

% Score multiple recordings
dataStruct.Recording_1 = {pred1, gt1};
dataStruct.Recording_2 = {pred2, gt2};
[groupMetrics, overallMetrics] = BANOS_score(dataStruct);

See demo/tutorial_matlab.m for a full walkthrough.

Also available on MATLAB File Exchange.

Contributing

BANOS is functionally complete by design. We welcome bug reports and documentation improvements. See CONTRIBUTING.md for details on how to report issues, submit fixes, and the project's maintenance lifecycle.

To report a security vulnerability, see SECURITY.md — please do not use public GitHub Issues for security reports.

Citation

If you use BANOS, please cite:

Chindemi G., Bellone C., Girard B. From eye to AI: studying rodent social behavior in the era of machine learning. arXiv:2508.04255 (2025). https://doi.org/10.48550/arXiv.2508.04255

@article{chindemi2025eye,
  title   = {From eye to {AI}: studying rodent social behavior in the era of machine learning},
  author  = {Chindemi, Giuseppe and Bellone, Camilla and Girard, Benoit},
  journal = {arXiv preprint arXiv:2508.04255},
  year    = {2025},
  doi     = {10.48550/arXiv.2508.04255}
}

Changelog

See CHANGELOG.md for release history.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

banos-0.3.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

banos-0.3.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file banos-0.3.0.tar.gz.

File metadata

  • Download URL: banos-0.3.0.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for banos-0.3.0.tar.gz
Algorithm Hash digest
SHA256 554e591ba5428790431117222f2a69b264582c44fb76763e4df64dcaeeac0da5
MD5 0fc628f217bceb3249078752fc74ef43
BLAKE2b-256 e7e174f0b106f76a648032af12769cf30c88d4d80b5ed98a8a7d9d8e96a914d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for banos-0.3.0.tar.gz:

Publisher: publish.yml on BelloneLab/BANOS

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file banos-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: banos-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for banos-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1aaed072d00b4f603b8d0737b336ad2403c3115ecfa695207501b87b1ae8424c
MD5 f8712457b932e315bc18477495e0bc9c
BLAKE2b-256 7829870778b3ed0deb2e3b88c52e025caaefbc2aa74c204b1e685b4f934c967f

See more details on using hashes here.

Provenance

The following attestation bundles were made for banos-0.3.0-py3-none-any.whl:

Publisher: publish.yml on BelloneLab/BANOS

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.3

2 files

0.1.5

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page