File size: 2,795 Bytes
11ab05d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | """
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()
|