Skip to main content

ML Feature Pipeline

varistar.ml turns a collection of (TimeSeries, LightCurve) pairs into a feature matrix, then clusters it. Dataset is the interactive entry point; FeaturePipeline is the CLI equivalent for a directory of .dat files.

from varistar import TimeSeries, LightCurve
from varistar.ml.data import Dataset
from _synthetic import make_sinusoidal_lightcurve, make_eclipsing_lightcurve

ds = Dataset(data_dir="./_scratch") # only used if you later call export_features()

for i in range(4):
df = make_sinusoidal_lightcurve(period=1.5 + 0.4 * i, seed=100 + i)
ts = TimeSeries(magnitude="mag I", time_scale="HJD")
ts.load_data_from_df(df, data_id=f"sine_{i:02d}")
ds.add_object(ts, LightCurve(ts))

for i in range(4):
df = make_eclipsing_lightcurve(period=3.0 + 0.5 * i, seed=200 + i)
ts = TimeSeries(magnitude="mag I", time_scale="HJD")
ts.load_data_from_df(df, data_id=f"eb_{i:02d}")
ds.add_object(ts, LightCurve(ts))

len(ds)
8

Feature extraction​

18 statistical and astrophysical features per star (n_cores=1 here so docs builds stay deterministic and single-process; raise it for real datasets):

features = ds.build_features(n_cores=1)
features.head()
Extracting 18 features for 8 stars using 1 worker(s)...

Features: 0%| | 0/8 [00:00<?, ?it/s]
Features: 12%|█▎ | 1/8 [00:01<00:11, 1.63s/it]
Features: 100%|██████████| 8/8 [00:01<00:00, 4.77it/s]
Done. Feature matrix shape: (8, 18)
median mad octile_skew low row mav skew stetson_j flux_perc_ratio log_freq log_amp r21 ph21_cos ph21_sin freq_ratio von_neumann kurtosis beyond1std
id
sine_00 14.951740 0.166829 0.189136 0.193654 0.240996 0.348094 0.201077 0.309150 3.281441 -0.175862 -0.240124 0.006874 0.660781 -0.750578 0.998747 1.288633 -1.449550 0.472500
sine_01 15.022269 0.183528 -0.098277 0.213774 0.162972 0.222661 -0.099757 0.474463 3.279984 -0.278745 -0.232032 0.003478 0.551693 -0.834047 0.998408 0.921233 -1.496527 0.510000
sine_02 14.977564 0.167837 0.078717 0.192879 0.237459 0.227769 0.098007 0.503178 3.471829 -0.362145 -0.246232 0.012902 0.999299 0.037447 1.001941 0.872591 -1.432720 0.485000
sine_03 14.990327 0.168094 0.033304 0.258124 0.251973 0.185170 0.024304 0.575821 3.709217 -0.430923 -0.239747 0.003099 0.721878 -0.692020 0.997723 0.697706 -1.407703 0.467500
eb_00 14.516083 0.026262 0.787165 0.355746 0.492507 3.098591 1.870418 0.318536 25.579643 -0.175760 -0.180594 0.671235 -0.022895 -0.999738 0.998996 1.194360 2.583707 0.121667

A single object’s features, without a Dataset:

from varistar.ml.features import FeatureExtractor

FeatureExtractor.extract(ts_obj=ts, lc_obj=LightCurve(ts))
{'id': 'eb_03',
'median': 14.513510845943607,
'mad': 0.0231098868662869,
'octile_skew': 0.8102747606539833,
'low': 0.3426635039358418,
'row': 0.6915083175115532,
'mav': 2.5723796625588657,
'skew': 2.0290688803683263,
'stetson_j': 0.44216469327519986,
'flux_perc_ratio': 30.411516136791843,
'log_freq': -0.3524273582841337,
'log_amp': -0.18215504515974948,
'r21': 0.7156677153912228,
'ph21_cos': 0.018359270416665654,
'ph21_sin': -0.9998314543910727,
'freq_ratio': 1.001504900047014,
'von_neumann': 0.7911990804613463,
'kurtosis': 3.0893407150292695,
'beyond1std': 0.13166666666666665}

Clustering​

ds.cluster_data(n_clusters=2)
ds.visualize_clusters()
K-Means complete. Cluster distribution: {0: 4, 1: 4}


Top 5 features driving PC1 separation:
median 0.271079
r21 0.270773
beyond1std 0.270707
mad 0.270554
skew 0.270445

CLI: whole directories of .dat files​

For a real survey field, skip the Python loop and run the pipeline directly against a directory (illustrative — not executed on this page):

python -m varistar.ml.pipeline --data ./ogle_field_01/ \
--features 0 1 7 11 15 --output ./catalogues/

Next: Visualization.