batterySwap / inspect_data.py
slappatuski's picture
Upload 27 files
11ab05d verified
Raw History Blame Contribute Delete
2.8 kB
"""
Data-schema inspector.
Prints exactly what raw signals are available so we can decide which FEATURES to
add. The current model (batteryswap_example/train.py, BaseRULModel) only uses
value_cols=('voltage', 'temperature') from the timeseries and ignores device
metadata entirely -- if the parquet or devices.csv carry more predictive signal
(current, soc, resistance, cycle count, install age, ...) we are leaving accuracy
on the table, and late_swap + early_swap (84% of total cost) is now a
prediction-accuracy problem.
Run:
BATTERYSWAP_DATASET_PATH=BatterySwapAI-2026-Public \
venv/bin/python3 inspect_data.py
"""
import os
from pathlib import Path
import pandas as pd
from batteryswap_example.train import load_dataset
def main():
dataset_path = os.environ.get("BATTERYSWAP_DATASET_PATH")
assert dataset_path, "set BATTERYSWAP_DATASET_PATH (e.g. BatterySwapAI-2026-Public)"
split_path = Path(dataset_path) / "train"
locations, timeseries, eol_times, scenarios = load_dataset(split_path)
print("=" * 70)
print("TIMESERIES (battery_metrics) -- one row per device per timestamp")
print("=" * 70)
print("index names :", list(timeseries.index.names))
print("columns :", list(timeseries.columns))
print("dtypes :\n", timeseries.dtypes)
print("shape :", timeseries.shape)
print("head:\n", timeseries.head(3))
# Numeric columns beyond voltage/temperature are candidate new features.
numeric = timeseries.select_dtypes("number").columns.tolist()
used = ["voltage", "temperature"]
unused = [c for c in numeric if c not in used]
print("\nnumeric columns NOT currently used as features:", unused)
print("\n" + "=" * 70)
print("LOCATIONS -- per-device placement the planner sees")
print("=" * 70)
print("columns:", list(locations.columns))
print(locations.head(3))
print("\n" + "=" * 70)
print("devices.csv -- has install start_time => TRUE device AGE feature")
print("=" * 70)
dev = pd.read_csv(split_path / "devices.csv")
print("columns:", list(dev.columns))
print(dev.head(3))
# How old are devices? (age = plan time - install time). Strong RUL signal.
if "start_time" in dev.columns:
st = pd.to_datetime(dev["start_time"], utc=True, errors="coerce")
span = (pd.Timestamp.utcnow() - st).dt.days
print("\ninstall-age (days) distribution:")
print(span.describe())
print("\n" + "=" * 70)
print("eol_times -- censoring rate")
print("=" * 70)
eol = pd.Series(eol_times)
n = len(eol)
n_obs = eol.notna().sum()
print(f"devices={n} observed_eol={n_obs} censored(blank)={n - n_obs} "
f"({100 * (n - n_obs) / max(n, 1):.1f}% censored)")
if __name__ == "__main__":
main()