skills/cv/sparse-event-temporal-window-expansion/SKILL.md
Turn sparse single-frame event labels (impacts, collisions, goals) into a usable detector training set by stamping the positive label onto a ±k-frame window around each event, then dropping any frame that contains no positives — gives the detector enough positive samples without changing the original annotation
npx skillsauth add wenmin-wu/ds-skills cv-sparse-event-temporal-window-expansionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Video event datasets are brutal for object detectors: a "helmet impact" might be marked on exactly one frame in a 600-frame clip, leaving a 1:600 positive ratio that no detector can train on. Worse, the labeled frame may not even be the visually clearest one — events span 4-8 frames in reality. The fix is temporal window expansion: for every positive frame, mark frames t-k…t+k (typically k=4) as positive too, using the same bounding box. Then filter the dataset to keep only frames that contain at least one positive — discarding the boring 590 negative frames per clip. The detector now sees ~9x more positive samples without you having to relabel anything.
import numpy as np
import pandas as pd
video_labels = pd.read_csv('train_labels.csv').fillna(0)
positives = video_labels[video_labels['impact'] > 0]
K = 4 # +/- frames around each event
offsets = np.array([-4, -3, -2, -1, 1, 2, 3, 4])
for vid, frame, lbl in positives[['video', 'frame', 'label']].values:
nbr_frames = offsets + frame
mask = (
(video_labels['video'] == vid) &
(video_labels['frame'].isin(nbr_frames)) &
(video_labels['label'] == lbl)
)
video_labels.loc[mask, 'impact'] = 1
# drop frames with no positives at all
video_labels = video_labels[
video_labels.groupby('image_name')['impact'].transform('sum') > 0
].reset_index(drop=True)
# remap to 1=non-impact, 2=impact for 2-class detector
video_labels['impact'] = video_labels['impact'].astype(int) + 1
(video, frame, label), mark frames in [frame-k, frame+k] of the same (video, label) as positive too — match the bounding box of the existing tracked objectimage_name and drop any frame whose total positive count is zerodata-ai
Scaled Pinball Loss (SPL) metric for evaluating quantile forecasts, normalized by mean absolute successive differences of training data
data-ai
Walk backward through a time series and multiplicatively rescale segments when jumps exceed a fraction of the running mean to correct data collection anomalies
testing
Transform forecasting target to next/current ratio minus one so that optimizing MAE or squared error implicitly minimizes SMAPE
tools
Convert point forecasts to prediction intervals by scaling with logit-transformed quantile ratios passed through a Normal CDF