Reproducing the CMAPSS Benchmark

NASA's CMAPSS FD001 turbofan dataset: 24 channels, identifiers stripped, classified with zero prior knowledge. Below is how to reproduce it end to end on your own account.

Requirements: a VAAS-X API key, pip install vaas-x pandas, and the dataset.

Data

https://phm-datasets.s3.amazonaws.com/NASA/6.+Turbofan+Engine+Degradation+Simulation+Data+Set.zip

(NASA Prognostics Center of Excellence repository, item 6.) Unzip it -- CMAPSSData/train_FD001.txt is what's used here: 100 turbofan engines run to failure under a single operating condition, one row per engine-cycle, 26 columns (unit, cycle, 3 operational settings, 21 sensors), space delimited, no header.

Strip the identifiers

import pandas as pd

columns = ["unit", "cycle", "op_setting_1", "op_setting_2", "op_setting_3"] + [f"sensor_{i}" for i in range(1, 22)]
df = pd.read_csv("CMAPSSData/train_FD001.txt", sep=r"\s+", header=None, names=columns)

measurement_cols = [c for c in columns if c not in ("unit", "cycle")]
df_blind = df[measurement_cols].rename(columns={c: f"channel_{i:02d}" for i, c in enumerate(measurement_cols)})

24 channels, channel_00 through channel_23 -- no sensor names, no units.

Ingest it

from vaasx import Bootstrap

brain = Bootstrap(api_key="YOUR_API_KEY", device_id="cmapss_fd001")

records = df_blind.to_dict(orient="records")
for i in range(0, len(records), 1000):
    batch = records[i:i+1000]
    brain.ingest([{"payload": r} for r in batch])

Query it

hits = brain.query("engine sensor readings drifting toward end of life", k=5, prefer_success=True)
for h in hits:
    print(h["score"], h["timestamp"], h["text"])

Reproduce the classification result

from vaasx.bootstrap import StatisticalProfiler, SchemaClassifier

profiler = StatisticalProfiler(device_id="cmapss_fd001")
for row in records:
    profiler.observe(row)

result = SchemaClassifier().classify(profiler.snapshot())
print("stable channels:", sorted(result["stable_channels"]))
print("significant channels:", sorted(result["significant_channels"]))

This step is local -- no data leaves the machine. stable_channels are channels the classifier found no real information in; significant_channels show real dynamic behaviour. Since FD001 runs one operating condition, the 3 operational settings should land in stable_channels, and the sensors tracking degradation should land in significant_channels.

Verify independently

variances = df_blind.var()
threshold = variances.median() / 100
ground_truth_flat = set(variances[variances < threshold].index)
print(ground_truth_flat, set(result["stable_channels"]))

Compare the two sets directly rather than relying on either the classifier or a cited list of which sensors are supposed to be constant.

FD002 / FD004

Six operating conditions instead of one, so the operational settings are genuinely dynamic there too -- swap the filename and rerun.

More guides: Reproduction Guides. Full reference: Developer Guide.