Skip to content

Predictive Studio

Train predictive models on a client’s own data — and score records with them — entirely inside MemberJunction. Member retention/renewal, lapse and lead scoring, and any other tabular yes/no-or-number question, answered by a model trained on their data.

Predictive Studio is core MJ, not an OpenApp. It is composed onto existing MJ substrates (entities/RunView, Record Set Processing, Remote Operations, Agents, vectors) plus a self-managing Python ML sidecar — rather than re-implementing batching, audit, training, or inference. This folder is the three npm packages that make that work.

Start here, then read the Predictive Studio Guide for the full architecture, the data model (MJ: ML Models / Experiments / …), the dashboard, and end-to-end walkthroughs. The design record is plans/predictive-studio.md.

Predictive Studio is one pipeline split across four layers. The first three live in TypeScript (this folder); the model-compute layer is a bundled Python service.

flowchart LR
    subgraph DATA["1 · Data"]
        D["Entities · Queries · External entities<br/>Vector sets · Feature Pipelines"]
    end
    subgraph FEATURE["2 · Feature"]
        F["FeatureAssemblyExecutor<br/>(as-of · leakage guard · fit-once recipe)"]
    end
    subgraph MODEL["3 · Model (compute)"]
        M["MLSidecar → Python FastAPI<br/>xgboost · lightgbm · scikit-learn"]
    end
    subgraph INFER["4 · Inference"]
        I["MLModelInferenceProcessor<br/>(Record Set Processing work type)"]
    end
    D --> F --> M --> I
    M -. "immutable, versioned" .-> ML["MJ: ML Models"]
    ML --> I
LayerWhat happensLives in
1 · DataPull the training/scoring rows from MJ’s existing substrates@memberjunction/predictive-studio (feature-assembly/data-access)
2 · FeatureAssemble the raw matrix identically for train / materialize / on-demand; enforce point-in-time (as-of) and leakage deny-lists; emit a fit-once preprocessing recipe@memberjunction/predictive-studio (feature-assembly)
3 · ModelThe CPU-bound fit (/train) and inference (/predict) — Node orchestrates, Python computes@memberjunction/predictive-studio-sidecar (+ bundled Python)
4 · InferenceBatch + single-record scoring as a Record Set Processing work type, ephemeral or write-back@memberjunction/predictive-studio (scoring)

The cardinal correctness rule runs through all four: one feature-assembly code path, used identically everywhere, plus fit-once / apply-everywhere preprocessing — so there is no train/serve skew by construction.

PackageWhat it isRead
@memberjunction/predictive-studio-coreThe shared type contracts — the sidecar /train+/predict shapes, the declarative pipeline spec, the visual FeatureStep DAG, the Model Development Agent’s ModelingPlanSpec, plus the zod runtime validators and the metric-direction helper. Defined once; imported by everything; importing (almost) nothing.Core/README.md
@memberjunction/predictive-studio-sidecarA self-managing TypeScript wrapper (MLSidecar) around a bundled Python FastAPI ML service. new MLSidecar(); await s.start() and you have a live training/inference service — no Docker required (managed child-process spawn on an ephemeral port; remote-URL mode for scaled deployments).Sidecar/README.md
@memberjunction/predictive-studioThe server-side engine — FeatureAssemblyExecutor, TrainingEngine, MLModelInferenceProcessor, ExperimentOrchestrator, plus feature-pipeline discovery, maintenance, and the Actions + Remote Operations invocation surfaces.Engine/README.md
predictive-studio-core (types — no runtime deps except zod)
│ imported by
├── predictive-studio-sidecar → MLSidecar + bundled Python service
└── predictive-studio (Engine) → the four engines + Actions + Remote Operations
│ which also depends on
└── predictive-studio-sidecar (MLSidecar)

Per root CLAUDE.md rule 5, types are imported directly from -core — never re-exported through -sidecar or the Engine.

One-time setup (fresh clone). Predictive Studio’s packages depend on other workspace packages, so build them together, never one by one (a per-package tsc on a fresh clone fails with TS2307 Cannot find module '@memberjunction/core'):

Terminal window
pnpm install # repo root
pnpm run build # repo root: builds PS and everything it depends on, in dependency order
pnpm --filter @memberjunction/predictive-studio-sidecar run setup:python

setup:python needs CPython 3.11 or 3.12 (numpy 1.26.4 has no wheels for 3.13+); it tries python3.11, python3.12, python3, python and stops with the list it probed if none fits. Pass -- --python <path> after the setup:python command to choose one. On macOS also brew install libomp (XGBoost/LightGBM). To run the sidecar or its tests on another interpreter, set PREDICTIVE_STUDIO_PYTHON=<path to python>.

Then train + score in TypeScript:

import { MLSidecar } from '@memberjunction/predictive-studio-sidecar';
const sidecar = new MLSidecar(); // managed mode — spawns the bundled Python service
await sidecar.start();
const trained = await sidecar.train(/* TrainRequest from @memberjunction/predictive-studio-core */);
const { predictions } = await sidecar.predict(/* PredictRequest */);
await sidecar.stop();

For the full path — pipeline → TrainingEngine → immutable MJ: ML Models row → MLModelInferenceProcessor scoring, plus the experiment search and the Studio dashboard — see the Engine README and the guide.

PackageCommandCovers
Core / Sidecar / Enginenpm run test (per package)Vitest unit tests — all seams mocked, no DB, no live process
Sidecar (Python)npm run test:python (after setup:python)pytest — per-algorithm train/predict + the anti-skew preprocessing golden tests
Engine (live)npm run test:integration with PS_INTEGRATION=1End-to-end against the real managed Python sidecar; skips gracefully if the venv is missing