MLFOX
Automated tabular machine learning on CPU. Give it a CSV, get a tested model and a report.
MLFOX takes a CSV, Excel file, or pandas DataFrame and handles the rest: it profiles the data, builds leakage-safe preprocessing, compares candidate models with cross-validation, evaluates the winner once on an untouched holdout set, and writes a report.
Built by vprojectx · Source: github.com/vprojectx-ai-lab/mlfox
Highlights
- One-line workflow:
mlfox().fit("data.csv", target="y") - Classification and regression, with automatic task detection
- Fold-aware preprocessing: imputation, encoding, scaling, feature engineering, and feature selection are learned only from each fold's training rows, so no information leaks from validation data
- Honest evaluation: the holdout set is never used to pick the model
- Reports: a short console summary, a full self-contained HTML report, and JSON export
- Explainability: permutation importance and single-row perturbation explanations
- Runs on CPU only: no GPU setup needed
Installation
python -m pip install mlfox
Requires Python 3.11 or later (CI covers 3.11–3.13).
Optional extras:
python -m pip install "mlfox[rich]" # Rich progress bars and report formatting
python -m pip install "mlfox[excel]" # .xlsx / .xls input support
python -m pip install "mlfox[test]" # pytest
To install from a local checkout:
git clone https://github.com/vprojectx-ai-lab/mlfox.git
cd mlfox
python -m pip install -e .
XGBoost is a required dependency. Windows and Linux install
xgboost-cpu; macOS installsxgboostconfigured for CPU execution.
Quick start
The package itself is callable, so use import mlfox and then mlfox(...).
import mlfox
model = mlfox()
model.fit("customers.csv", target="Churn")
model.report()
target is the column you want to predict. To control the run, pass options:
model = mlfox(task="auto", cv=5, random_state=42)
model.fit("customers.csv", target="Churn")
model.report()
Examples
Classification
import pandas as pd
import mlfox
data = pd.read_csv("customers.csv")
X = data.drop(columns="Churn")
model = mlfox(task="binary_classification", cv=5, random_state=42)
model.fit(data, target="Churn")
predictions = model.predict(X)
print(predictions.head())
# Available when the selected classifier supports probabilities
probabilities = model.predict_proba(X)
print(probabilities.head())
For three or more classes, use task="multiclass_classification" when you know the target type.
Regression
import pandas as pd
import mlfox
data = pd.read_csv("sales.csv")
model = mlfox(task="regression", metric="rmse", cv=5, random_state=42)
model.fit(data, target="Sales")
predictions = model.predict(data.drop(columns="Sales"))
print(predictions.head())
More runnable scripts are in examples/.
How fit() works
- Load and profile: validates the input, profiles columns, and detects or checks the task.
- Split: divides the data into training and holdout partitions.
- Benchmark: cross-validates every eligible candidate model on the training partition.
- Preprocess per fold: column decisions, imputation, feature engineering, encoding/scaling, and feature selection are fit only on each fold's training rows.
- Select and evaluate: picks the best candidate by the primary CV metric, refits it on the full training partition, and evaluates it once on the holdout.
Classification uses stratified CV and defaults to balanced accuracy. Regression uses K-fold CV and defaults to RMSE. Configure the run with cv, metric, test_size, and random_state.
Models
| Classification | Regression |
|---|---|
| Logistic Regression | Linear Regression |
| Decision Tree | Ridge |
| Random Forest | ElasticNet |
| Extra Trees | Decision Tree Regressor |
| XGBoost | Random Forest Regressor |
| HistGradientBoosting (when eligible) | Extra Trees Regressor |
| Calibrated SVM (within size limits) | XGBoost Regressor |
| HistGradientBoosting Regressor (when eligible) |
Models run sequentially on CPU. Some candidates are skipped when a dataset exceeds their size or dimensionality limits. Any candidate failure (with the exception and fold) is recorded in the HTML report.
Metrics
| Task | Reported | Primary metric options |
|---|---|---|
| Classification | accuracy, balanced accuracy, weighted precision, weighted recall, weighted F1, ROC-AUC (when supported) | balanced_accuracy, accuracy, precision, recall, f1, roc_auc |
| Regression | R², MAE, RMSE | rmse, mae, r2 |
Benchmarks
Produced by the repository's benchmark runner using an external holdout. Fit time is the time spent in model.fit(). Runs used default five-fold CV and three seeds, except full Covertype, which used one.
| Dataset | Rows | Accuracy | Macro F1 | R² | RMSE | Mean fit time |
|---|---|---|---|---|---|---|
| Adult | 48,842 | 0.8732 | 0.8149 | — | — | 132.6 s |
| Credit-g | 1,000 | 0.7667 | 0.6995 | — | — | 8.5 s |
| Covertype (full) | 581,012 | 0.9582 | 0.9309 | — | — | 1,079.2 s |
| California Housing | 20,640 | — | — | 0.8291 | 0.4751 | 62.0 s |
| Diamonds | 53,940 | — | — | 0.9762 | 612.62 | 195.8 s |
These are example runs, not guarantees. Hardware, dependency versions, random splits, and dataset characteristics all affect results, and Credit-g varied more across seeds than the others. Because every candidate is cross-validated, expect training to take from seconds on small data to several minutes (or longer) on large data.
Bounded tuning
Tuning is optional and capped. It is not an open-ended search.
import mlfox
model = mlfox(
task="binary_classification",
tune=True,
max_tuning_trials=8,
cv=3,
random_state=42,
)
model.fit("customers.csv", target="Churn")
model.report()
Reports
| Method | Output |
|---|---|
model.report() |
Concise console summary: benchmark table, best model, holdout metrics |
model.html() |
Writes the full self-contained report to mlfox_report.html |
model.export_report("training_report.html") |
Full report to a path you choose |
model.export_report("training_report.json") |
Machine-readable JSON report |
The full HTML report covers the dataset, preprocessing, model comparison (including failures), holdout results, explainability, and runtime.
Saving and loading
import mlfox
model = mlfox().fit("training.csv", target="target")
model.save("model.joblib")
loaded = mlfox.load_model("model.joblib")
predictions = loaded.predict("new_rows.csv")
fit() returns the same model object, so calls can be chained.
-
predict()returns a one-dimensional pandas Series namedprediction, with the input index preserved:0 yes 1 no Name: prediction, dtype: object
-
predict_proba()returns a DataFrame of shape(n_rows, n_classes)when the selected classifier supports probabilities.
Security: Joblib uses pickle-based deserialization, which can execute code embedded in a file. Only load model files from sources you trust.
Explainability
importance = model.feature_importance(
data="labeled_evaluation.csv", target="target", n_repeats=10
)
explanation = model.explain_prediction(
data="one_customer.csv", background_data="reference_rows.csv"
)
- Permutation importance: global feature importance.
- Perturbation explanation: explains a single row against background data.
These describe model sensitivity, not causal effects. SHAP is not currently supported.
Task detection
With task="auto", MLFOX treats an integer-valued numeric target as multiclass when it has at least 3 distinct labels, at least 2 rows per label, and no more labels than min(100, max(20, int(2 * sqrt(n_valid_targets)))). Anything else numeric is treated as regression.
This is a heuristic. If integer values actually represent a continuous or count-like target, set task explicitly to binary_classification, multiclass_classification, or regression.
Limitations
- Tabular data only; free-form text is not vectorized automatically.
- Random/stratified splits only. Time-aware and group-aware holdout or CV are not supported.
- Duplicate rows are reported but not removed. Outliers are not clipped or removed.
- High-cardinality categorical features can use a lot of memory during one-hot encoding.
- No GPU training and no parallel model benchmarking.
Development
git clone https://github.com/vprojectx-ai-lab/mlfox.git
cd mlfox
python -m pip install -e ".[test,rich,excel]"
python -m compileall -q mlfox tests
python -m pytest -vv
python -m mlfox.test
See CHANGELOG.md for release notes.
License
Released under the MIT License.
Made by vprojectx
Metadata
Release files for mlfox 1.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mlfox-1.0.5.tar.gz | 45.4 kB | Without provenance | Details for mlfox-1.0.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mlfox-1.0.5-py3-none-any.whl | Python 3 | none | any | Details for mlfox-1.0.5-py3-none-any.whl |
Total release size: 92.3 kB
Release files / mlfox-1.0.5.tar.gz
| Download URL | mlfox-1.0.5.tar.gz |
|---|---|
| Size | 45.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9bd06e26330c2b5305f1d2b141e58962300a577300a2cc7318dba76f37b352db
|
|
BLAKE2b-256 checksum How to use checksums |
7b36f9542ec9d6dcb7df474e84dd6fe91442f7bb3db87d5ea24bc2c96a2d874b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / mlfox-1.0.5-py3-none-any.whl
| Download URL | mlfox-1.0.5-py3-none-any.whl |
|---|---|
| Size | 46.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92babf2abd456c56fd3fa9d25ebf32c2c170ffffd0aff43a750bba9fad739137
|
|
BLAKE2b-256 checksum How to use checksums |
b3864f4bfa57ffeadfba14f6bde1610517ef12663f300b981e44e709b9395a2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Security for mlfox 1.0.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.