# AutoML API: Train, Predict & Explain from CSV/Excel (`jumblemog/tabular-automl`) Actor

Predict any column of a CSV, Excel, Google Sheet or dataset: compares models by cross-validation, explains what drives the result and scores new rows. No code.

- **URL**: https://apify.com/jumblemog/tabular-automl.md
- **Developed by:** [Jumble Mog](https://apify.com/jumblemog) (community)
- **Categories:** AI, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## AutoML API: Train, Predict & Explain from CSV/Excel

**Predict any column of a table, without writing code.** Give a CSV, Excel file, Google Sheet, JSON rows or an Apify dataset and name the column to predict (price, churned, species, Survived ...). The Actor trains several machine learning models, compares them fairly by cross-validation, keeps the best, tells you **which columns drive the result and how**, and predicts new rows.

- **Classification or regression**, picked from the column: a class (yes/no, a category) or a number. You can force either.
- **Models compared on the same folds**: logistic or ridge regression, random forest and gradient boosting, against a baseline (always guessing the most common class or the average), so you see whether the data predicts anything at all.
- **Honest scores**: every row is scored by a model that never saw it (out-of-fold). R², RMSE, MAE and MAPE for numbers; ROC AUC, accuracy, balanced accuracy, macro F1 and log loss for classes; a confusion matrix.
- **Explanations**: each column's permutation importance on held-out rows, and its effect: the average prediction as the column moves across its range (bigger house → higher price; first class → better survival).
- **Predictions** for new rows you send, and for rows of the data with an empty target, with class probabilities or an 80% range, in the results and as a CSV file.
- **Data handled for you**: numbers with $, % or thousands separators, categories, dates (split into year, month, weekday), missing values; ID columns, constant columns, free text and links are left out and listed with the reason.

It's made for:

- AI agents and chatbots that need a real model behind a "what will happen" or "what drives this" question, instead of a guess. Language models can't fit models in their heads.
- Analysts and teams who want a quick, well-validated baseline model for churn, lead scoring, pricing, demand or risk, with the drivers explained.
- No-code pipelines (Zapier, Make, n8n) and scrapers that score new records as they arrive.

![The chart made by this Actor for the Titanic passenger list: gradient boosting predicts survival with ROC AUC 0.86 against 0.50 for guessing; sex matters most, then class, age and fare; the confusion matrix of out-of-fold predictions; women's average chance of survival 64% against 19% for men](https://api.apify.com/v2/key-value-stores/Km5b4PG3kYHdZSb1E/records/tabular-automl-example.png?signature=Wte6MBpJGWsPOiFUjUTK)

### How to use it

1. Add **Requests**, one per table. The form has two examples: the Titanic passenger list (predict Survived and score two new passengers) and car fuel economy (predict mpg).
2. Optionally pick an **Apify dataset** to learn from (for requests without their own data), and the number of cross-validation **folds**.
3. Click **Start**. Each table is a row in the results, with the summary, scores, explanations, predictions, chart and report.

#### What you can send

A line of text: `predict price from https://example.com/houses.csv`. The link can point to a CSV, TSV, JSON or Excel (.xlsx) file, a Google Sheet shared with anyone who has the link, or a file on GitHub.

Or an object:

```json
{
  "data": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
  "target": "Survived",
  "predict": [
    {"Pclass": 1, "Sex": "female", "Age": 29, "SibSp": 0, "Parch": 0, "Fare": 80, "Embarked": "S"},
    {"Pclass": 3, "Sex": "male", "Age": 25, "SibSp": 0, "Parch": 0, "Fare": 7.9, "Embarked": "S"}
  ]
}
```

| Field | What it takes |
|---|---|
| `data` | A link, CSV or JSON text, or a list of rows. Leave it out to use the Apify dataset picked in the input. |
| `target` | The column to predict (any case; `ad spend` finds `ad_spend`). |
| `predict` | New rows to predict: a list of rows, CSV text or a link. Missing columns are treated as missing values. |
| `task` | `auto` (default), `classification` or `regression`. |
| `features` | Only these columns are used. |
| `exclude` | These columns are left out (for example one that is only known after the fact). |
| `models` | Some of `logistic`/`linear`, `random forest`, `gradient boosting` (all by default). |
| `folds` | Cross-validation folds, 2 to 10 (5 up to 5,000 rows, 3 above). |
| `positiveClass` | For two classes: the one whose chance is reported (by default 1, yes or true, else the rarer class). |
| `predictMissing` | Predict the data's rows with an empty target too (true by default). |
| `title` | A title for the result. |

### Examples

- Titanic passengers, predict `Survived` → gradient boosting, ROC AUC 0.86 and 82% accuracy against 62% for always guessing "died"; Sex 51% of the importance, then Pclass, Age and Fare. Name, Ticket, Cabin and PassengerId are left out as IDs and near-unique text. A 29-year-old woman in first class: survives (99%); a 25-year-old man in third: doesn't.
- Car fuel economy, `predict mpg` → gradient boosting, R² 0.88 and a typical error of 2.7 mpg (7.8 for guessing the average); weight and model year matter most; predicted mpg falls from 29 to 20 as weight goes from 1,900 to 4,500 lb.
- Palmer penguins, predict `species` → logistic regression, 99% accuracy across three species; bill length matters most.
- 54,000 diamonds, predict `price` → gradient boosting, R² 0.98; carat and size matter most (models compared on 20,000 rows, the best one then trained on all 54,000).

### How-to examples

These are the two examples in the input form; the results are from runs of the Actor.

#### How to predict a column of a CSV file without code

```json
{"requests": [{"data": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv", "target": "Survived",
               "predict": [{"Pclass": 1, "Sex": "female", "Age": 29, "SibSp": 0, "Parch": 0, "Fare": 80, "Embarked": "S"},
                           {"Pclass": 3, "Sex": "male", "Age": 25, "SibSp": 0, "Parch": 0, "Fare": 7.9, "Embarked": "S"}]}]}
```

Result: gradient boosting wins, with ROC AUC 0.86 and 82% accuracy against 62% for always guessing "died". The 29-year-old woman in first class survives (99%) and the 25-year-old man in third class doesn't. Name, Ticket, Cabin and PassengerId are left out by themselves as IDs and near-unique text.

#### How to train a regression model in one line

```json
{"requests": ["predict mpg from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/mpg.csv"]}
```

Result: gradient boosting, R² 0.88 and a typical error of 2.7 mpg (against 7.8 for guessing the average). Weight and model year matter most, and predicted mpg falls from 29 to 20 as weight goes from 1,900 to 4,500 lb.

#### How to find what drives churn, sales or prices

Send your table with the column to explain as `target`, such as `{"data": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit", "target": "churned"}`. The result lists each column's share of the `importance` and its `effects`: how the prediction rises or falls as that column changes. Rows with an empty target are predicted too, so a list of current customers comes back scored.

#### How to let an AI agent make predictions from data

Add this Actor to the [Apify MCP server](https://mcp.apify.com) with `https://mcp.apify.com/?tools=jumblemog/tabular-automl`. The agent names the table and the column, and passes on the `summary`, the cross-validated scores and the predictions, instead of guessing from a few rows it read.

### FAQ

**Which models does it try?** Logistic or linear regression, random forest and gradient boosting from scikit-learn, compared with cross-validation. The best one is trained on all the data.

**Do I need to clean the data first?** No. Column types are found, IDs and near-unique text are dropped, and missing values, categories and dates are handled.

**How do I know the model is any good?** Every result has cross-validated scores and compares them with a simple baseline, such as always guessing the most common answer or the average.

**Does importance mean cause?** No. Importance and effects say what the model uses to predict, not what causes the outcome.

**Does it work with Zapier, Make or n8n?** Yes. Call the Actor with its Apify app or an HTTP request, and send the predictions on.

### Output

One dataset item per table, also saved together in the run's `OUTPUT` record:

```json
{
  "request": 1, "status": "ok", "type": "classification", "title": "Predict Survived",
  "summary": "Gradient boosting predicts Survived best: ROC AUC 0.86 and accuracy 82% (always guessing 0: 62%), in 5-fold cross-validation on 891 rows. Most important: Sex (51%), Pclass (17%), Age (14%). Predicted 2 rows: 1 (99%); 0 (100%).",
  "best": {"model": "gradient boosting", "metric": "rocAuc", "metricName": "ROC AUC", "value": 0.8597, "baseline": 0.4975, "cvFolds": 5},
  "models": [{"model": "gradient boosting", "rocAuc": 0.8597, "accuracy": 0.8171, "balancedAccuracy": 0.7997, "f1Macro": 0.8038, "logLoss": 0.4819, "best": true}, "..."],
  "importance": [{"feature": "Sex", "kind": "category", "importance": 0.1836, "sharePct": 51.2}, "..."],
  "effects": [{"feature": "Pclass", "kind": "number", "trend": "falls", "points": [{"value": 1, "prediction": 0.488}, {"value": 2, "prediction": 0.423}, {"value": 3, "prediction": 0.270}]}, "..."],
  "confusion": {"labels": ["0", "1"], "matrix": [[480, 69], [94, 248]], "rowsAreActual": true},
  "predictions": [{"row": 1, "source": "predict", "prediction": "1", "probability": 0.9931, "probabilities": {"0": 0.0069, "1": 0.9931}, "input": {"Pclass": 1, "Sex": "female", "...": "..."}}, "..."],
  "data": {"rows": 891, "labeledRows": 891, "features": [{"name": "Age", "kind": "number", "missingPct": 19.9}, "..."], "dropped": [{"column": "Name", "reason": "an ID (different in every row)"}, "..."]}
}
```

Regression items carry `low` and `high` (an 80% range) with each prediction and `rmse`, `r2`, `mae` and `mapePct` per model. Every item has `target` (the classes with counts, or the column's spread), `warnings` (weak or suspiciously perfect results, small data, columns missing from the rows to predict), `notes`, links to the chart (`imageUrl`, `svgUrl`), the predictions CSV (`predictionsUrl`) and the Markdown report. A table that can't be modeled has `"status": "failed"` and the reason in `error`, and isn't billed.

### How it works

1. **Reading the columns**: numbers (including "$1,200", "45%", "1.2k"), dates, and categories (the 30 most common values, the rest grouped); missing values are filled with the median or a "(missing)" category, with a flag for numbers. IDs, row numbers, constant columns, near-unique text and links are left out.
2. **Comparing models**: [scikit-learn](https://scikit-learn.org) pipelines (preprocessing inside each fold, so nothing leaks) are scored with k-fold cross-validation, stratified for classes. The best model is picked by ROC AUC (two classes), macro F1 (more) or RMSE (numbers), then trained on all labeled rows.
3. **Explaining**: permutation importance on each fold's held-out rows; effects by setting one column to each of several values for a sample of rows and averaging the predictions.
4. **Predicting**: the final model scores the new rows; a number's 80% range comes from the model's cross-validated errors.

### Pricing

You pay one price per table modeled, at the price shown on this page, however many rows you predict. The chart, report and predictions file are included. Requests that fail are never charged. If you set a maximum cost per run, the Actor stops before a table that wouldn't fit.

### Speed

A table of a few hundred rows takes a few seconds of work and 50,000 rows about half a minute. A run through the API answers in about 15 seconds for a small table, including the cloud container starting.

### Tips and limits

- **Garbage in, garbage out**: a model only finds patterns that are in the columns. The baseline's score next to the best one shows how much the data really tells. A near-perfect score from one column usually means it leaks the answer (it's filled in after the fact); the Actor warns about it.
- **Causes**: importance and effects describe what the model uses, not cause and effect.
- **No time series**: rows are shuffled into folds, so for forecasting a series over time use a forecasting tool instead.
- **Models aren't stored**: send the rows to predict with the data; training again takes seconds and gives the same model.
- **Limits**: 20 tables per run; 500,000 rows (200,000 used for the final model, 20,000 for comparing models); 200 columns; 50 classes.

### For AI agents and developers

This Actor works with the [Apify MCP server](https://mcp.apify.com), so AI agents can call it as a tool. Send `requests` with `data`, `target` and `predict`, and read `summary`, `best`, `importance`, `effects`, `predictions` and `warnings`. A direct API call that waits for the answer:

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~tabular-automl/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"requests": ["predict mpg from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/mpg.csv"]}'
```

`run-sync` instead returns the run's `OUTPUT`: the status, the counts and every result as JSON.

In Python, with the `apify-client` package, scoring new leads with a model trained on past ones:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("jumblemog/tabular-automl").call(run_input={
    "requests": [{"data": "https://example.com/past-leads.csv", "target": "converted",
                  "predict": "https://example.com/new-leads.csv", "exclude": ["sales_rep_notes"]}],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["summary"], item["predictionsUrl"])
```

### Credits

- Models and metrics: [scikit-learn](https://scikit-learn.org) (BSD-3-Clause), with [pandas](https://pandas.pydata.org) and [NumPy](https://numpy.org).
- Charts: [Vega-Lite](https://vega.github.io/vega-lite/) and [vl-convert](https://github.com/vega/vl-convert) (BSD-3-Clause), with the [Inter](https://rsms.me/inter/) font (SIL Open Font License).
- Example data: the Titanic passenger list (Data Science Dojo's copy) and the Auto MPG data from the UCI Machine Learning Repository (seaborn-data copy).

# Actor input Schema

## `requests` (type: `array`):

One table and one column to predict per entry, as a line ('predict price from https://.../houses.csv') or an object: {"data": a link to a CSV, TSV, JSON or Excel file or a Google Sheet, CSV text, or a list of rows; "target": the column to predict; "predict": new rows to score (a list of rows, CSV text or a link)}. Rows of the data with an empty target are predicted too. Optional: task (auto, classification or regression), features (the columns to use), exclude (columns to leave out), models (logistic or linear, random forest, gradient boosting), folds (2-10), positiveClass, predictMissing (true), title. Leave data out to use the Apify dataset below.

## `datasetId` (type: `string`):

Learn from the items of a dataset in your account, such as a scraper's results, for requests without their own data. Up to 500,000 items; the tool gets read access to this dataset only.

## `folds` (type: `integer`):

When a request doesn't say: 5 up to 5,000 rows, 3 above.

## `charts` (type: `boolean`):

Models compared, what matters most, the confusion matrix or predicted against actual, and the strongest column's effect.

## Actor input object example

```json
{
  "requests": [
    {
      "data": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
      "target": "Survived",
      "predict": [
        {
          "Pclass": 1,
          "Sex": "female",
          "Age": 29,
          "SibSp": 0,
          "Parch": 0,
          "Fare": 80,
          "Embarked": "S"
        },
        {
          "Pclass": 3,
          "Sex": "male",
          "Age": 25,
          "SibSp": 0,
          "Parch": 0,
          "Fare": 7.9,
          "Embarked": "S"
        }
      ]
    },
    "predict mpg from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/mpg.csv"
  ],
  "charts": true
}
```

# Actor output Schema

## `results` (type: `string`):

One row per table: the chart and the summary.

## `output` (type: `string`):

The OUTPUT record: every result in one JSON object.

## `files` (type: `string`):

Charts (PNG and SVG), predictions (CSV) and Markdown reports in the run's key-value store.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "requests": [
        {
            "data": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
            "target": "Survived",
            "predict": [
                {
                    "Pclass": 1,
                    "Sex": "female",
                    "Age": 29,
                    "SibSp": 0,
                    "Parch": 0,
                    "Fare": 80,
                    "Embarked": "S"
                },
                {
                    "Pclass": 3,
                    "Sex": "male",
                    "Age": 25,
                    "SibSp": 0,
                    "Parch": 0,
                    "Fare": 7.9,
                    "Embarked": "S"
                }
            ]
        },
        "predict mpg from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/mpg.csv"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jumblemog/tabular-automl").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "requests": [
        {
            "data": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
            "target": "Survived",
            "predict": [
                {
                    "Pclass": 1,
                    "Sex": "female",
                    "Age": 29,
                    "SibSp": 0,
                    "Parch": 0,
                    "Fare": 80,
                    "Embarked": "S",
                },
                {
                    "Pclass": 3,
                    "Sex": "male",
                    "Age": 25,
                    "SibSp": 0,
                    "Parch": 0,
                    "Fare": 7.9,
                    "Embarked": "S",
                },
            ],
        },
        "predict mpg from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/mpg.csv",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("jumblemog/tabular-automl").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "requests": [
    {
      "data": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv",
      "target": "Survived",
      "predict": [
        {
          "Pclass": 1,
          "Sex": "female",
          "Age": 29,
          "SibSp": 0,
          "Parch": 0,
          "Fare": 80,
          "Embarked": "S"
        },
        {
          "Pclass": 3,
          "Sex": "male",
          "Age": 25,
          "SibSp": 0,
          "Parch": 0,
          "Fare": 7.9,
          "Embarked": "S"
        }
      ]
    },
    "predict mpg from https://raw.githubusercontent.com/mwaskom/seaborn-data/master/mpg.csv"
  ]
}' |
apify call jumblemog/tabular-automl --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jumblemog/tabular-automl"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/lsnZe3p1HEmhgvaEK/builds/vErjJEA6EqKHsuQdz/openapi.json
