RamenTruck
RamenTruck is a machine learning and deep learning toolkit for Python, designed to simplify the modeling workflow from dataset inspection and preprocessing through feature engineering, training, tuning, evaluation, calibration, ensembling, explainability, experiment tracking, and serving.
Built as the machine learning companion to ThaiTruck, RamenTruck emphasizes clean APIs, reproducible workflows, and production-ready engineering practices rather than notebook-only examples.
Great ramen isn't rushed. Neither is great machine learning.
Table of Contents
- Why RamenTruck?
- Installation
- Quickstart
- Module Guide
- noodles — dataset inspection
- kaedama — feature engineering
- broth — model training
- tare — hyperparameter tuning
- soft_boiled_egg — cross-validation
- kaeshi — probability calibration
- toppings — ensemble methods
- diagnostics — shared model-quality rules
- nori — explainability
- chashu — model persistence
- donburi — prediction and serving
- miso — experiment tracking
- tonkotsu — deep learning
- drivethrough — multi-label text classification
- Module Reference Table
- Design Principles
- The Food Truck Fleet
- Current Status
- License
Why RamenTruck?
Machine learning projects often require dozens of disconnected libraries and hundreds of lines of repetitive boilerplate before the first model is ever trained.
RamenTruck provides a unified, opinionated toolkit that helps you:
- Inspect datasets and receive intelligent preprocessing recommendations
- Engineer new features from raw columns
- Train and evaluate classical machine learning models
- Tune hyperparameters
- Cross-validate and diagnose learning curves
- Calibrate predicted probabilities
- Combine multiple models into ensembles
- Explain model predictions
- Track experiments across runs
- Save, version, and reload trained models
- Serve predictions through a clean, validated API
- Build modern neural network architectures
The goal is to let data scientists spend less time wiring together infrastructure and more time building better models.
Every module is named after something you'd find in an actual bowl of ramen. The metaphors aren't just decoration - each one describes what the module does:
| Ramen term | What it is, literally | What the module does |
|---|---|---|
| noodles | The base ingredient | Inspect and understand your raw dataset |
| kaedama | A refill of noodles dropped into remaining broth | Add engineered feature columns to a dataset |
| broth | The base liquid everything else builds on | Train and evaluate a model |
| tare | The concentrated seasoning that defines the bowl | Tune hyperparameters |
| soft_boiled_egg | A topping that's all about timing | Cross-validate and check learning curves |
| kaeshi | The sauce blended in to balance final flavor | Calibrate predicted probabilities |
| toppings | Many ingredients, combined, better together | Ensemble multiple models |
| nori | A thin layer that adds insight/flavor on top | Explain model predictions |
| chashu | Slow-cooked, preserved, sliced when needed | Persist and version trained models |
| donburi | The bowl the finished dish is served in | Serve predictions through an API |
| miso | Fermented; wisdom accumulated over time | Track experiments across runs |
| tonkotsu | Heavy, rich, long-cooked | Deep learning |
| drivethrough | Raw orders in, requested items out | Multi-label text classification |
Installation
Core installation:
pip install ramentruck
The core install pulls in noodles, kaedama, broth, tare,
soft_boiled_egg, kaeshi, toppings, diagnostics, chashu, and
donburi. These only require:
numpy
pandas
scikit-learn
joblib
Three modules wrap heavier, optional libraries and are installed via extras so you never pay for a dependency you don't use:
pip install ramentruck[deep] # tonkotsu: tensorflow, matplotlib
pip install ramentruck[explain] # nori: shap, matplotlib
pip install ramentruck[tracking] # miso: mlflow
pip install ramentruck[nlp] # drivethrough's pretrained sentence-embedding encoder
pip install ramentruck[all] # everything above
Importing an extras-gated module without its dependency installed
raises a clear ImportError telling you exactly which extra to install
- there's no silent fallback or degraded behavior.
drivethrough is a special case worth calling out: the module itself
requires no extra (its default TF-IDF + linear backend only needs
scikit-learn, already a core dependency), but its optional neural
backend needs [deep] and its optional pretrained sentence-embedding
vectorizer needs [nlp]. Both are imported lazily, only when you
actually select them, so picking the TF-IDF+linear combination never
requires installing TensorFlow or sentence-transformers.
Quickstart
An end-to-end walkthrough touching most of the toolkit, from a raw DataFrame to a served prediction:
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from ramentruck import slurp, Kaedama, Broth, tare, soft_boiled_egg, chashu, Donburi
# 1. Inspect the dataset
menu = slurp(df, target="Purchased")
print(menu)
# 2. Engineer a couple of extra features
kaedama = Kaedama().ratio("income", "age").log_transform("income")
engineered = kaedama.fit_transform(df)
X = engineered.drop(columns=["Purchased"])
y = engineered["Purchased"]
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
# 3. Tune hyperparameters
tuned = tare(
RandomForestClassifier(random_state=42),
param_grid={"n_estimators": [100, 200], "max_depth": [4, 8, None]},
X=X_train, y=y_train, method="grid", cv=5,
)
# 4. Train and evaluate the best configuration
trainer = Broth(tuned.best_model)
result = trainer.fit(X_train, y_train, X_val, y_val, metrics=["accuracy", "f1", "roc_auc"])
print(result.metrics)
# 5. Cross-validate to sanity-check the split
cv_result = soft_boiled_egg(tuned.best_model, X_train, y_train, learning_curve=True)
# 6. Persist the model
chashu.save(trainer.estimator, "models/rf_v1.chashu", metadata={"feature_names": list(X.columns)})
# 7. Serve predictions
donburi = Donburi.from_chashu("models/rf_v1.chashu")
response = donburi.serve({col: X_val.iloc[0][col] for col in X.columns})
print(response) # {"prediction": 1, "probabilities": {"0": 0.12, "1": 0.88}}
Module Guide
noodles — dataset inspection
The base ingredient: before anything else, you need to understand what
you're working with. slurp() inspects a DataFrame and returns a
DatasetMenu with statistics and preprocessing recommendations.
from ramentruck import slurp
menu = slurp(df, target="Purchased")
print(menu)
DatasetMenu includes:
- Row/column counts and memory usage
- Column type breakdown (numeric, categorical, boolean, datetime)
- Missing value counts and percentages, per column
- Duplicate row count
- A
ChefRecommendation: inferred problem type (classification vs. regression), suggested scaling/encoding, loss function, output activation, optimizer, and class imbalance detection
print(menu) renders a formatted text report; every field is also
available as a plain attribute (menu.rows, menu.missing_values,
menu.chef_recommendation.problem_type, etc.) for programmatic use.
kaedama — feature engineering
An extra serving of noodles dropped into broth that's already been
depleted. Kaedama is a fluent builder for adding engineered columns
to a DataFrame without touching the original data.
from ramentruck import Kaedama
kaedama = (
Kaedama()
.datetime_features("signup_date", features=("year", "month", "dayofweek"))
.polynomial_features(["income", "age"], degree=2)
.ratio("income", "household_size", name="income_per_person")
.log_transform("income")
.bin("age", bins=[0, 18, 35, 50, 65, 120], labels=["<18", "18-34", "35-49", "50-64", "65+"])
)
engineered = kaedama.fit_transform(df)
print(kaedama.added_columns_) # every column name that was added, in order
Available steps:
| Method | Adds |
|---|---|
.datetime_features(cols, features=...) |
Calendar components (year, month, day, dayofweek, hour, ...) pulled from any .dt accessor attribute |
.polynomial_features(cols, degree=, interaction_only=) |
Powers and interaction terms via scikit-learn's PolynomialFeatures |
.ratio(numerator, denominator, name=) |
A safe ratio column (division by zero produces NaN, not an error) |
.log_transform(cols, offset=) |
Natural-log transformed columns |
.bin(col, bins=, labels=, name=) |
A categorical bucketed version of a numeric column |
fit_transform() never mutates the input DataFrame - it returns a new
one with the original columns plus everything added by each chained
step. Chain as many steps as you like before calling it once.
broth — model training
The base liquid everything else is built on. Broth wraps any
scikit-learn compatible estimator (implementing fit/predict) with
consistent training, scoring, and overfitting diagnostics.
from sklearn.ensemble import RandomForestClassifier
from ramentruck import Broth
trainer = Broth(RandomForestClassifier(random_state=42))
result = trainer.fit(
X_train, y_train,
X_val, y_val,
metrics=["accuracy", "f1", "roc_auc"],
)
print(result.train_score, result.val_score, result.metrics, result.fit_time_s)
predictions = trainer.predict(X_val)
score = trainer.score(X_val, y_val, metric="f1")
Supported metrics names: accuracy, precision, recall, f1,
roc_auc, mse, rmse, r2. Precision/recall/F1 automatically pick
binary vs. weighted averaging based on the number of classes in y.
roc_auc supports both binary and multiclass (one-vs-rest) targets.
If validation data is supplied and the training score exceeds the
validation score by more than 0.10, Broth.fit() raises a UserWarning
so overfitting doesn't go unnoticed.
tare — hyperparameter tuning
The concentrated seasoning that defines the bowl - small adjustments,
big impact. tare() wraps GridSearchCV/RandomizedSearchCV behind a
single function.
from sklearn.ensemble import GradientBoostingClassifier
from ramentruck import tare
result = tare(
GradientBoostingClassifier(),
param_grid={"n_estimators": [50, 100, 200], "learning_rate": [0.01, 0.1, 0.3]},
X=X_train, y=y_train,
method="random", # or "grid"
n_iter=20, # only used by method="random"
cv=5,
scoring="roc_auc",
)
print(result.best_params, result.best_score)
best_model = result.best_model # already refit on the full training set
print(result.cv_results.head()) # every candidate, best rank first
print(result.search_time_s)
soft_boiled_egg — cross-validation
A topping that's all about timing and calibration. soft_boiled_egg()
cross-validates a model and can compute learning curves in the same
call, surfacing overfitting/underfitting patterns directly.
from ramentruck import soft_boiled_egg
result = soft_boiled_egg(
my_model,
X, y,
strategy="stratified", # "kfold", "stratified", or "timeseries"
n_splits=5,
scoring=["accuracy", "f1"], # first entry is the primary metric
learning_curve=True,
)
print(f"{result.mean_score:.3f} +/- {result.std_score:.3f}")
print(result.fold_results) # per-fold scores for every requested metric
print(result.learning_curve_df) # train_size, train/val score mean and std
strategy="stratified" preserves class balance per fold and is the
default. strategy="timeseries" never shuffles, respecting temporal
order. A UserWarning fires if fold-to-fold variance exceeds 0.05, or
if n_splits exceeds the minority class count under stratified
splitting.
kaeshi — probability calibration
The concentrated sauce blended with dashi to balance a bowl's final
flavor. kaeshi() calibrates a binary classifier's predicted
probabilities so they can be trusted at face value (a model with
"90% confidence" should be right about 90% of the time).
from sklearn.svm import SVC
from ramentruck import kaeshi, plot_calibration_curve
result = kaeshi(
SVC(probability=True),
X_train, y_train,
method="isotonic", # or "sigmoid" (Platt scaling) for smaller datasets
cv=5,
)
print(result.brier_score_before, result.brier_score_after)
calibrated_model = result.model
fig = plot_calibration_curve(result) # reliability diagram
method="sigmoid" is generally more stable on small or noisy datasets;
method="isotonic" is more flexible but needs more data to avoid
overfitting the calibration curve itself. Currently supports binary
classification only.
toppings — ensemble methods
Many ingredients, combined, better together than any single one alone.
toppings wraps scikit-learn's voting, stacking, and bagging ensembles
behind a consistent API that also scores each individual member for
comparison.
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from ramentruck import toppings
# Voting: combine independently-trained models
result = toppings.voting(
{"logreg": LogisticRegression(max_iter=500), "tree": DecisionTreeClassifier()},
X_train, y_train,
task="classification",
voting_type="soft",
)
print(result.train_score, result.individual_scores)
# Stacking: train a meta-model on the base models' out-of-fold predictions
result = toppings.stack(
{"logreg": LogisticRegression(max_iter=500), "tree": DecisionTreeClassifier()},
meta_model=LogisticRegression(max_iter=500),
X=X_train, y=y_train,
cv=5,
)
# Bagging: many bootstrap-sampled copies of one model
result = toppings.bag(
DecisionTreeClassifier(),
X_train, y_train,
n_estimators=25,
)
All three accept task="classification" or task="regression", and
optional X_val/y_val to score against held-out data instead of
training data. Every call returns a ToppingsResult with the fitted
ensemble, train_score, val_score, individual_scores (per member),
and fit_time_s.
diagnostics — shared model-quality rules
Deterministic evaluation rules shared across the toolkit: overfitting, underfitting, small-dataset, high-variance, and class-imbalance detection, each with concrete recommendations and confidence scores.
from ramentruck import DiagnosticEngine
report = DiagnosticEngine().evaluate(
train_score=0.96,
validation_score=0.80,
dataset_size=80,
variance=0.07,
class_imbalance=True,
)
print(report.diagnosis) # "Mild overfitting detected."
print(report.warnings) # ("Small dataset detected.", "High validation variance.", ...)
print(report.recommendations) # tuple of Recommendation(message, category, severity, confidence)
print(report.chef_report()) # formatted text report combining all of the above
DiagnosticEngine is standalone infrastructure - it isn't automatically
invoked by Broth or soft_boiled_egg, but is available any time you
want a consistent, rule-based second opinion on a set of scores.
nori — explainability
Requires pip install ramentruck[explain].
A thin layer that adds insight on top. nori wraps SHAP to explain
what any model is actually paying attention to, at both the dataset and
individual-prediction level.
from ramentruck import nori
result = nori.explain(model, X_test) # auto-picks Tree/Linear/model-agnostic SHAP explainer
print(result.importance) # feature, mean_abs_shap - sorted
fig = nori.plot_importance(result, max_display=15) # bar chart
fig = nori.plot_summary(result, max_display=15) # beeswarm-style per-sample plot
# Explain one specific prediction
contributions = nori.explain_instance(result, index=0)
print(contributions) # per-feature SHAP value, sorted by magnitude
# Partial dependence: how does the prediction change as one feature varies?
pd_result = nori.partial_dependence(model, X_test, features=["age", "income"], grid_resolution=20)
fig = nori.plot_partial_dependence(pd_result)
For binary classifiers, explain() defaults to explaining the positive
class. Multiclass models require an explicit class_index argument -
nori raises a clear ValueError rather than guessing which class you
meant.
chashu — model persistence
Slow-cooked, preserved perfectly, sliced when needed. chashu wraps
joblib with versioning metadata so saved models are traceable months
later.
from ramentruck import chashu
chashu.save(
trainer.estimator,
"models/rf_v1.chashu",
metadata={"val_auc": 0.93, "feature_names": list(X.columns)},
)
bundle = chashu.load("models/rf_v1.chashu")
print(bundle.model, bundle.metadata, bundle.saved_at, bundle.sklearn_version)
catalog = chashu.list_models("models/") # one row per bundle, with metadata as columns
Every bundle automatically records saved_at, the RamenTruck version,
Python version, and scikit-learn version at save time. chashu.load()
warns (rather than fails) if the current scikit-learn version doesn't
match what the bundle was saved with. chashu.save() refuses to
overwrite an existing bundle path unless you pass overwrite=True.
donburi — prediction and serving
The bowl the finished dish is served in. Donburi wraps a fitted model
for prediction, adding record-level validation and a JSON-friendly
serve() method that plugs directly into a REST endpoint.
from ramentruck import Donburi, chashu
# From an in-memory model:
donburi = Donburi(trainer.estimator, feature_names=list(X.columns))
# Or straight from a saved chashu bundle (feature_names is restored from its metadata):
donburi = Donburi.from_chashu("models/rf_v1.chashu")
donburi.predict(X_val) # batch predictions, as a numpy array
donburi.predict_proba(X_val) # raises AttributeError if unsupported
donburi.predict_one({"age": 34, "income": 52000}) # single record -> single prediction
donburi.predict_batch([{"age": 34, "income": 52000}, {"age": 61, "income": 88000}])
donburi.serve({"age": 34, "income": 52000})
# {"prediction": 1, "probabilities": {"0": 0.12, "1": 0.88}}
When feature_names is known (either passed explicitly or restored
from a chashu bundle's metadata), every record-based call validates
that all required features are present and raises a descriptive
ValueError naming exactly what's missing - so a malformed request
fails loudly instead of producing a silently wrong prediction.
miso — experiment tracking
Requires pip install ramentruck[tracking].
Fermented - wisdom accumulated over many runs. miso wraps MLflow for
experiment tracking that works out of the box with zero setup: runs are
recorded to a local SQLite-backed store (.miso/tracking.db) unless you
point it at a shared or remote tracking server.
from ramentruck import miso
with miso.brew("rf_experiment", run_name="rf_v1") as run:
run.log_params({"n_estimators": 200, "max_depth": 8})
run.log_metric("accuracy", 0.93)
run.log_metrics({"f1": 0.91, "roc_auc": 0.97})
run.log_model(trainer.estimator)
run.log_artifact("plots/learning_curve.png")
runs = miso.list_runs("rf_experiment") # every run, most recent first
best = miso.best_run("rf_experiment", "accuracy", mode="max")
print(best.run_id, best.params, best.metrics)
Point tracking_uri (or the MLFLOW_TRACKING_URI environment variable)
at http://your-mlflow-server:5000 to share runs across a team without
changing any other code.
tonkotsu — deep learning
Requires pip install ramentruck[deep].
Heavy, rich, long-cooked. tonkotsu wraps TensorFlow/Keras (functional
API) for building and training neural networks, from a plain dense
network to a full ResNet.
from ramentruck import tonkotsu
# Dense feedforward network
model = tonkotsu.build_dense(
input_dim=20, hidden_layers=[64, 32], output_dim=1,
dropout_rate=0.3, l2_lambda=0.001, batch_norm=True,
)
result = tonkotsu.simmer(
model, X_train, y_train, X_val, y_val,
epochs=100, early_stopping=True, patience=10,
checkpoint_path="checkpoints/best.keras",
)
print(result.best_epoch, result.stopped_early, result.train_time_s)
fig = tonkotsu.plot_history(result)
# A custom callback that fires every N epochs
callback = tonkotsu.EveryNEpochs(5, lambda epoch, logs: print(epoch, logs))
# CNN family: one-call ResNet50-equivalent, or compose your own
resnet = tonkotsu.build_resnet(input_shape=(64, 64, 3), classes=6)
result = tonkotsu.simmer(resnet, X_train_img, y_train_img, X_val_img, y_val_img, epochs=50)
build_dense and build_resnet return models built with the Keras
functional API, not Sequential - every layer is named, and the
returned model can be freely composed into larger graphs.
residual_identity_block and residual_conv_block are exposed
individually if you want to assemble a custom architecture rather than
use the build_resnet preset. An RNN/sequence family (LSTM, GRU,
attention) is planned next.
drivethrough — multi-label text classification
Raw orders come in, requested items go out. drivethrough classifies
text into zero, one, or several consumer-defined labels - it has no
built-in notion of what those labels mean. A support-ticket classifier
and an AI-agent router are both just label vocabularies to this module.
from ramentruck.drivethrough import MultiLabelTextClassifier
labels = ["BILLING", "SALES", "TECH_SUPPORT", "CANCELLATION"]
texts_train = [
"I want to cancel my subscription",
"how much does the premium plan cost",
"my app keeps crashing on startup",
"I was charged twice this month",
"please cancel my plan and refund the last charge",
]
labels_train = [
["CANCELLATION"],
["SALES"],
["TECH_SUPPORT"],
["BILLING"],
["CANCELLATION", "BILLING"],
]
# TF-IDF + independent per-label logistic regression: the lightweight,
# dependency-free default and a legitimate baseline in its own right.
classifier = MultiLabelTextClassifier(labels, vectorizer="tfidf", backend="linear")
classifier.fit(texts_train, labels_train)
result = classifier.predict_one("please refund me and cancel my account")
print(result.labels) # ["BILLING", "CANCELLATION"]
print(result.scores) # every label's probability, thresholded or not
print(result.abstained) # False - at least one label cleared its threshold
# Tune thresholds against VALIDATION data only, then evaluate on TEST once.
classifier.tune_thresholds(texts_val, labels_val, metric="f1")
report = classifier.evaluate(texts_test, labels_test)
print(report.micro_f1, report.hamming_loss, report.per_label)
# Swap in the neural backend (requires `pip install ramentruck[deep]`) -
# same API, same thresholds/evaluation/persistence.
neural_classifier = MultiLabelTextClassifier(labels, vectorizer="tfidf", backend="neural")
neural_classifier.fit(texts_train, labels_train, texts_val, labels_val)
# Complete, portable persistence.
classifier.save("models/support_router.drivethrough")
reloaded = MultiLabelTextClassifier.load("models/support_router.drivethrough")
Multi-class vs. multi-label
drivethrough deliberately never uses softmax. Softmax normalizes
probabilities across labels to sum to 1, which only makes sense when
labels are mutually exclusive. Real text isn't always: "how old was he
when he died" can require both a lookup and a calculation at once, and
a support message can be both a cancellation and a billing question.
Every backend produces independent per-label sigmoid probabilities
instead, and each label is thresholded on its own - so zero, one, or
several labels can apply to the same input.
Abstention
When no label clears its threshold, predict_one/predict_batch
return an empty label list with abstained=True - never a guessed
default label. Raw scores for every label are always included, even
when none cross the threshold. Deciding what to do next (retry, ask a
clarifying question, fall back to a default) is the consuming
application's job, not this module's.
Data leakage
- Fit the vectorizer (
classifier.fit(...)) on training text only - there is no parameter that lets validation or test text reach vectorizer fitting. - Call
tune_thresholds()with validation data only. It selects a decision threshold from already-computed probabilities; it does not recalibrate the probabilities themselves (seekaeshifor that). - Call
evaluate()against a held-out test set exactly once. Reusing its output to further tune thresholds or preprocessing turns "test" into a second validation set. check_for_leakage(protected_texts, corpus_texts)checks whether protected/held-out text (e.g. a frozen evaluation benchmark you supply) appears - exactly or after normalizing case/whitespace - in a training or validation corpus you supply. It has no built-in notion of what counts as "protected."
Linear vs. neural
backend="linear" (independent per-label logistic regression over
TF-IDF features) is a legitimate baseline, not a placeholder - it lets
you distinguish "text classification works for this problem" from "a
neural network measurably helps." backend="neural" is not assumed to
be better; it reuses tonkotsu.build_dense (sigmoid output) and
tonkotsu.simmer (binary cross-entropy) unchanged; comparing the two
backends' evaluate() reports on the same data is how you find out
which one actually earns its extra cost for your data.
Text representation is pluggable
vectorizer="tfidf" (default) needs no optional dependency.
vectorizer="sentence_embedding" (requires pip install ramentruck[nlp]) wraps a frozen, pretrained sentence-transformers
model - configurable by name, never hard-coded - trading a small
dependency for better generalization across paraphrased text. Both
implement the same TextVectorizer interface, so swapping one for the
other never touches the classifier or evaluation code.
Module Reference Table
| Module | Purpose | Extra required |
|---|---|---|
| noodles | Dataset inspection (slurp, DatasetMenu, ChefRecommendation) |
none |
| kaedama | Feature engineering (Kaedama) |
none |
| broth | Model training and evaluation (Broth, BrothResult) |
none |
| tare | Hyperparameter tuning (tare, TareResult) |
none |
| soft_boiled_egg | Cross-validation and learning curves (soft_boiled_egg, EggResult) |
none |
| kaeshi | Probability calibration (kaeshi, plot_calibration_curve, KaeshiResult) |
none |
| toppings | Ensemble methods (toppings.voting, .stack, .bag, ToppingsResult) |
none |
| diagnostics | Shared deterministic diagnostics (DiagnosticEngine, DiagnosticReport, Recommendation) |
none |
| chashu | Model persistence and versioning (chashu.save, .load, .list_models, ChashuBundle) |
none |
| donburi | Prediction and serving (Donburi) |
none |
| nori | Explainability (nori.explain, .plot_summary, .plot_importance, .partial_dependence, NoriResult, PDResult) |
[explain] |
| miso | Experiment tracking (miso.brew, .list_runs, .best_run, MisoRunSummary) |
[tracking] |
| tonkotsu | Deep learning (build_dense, simmer, build_resnet, EveryNEpochs, SipResult) |
[deep] |
| drivethrough | Multi-label text classification (MultiLabelTextClassifier, check_for_leakage, TfidfTextVectorizer, SentenceEmbeddingTextVectorizer) |
none ([deep] for the neural backend, [nlp] for sentence embeddings) |
Design Principles
RamenTruck is built around a few core ideas:
- Composable modules - every component can be used independently.
- Immutable workflows - functions return new objects rather than modifying inputs.
- Strong typing - type hints and dataclasses throughout.
- Production-first - built for real applications, not just notebooks.
- Testing-first - every public module includes automated unit tests.
- Explainability matters - model interpretation is a first-class feature.
- Classical ML and Deep Learning - one consistent API across both worlds.
- Optional extras stay optional - a missing
[extras]dependency fails loudly with an install hint, never silently.
The Food Truck Fleet
The Food Truck ecosystem consists of independent Python packages that work well together while remaining completely decoupled.
| Package | Purpose | Status |
|---|---|---|
| ThaiTruck | Data cleaning, transformation, and DataFrame utilities | Available |
| RamenTruck | Machine learning and deep learning toolkit | Available |
| SushiTruck | Streaming ingestion and API connectors | Planned |
| BentoTruck | Statistical analysis, feature engineering, and predictive analytics | Planned |
Each package can be installed independently and composes naturally with the others through standard pandas DataFrames and NumPy arrays.
Current Status
Version: 0.7.0
Every module from the original design is now implemented:
- Dataset inspection with
slurp() - Feature engineering with
Kaedama(datetime features, polynomial/interaction terms, ratios, log transforms, binning) - Classical model training with
Broth - Hyperparameter tuning with
tare(grid and randomized search) - Cross-validation and learning curves with
soft_boiled_egg - Probability calibration with
kaeshi(isotonic and sigmoid, with reliability diagrams) - Ensemble methods with
toppings(voting, stacking, bagging) - Shared deterministic diagnostics with
DiagnosticEngineandDiagnosticReport - Model persistence and versioning with
chashu - Prediction and serving with
Donburi(including afrom_chashuloader) - Explainability with
nori(SHAP-based feature importance, summary plots, instance explanations, partial dependence) - Experiment tracking with
miso(local-first, MLflow-backed, zero setup required) - Deep learning with
tonkotsu:build_dense(with optional seeded, reproducible weight initialization),simmer,plot_history,EveryNEpochs, and a CNN family (residual_identity_block,residual_conv_block,build_resnet) - Multi-label text classification with
drivethrough: pluggable text representation (TfidfTextVectorizer, optionalSentenceEmbeddingTextVectorizer) and pluggable classifier backends (LinearMultiLabelBackend,DenseNeuralMultiLabelBackend) behind oneMultiLabelTextClassifierAPI, with abstention, threshold tuning, multi-label evaluation and failure analysis, leakage checking, and complete bundle persistence - Shared result objects (
DatasetMenu,ChefRecommendation,BrothResult,TareResult,EggResult,ChashuBundle,KaeshiResult,ToppingsResult,NoriResult,PDResult,MisoRunSummary,SipResult) throughout - Comprehensive unit testing across every module
Planned next: an RNN/sequence family for tonkotsu (LSTM, GRU,
attention).
License
MIT License
RamenTruck is an open-source project built with the philosophy that elegant APIs, reproducible workflows, and thoughtful engineering should be available to every machine learning practitioner.
Release files for ramentruck 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ramentruck-0.7.0.tar.gz | 97.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ramentruck-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 159.0 kB
Release files / ramentruck-0.7.0.tar.gz
| Download URL | ramentruck-0.7.0.tar.gz |
|---|---|
| Size | 97.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
236bd005fc0de30b2a8409b5c3b57845b1072755861e3281d33b073e944abf83
|
|
BLAKE2b-256 checksum How to use checksums |
6dd38a3cf2d3070f9b0200ca5d9e02d6f7c1b44319501ba724d7d366eeffbc6d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|
Release files / ramentruck-0.7.0-py3-none-any.whl
| Download URL | ramentruck-0.7.0-py3-none-any.whl |
|---|---|
| Size | 62.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6956f76a351c329a86a09b7ee19c815ec78856e534c8526c29650e65f5bb15ea
|
|
BLAKE2b-256 checksum How to use checksums |
2d1b0bdd19a2d601b0af6e2bfd0780f5cca00f2a1070ba4bd110b87bcf4aff39
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|