autoseqmodels
Automated weekly sequence-model workflow for customer transaction prediction. Provides an end-to-end pipeline from raw transaction tables to trained LSTM / Transformer models, with column-type inference, encoding strategy proposal, per-customer sequence construction, training, tuning (Optuna), and holdout evaluation.
Installation
pip install autoseqmodels
Or from a local clone:
pip install -e .
Expected input format
build_transaction_panel does not infer column roles — auto-detection
silently degrades if the inputs don't match these expectations:
tx_df(raw transactions, one row per purchase) must contain a customer-identifier column (the name you pass asmerge_on, e.g."Id") and exactly one date-typed column (eitherdatetime64dtype, or a string column whose name contains"date"and parses as a date). Any other columns are ignored at panel-building time but flow through to the panel and are typed in step 3.cov_df(optional covariate calendar) must contain the samemerge_oncolumn, exactly one date-typed column (the per-week observation date), and one row per(customer, week). Merge-key dtypes are coerced automatically across the two tables, so anint64Idon one side and a stringIdon the other is fine.- The downstream
build_transaction_sequencesstep expects the panel to carry atransaction_countcolumn (added bybuild_transaction_panel) plus the customer and date columns; everything else is treated as a feature.
Workflow
Steps 1-7 prepare the data and are identical for both training paths. Step 8 has two variants — pick one:
- 8a trains a single model with hyperparameters you set yourself.
- 8b runs an Optuna search, then refits with the best trial.
Steps 1-7 — data preparation (shared)
from autoseqmodels import (
loader, inspection, encoders, sequence_builder,
)
# 1. Load data (CSV / Excel / RData)
df = loader.load_table("transactions.csv")
# 2. Aggregate raw transactions to a (customer, week) panel
# Two modes:
# a) With a covariate calendar — pass tx_df + cov_df:
panel = loader.build_transaction_panel(tx_df, cov_df, merge_on="Id")
# b) Transactions only (no covariates) — omit cov_df:
panel = loader.build_transaction_panel(tx_df, merge_on="Id")
# The transactions-only mode returns one row per (customer, purchase-week);
# sequence_builder fills zero-transaction weeks itself in step 7.
# 3. Detect column types (user-editable)
detected = inspection.infer_column_types(panel)
panel = inspection.cast_columns_by_detected_type(panel, detected)
# 4. Resolve entity / date / target + covariate plan
structure, plan = inspection.analyze_structure(panel, detected)
# 5. Propose encoding strategy (user-editable)
strategy = encoders.propose_encodings(panel, detected, plan)
# 6. Fit encoders on training rows only
enc_df, spec = encoders.apply_encodings(panel, strategy, ...)
plan = encoders.expand_plan(plan, spec)
# 7. Build per-customer sequences
seqs = sequence_builder.build_transaction_sequences(enc_df, ...)
Step 8a — train with fixed hyperparameters
Use this when you already know the hyperparameters you want or just need a quick baseline. No Optuna involved.
from autoseqmodels import training, sequence_lstm
ds = training.SequenceDataset(seqs)
train_ds, val_ds = training.make_train_val_split(ds, val_fraction=0.1, seed=42)
model = sequence_lstm.SequenceLSTM.from_sequences(
seqs, hidden_size=128, n_layers=1, dropout=0.1,
)
history = training.train_model(model, train_ds, val_ds, lr=1e-3, epochs=30)
preds = sequence_lstm.predict_holdout(model, seqs)
Step 8b — train with Optuna hyperparameter search
tune_lstm runs the search; train_tuned_lstm is the post-tuning refit
and requires the resulting study plus the same train/val subsets.
The study persists to SQLite when storage is given, so re-running the
same study_name resumes from where it left off.
from autoseqmodels import training, sequence_lstm
ds = training.SequenceDataset(seqs)
train_ds, val_ds = training.make_train_val_split(ds, val_fraction=0.1, seed=42)
study = sequence_lstm.tune_lstm(
seqs,
train_ds,
val_ds,
n_trials = 30,
max_epochs = 100,
storage = "sqlite:///optuna_lstm.db",
study_name = "lstm_v1",
)
model, history = sequence_lstm.train_tuned_lstm(seqs, study, train_ds, val_ds)
preds = sequence_lstm.predict_holdout(model, seqs)
The Transformer variant mirrors both step-8 paths under
sequence_transformer: build with SequenceTransformer.from_sequences
training.train_model(8a), ortune_transformer→train_tuned_transformer→predict_holdout_transformer(8b).
Minimal runnable example
End-to-end on the bundled Electronic.csv (Id, Date, Price,
829 customers, transactions from 1999-01-01 to 2004-11-30). Uses the
transactions-only mode of build_transaction_panel so no covariate file
is needed; the same script works with a covariate calendar by passing it
as the second positional argument.
from autoseqmodels import (
loader, inspection, encoders, sequence_builder,
training, sequence_lstm,
)
# 1-2. Load and aggregate to a (customer, week) panel
tx_df = loader.load_table("Datasets/Electronic.csv")
panel = loader.build_transaction_panel(tx_df, merge_on="Id")
# 3. Detect column types and cast
detected = inspection.infer_column_types(panel)
panel = inspection.cast_columns_by_detected_type(panel, detected)
# 4. Resolve entity / date / target + covariate plan
structure, plan = inspection.analyze_structure(
panel, detected, target_col="transaction_count"
)
# 5-6. Encoding strategy + fit on training rows
strategy = encoders.propose_encodings(panel, detected, plan)
train_mask = panel["Date"] <= "2003-12-31"
enc_df, spec = encoders.apply_encodings(panel, strategy, train_mask=train_mask)
plan = encoders.expand_plan(plan, spec)
# 7. Build per-customer sequences (3-year calibration, 11-month holdout)
seqs = sequence_builder.build_transaction_sequences(
enc_df,
account_col = "Id",
date_col = "Date",
training_start = "2001-01-01",
training_end = "2003-12-31",
holdout_start = "2004-01-01",
holdout_end = "2004-11-30",
transaction_col = "transaction_count",
plan = plan,
seasonality = ["woy"],
)
# 8. Tune with Optuna, refit on the best trial, then roll out the holdout
ds = training.SequenceDataset(seqs)
train_ds, val_ds = training.make_train_val_split(ds, val_fraction=0.1, seed=42)
study = sequence_lstm.tune_lstm(
seqs, train_ds, val_ds,
n_trials = 10,
max_epochs = 30,
storage = "sqlite:///optuna_lstm.db",
study_name = "electronic_demo",
)
model, history = sequence_lstm.train_tuned_lstm(seqs, study, train_ds, val_ds)
preds = sequence_lstm.predict_holdout(model, seqs)
To verify the install in a few minutes, drop n_trials and max_epochs
to small values (e.g. 3 and 10). Re-running the same script with the
same study_name resumes the existing Optuna study from the SQLite
file.
Modules
loader — input I/O and panel aggregation
load_table(path, ...)— read.csv,.xlsx/.xls,.RData/.rda. For R files,r_covariates_object_name(and optionalr_base_object_name) returns a(base_df, covariates_df)tuple in one call.build_transaction_panel(tx_df, cov_df=None, merge_on=...)— aggregate raw transactions into a weekly(customer, week)panel. Withcov_df, left-joins counts onto a covariate calendar (missing weeks → 0). Withoutcov_df, returns one row per(customer, purchase-week); the sequence builder fills zero weeks itself. Auto-detects the date column and reconciles merge-key dtypes across the two tables.
inspection — column typing & structural analysis
infer_column_types(df, config=TypeDetectionConfig())— Auto-Prep-style detection: id / bool / date / time / category / string, plus a statistical role (identifier / discrete / continuous / binary / categorical / temporal / text). Output is a typed summary DataFrame (detected) the user can edit before casting.cast_columns_by_detected_type(df, detected)— apply the inferred dtypes column by column.propose_structure(detected)→DataStructure— pickentity_col,date_col(highest-cardinality date), and surface alternatives asentity_candidates/date_candidates.classify_time_variance(df, entity_col, detected)— label every column asinvariant/variantper entity, and pick the main transaction date.plan_covariates(df, detected, structure)→CovariatePlan— classify every column asstatic_cols,time_varying_cols, orskip_cols, with per-column encoding hints.analyze_structure(df, detected, unknown_future_cols=None, target_col=None)— one-shot wrapper that runspropose_structure+plan_covariatesand removes columns whose future values aren't known at prediction time fromtime_varying_cols.
encoders — turning columns into model-ready numerics
propose_encodings(df, detected, plan, ...)— pick a strategy per column:EMBED(id or high-cardinality category),ONE-HOT(low-cardinality),SCALE(numeric, Standard or MinMax), orPASSTHROUGH(binary). Embedding dimension follows the Guo & Berkhahn rule. Strategy is user-editable.apply_encodings(df, strategy, training_mask=...)— fit encoders on training rows only, transform the whole panel, return(enc_df, spec)wherespec: EncodingSpeccarries the embedding vocabularies, scaler parameters, one-hot category orders, and the totalinput_width.expand_plan(plan, spec)— rewrite theCovariatePlanso one-hot expansion columns replace their source column.prepare_encodings(...)/encoding_report(spec)— convenience wrapper and a human-readable summary table.
sequence_builder — per-customer weekly sequences
build_transaction_sequences(df, *, account_col, date_col, training_start, training_end, holdout_start, holdout_end, transaction_col="transaction_count", plan=None, covariate_cols=None, time_varying_cols=None, seasonality=None, clip_transactions=None)— constructs its own universal weekly calendar from(training_start, holdout_end), merges each customer's transactions onto it (zero-filling missing weeks), and emits a dict withsamples / targets(calibration shifted by one),calibration(full training tensor),holdout(rollout tensor),account_ids,n_features,feature_names,total_transactions. Optional seasonality features:woy / moy / dow / year(sin/cos pairs).
models.training — dataset, split, train loop, evaluation
SequenceDataset— wraps the dict frombuild_transaction_sequencesfor use withDataLoader.make_train_val_split(dataset, val_fraction=..., seed=...)— customer-level random split (no leakage between train and val).train_model(model, train_ds, val_ds, ...)— generic training loop with early stopping, returns the per-epoch loss history.evaluate_predictions(...)— MAE / RMSE / aggregate-count metrics on the holdout rollout.plot_training_and_predictions(...)— quick-look loss curves and predicted-vs-actual transaction plots.
models.sequence_lstm — LSTM model + Optuna tuning
SequenceLSTM(nn.Module)— embedding layers (one per id / categorical), multi-layer LSTM, regression head; consumes thefeature_namesorder produced bybuild_transaction_sequences.predict_holdout(model, seqs)— autoregressive holdout rollout, returns predicted weekly counts per customer.tune_lstm(seqs, train_ds, val_ds, *, n_trials, max_epochs, storage=None, study_name=None, fixed_params=None)— Optuna search overhidden_size,n_layers, dropout, learning rate, batch size, … Studies persist to SQLite (sqlite:///optuna_lstm.db) whenstorageis given, so runs are resumable. Any param can be pinned viafixed_params.train_tuned_lstm(seqs, study, train_ds, val_ds)— refit with the best trial's hyperparameters, returning(model, history).
models.sequence_transformer — Transformer mirror
SequenceTransformer(nn.Module)— same input contract asSequenceLSTMbut with positional encoding and a TransformerEncoder stack;n_headsis auto-picked to divided_model.predict_holdout_transformer,tune_transformer,train_tuned_transformer— direct counterparts of the LSTM helpers, with their own SQLite study (optuna_transformer.db).
Requirements
Python ≥ 3.10. See pyproject.toml for the full dependency list.
License
MIT — see LICENSE.
Metadata
Release files for autoseqmodels 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| autoseqmodels-0.1.2.tar.gz | 55.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| autoseqmodels-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 107.0 kB
Release files / autoseqmodels-0.1.2.tar.gz
| Download URL | autoseqmodels-0.1.2.tar.gz |
|---|---|
| Size | 55.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
616cd343297e806c5d28dd7e92e20e392958e86a17694e69f190dbc9fa57b206
|
|
BLAKE2b-256 checksum How to use checksums |
c7ae96d0d6fce1e8d36331380036ed2b6c875eea8d679a902013e0e3ed017d79
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / autoseqmodels-0.1.2-py3-none-any.whl
| Download URL | autoseqmodels-0.1.2-py3-none-any.whl |
|---|---|
| Size | 51.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
829e1d21dde1f3fb902cf86a795c161e2b5ae8434bb780dbb2c30e09aa5291f9
|
|
BLAKE2b-256 checksum How to use checksums |
ec009331fb3725b880c58f449b2acc01025a3711846c2bbf1cde6a89864dedb4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|