# Welt by Ergodic > Welt is a collection of the strongest AI models for tables, run behind one API: prediction, forecasting and causal discovery on your own data, with nothing to train. ergodic, Ergodic's open-source Python package, adds domain knowledge, tests causal hypotheses and estimates what each action would change, on your machine. - Welt for agents: hosted MCP server at https://welt.ergodic.dev/mcp (OAuth or API key); product docs for agents at https://welt.ergodic.dev/llms.txt; MCP discovery at https://ergodic.dev/.well-known/mcp.json - Python: `pip install welt-client` (Classifier, Regressor, Forecast, CausalDiscovery, Client.evaluate); docs at https://ergodic-ai.github.io/welt-python/ - ergodic: `pip install ergodic` (Apache 2.0), or `pip install "ergodic[welt]"` to call Welt from it; docs at https://docs.ergodic.dev/ - Welt does not estimate causal effects; ergodic does, locally. - Every Library page below is Markdown. All of them in one file: https://ergodic.dev/llms-full.txt --- # Welt: A Collection of Groundbreaking Models Page: https://ergodic.dev/library/articles/welt-a-collection-of-groundbreaking-models Welt is a collection of the strongest AI models built for tables, from labs including Inria, Amazon, Kumo and Mistral AI. Give one your spreadsheet, ask a question, and get an answer in minutes: which customers are likely to leave, what next month's sales look like, what's really driving your costs. You can ask in plain English through your AI assistant or use a few lines of Python, and there's nothing to train. ## Better predictions, without the model shopping Most of the useful data in the world lives in tables. Sales by week. Patients by visit. Votes by county. And most predictions from those tables are still built the slow way: clean the data, pick an algorithm, tune it for a week, and hope it holds next quarter. Think about how a good estate agent prices a house. They don't build a pricing model for your street first. They've seen thousands of houses, so they look at yours, compare it with a few recent sales nearby, and give you a number in a minute. The models in Welt work the same way. They're called foundation models, and each one has already learned from millions of tables, so it reads your rows as examples on the spot and predicts straight away. Nothing is trained on your data and there's nothing to tune. The catch is choice. There are a dozen of these models, every lab claims first place, and two of the biggest labs were bought this year: SAP bought Prior Labs and NVIDIA bought Kumo. Picking one means betting on one. Welt takes the bet away: you run all of them on your own table and see which ranks first on it. We don't train these models, so we've no reason to favour one. A model only joins the collection once it runs reliably on Welt, and if your table doesn't fit a model, Welt tells you before it charges you anything. ## Five questions Welt answers | You ask | Welt does | |---|---| | Will this customer leave? | Answers yes or no for every row, with how likely it is | | What will this house sell for? | Predicts a number, like a price, a delivery time or a yield | | Which model should I trust on my data? | Tests every model on your table and ranks them, fairly, on rows they haven't seen | | What will sales be over the next two weeks? | Forecasts ahead, with a likely range around each day | | What's driving the result? | Maps cause and effect between your columns, so you know which lever to pull | Each one is a single request, from Python or from Claude, ChatGPT, Cursor or Codex. [How Welt Works](https://ergodic.dev/library/articles/how-welt-works) walks through all five with a tiny example. ## The collection | Models | What they're for | |---|---| | TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 | Predict a category or a number from a table | | Chronos-2, Timestral | Forecast what comes next in a time series | | Arrow, CDFM, AVICI | Find what causes what | | Welt, TabPFN 3.5 Fast, Causilo, EXAONE Tabular | Coming next: more prediction models | Timestral weights: 2026 - Mistral AI, Modified MIT licence. ## What's next First in line is Welt's own prediction model. Welt's Causal Model follows once it can handle larger tables, and after that comes a reliable confidence range on every prediction, so you know how far to trust each answer. --- # How Welt Works Page: https://ergodic.dev/library/articles/how-welt-works You've got a table, and some cells are blank because they haven't happened yet. Welt fills them in, tells you how sure it is, and shows you which of its models does best on your own data. Pick a way in, then try the five steps below. ## Pick a way in There are three ways to use Welt, and they all run the same models. - Ask your AI assistant. Add Welt to Claude, ChatGPT or another assistant and ask in plain English, with no code at all. - Open a ready notebook. Run the examples in Google Colab, in your browser, with nothing to install. - Use Python on your own computer. Install Welt and sign in once. ``` pip install "welt-client[parquet]" welt login ``` `welt login` opens your browser so you can approve access to your workspace. You never copy or paste a key. ## 1. Ask a yes-or-no question Give Welt the rows where you already know the answer. It reads them, then answers for the rows where you don't. Nothing is trained on your side. | Months a customer | Support tickets | Plan | Churned? | |---|---|---|---| | 26 | 1 | Annual | No | | 3 | 7 | Monthly | Yes | | 14 | 2 | Monthly | No | | 2 | 5 | Monthly | ? | Example rows. Welt fills in the highlighted cell. ``` from welt import Classifier model = Classifier(model="tabicl-v2") model.fit(known_rows, target="churned") # show it the rows you know model.predict(new_rows) # yes or no model.predict_proba(new_rows) # and how likely ``` ## 2. Predict a number Same idea, but the blank is a number: a price, a delivery time, a yield. Swap `Classifier` for `Regressor` and nothing else changes. | Bedrooms | Floor area m² | To station km | Price £k | |---|---|---|---| | 2 | 68 | 0.4 | 412 | | 3 | 91 | 1.8 | 455 | | 4 | 120 | 3.2 | 520 | | 3 | 84 | 0.9 | ? | Example rows, made up for illustration. ``` from welt import Regressor model = Regressor(model="tabicl-v2") model.fit(known_rows, target="price") model.predict(new_rows) ``` ## 3. Rank the models on your table Welt has four models for steps 1 and 2, and which one ranks first depends on your table. So test them all on it. Welt hides part of your rows from every model, scores each one on what it couldn't see, and ranks them against a simple guess. Like a blind tasting. Every model gets the same glasses, nobody sees the label, and a tie is called a tie. | Rank | Model | Score on hidden rows | |---|---|---| | 1 | Model A | 0.91 | | 2 | Model B | 0.90, tied with A | | 3 | Model C | 0.86 | | | Baseline guess | 0.50 | Example leaderboard layout. Your numbers come from your table. ``` from welt import Client with Client() as client: result = client.evaluate(table, "churned", task="classification") print(result.summary()) # the leaderboard model = result.fit() # the top-ranked model ``` ## 4. Look ahead When your rows are dates, the blank is the future. Hand Welt the history and ask for the next 14 days. You get a middle estimate and a range around it. If you already know something about the future, like a bank holiday, add it as a column and the forecast uses it. | Date | Store | Sales | |---|---|---| | 12 Oct | North | 118 | | 13 Oct | North | 124 | | 14 Oct | North | 157 | | 15 to 28 Oct | North | ? | Example rows, made up for illustration. ``` from welt import Forecast model = Forecast(model="chronos-2").fit( history, time="date", id="store", target=["sales"]) model.forecast(14).to_frame() ``` ## 5. Ask why Prediction tells you what's likely. Sometimes you need to know what drives what, so you can change it. Welt looks at how your columns move together and proposes a map of cause and effect. Treat the map as a strong starting point rather than proof, then take it into ergodic, our open-source package, to measure how much one thing changes another. Example map. Arrows point from cause to effect. ``` job = client.submit_discover(dataset["id"], model="arrow") graph = job.result().to_ergodic() # pip install "ergodic[welt]" to measure effects ``` ## Good to know Each model has a largest table it can read. Wider tables take fewer rows, up to 8,000 rows at 20 columns for the biggest. If your table doesn't fit, Welt says why before anything runs. The likelihoods and forecast ranges come straight from the model: a useful guide, but not yet a guaranteed range. Running models uses workspace credits, which you can check under Workspace, then Billing. --- # Get Started with Welt Page: https://ergodic.dev/library/articles/get-started-with-welt Welt runs a collection of AI models on your own tables. This guide takes you from nothing to your first prediction in a few minutes, with or without code. ## No code? Start from your assistant You can use Welt without writing any Python. Add Welt to Claude, ChatGPT or another AI assistant, sign in once, and ask it in plain English to run the models for you. All it needs is this web address: ``` https://welt.ergodic.dev/mcp ``` In Claude, go to Customize → Connectors → Add custom connector. In ChatGPT, go to chatgpt.com/plugins → Add custom MCP server. You approve access in your browser, so no password or key ever goes into the chat. ## Set up Python in two steps ### 1. Install ``` pip install "welt-client[parquet]" ``` Using uv? Run `uv pip install "welt-client[parquet]"` instead. ### 2. Sign in From a terminal: ``` welt login ``` Your browser opens and asks you to approve access to your workspace. Welt saves that access privately on this computer, so any Python you run here afterwards is already signed in. From a notebook, including one running on another machine: ``` from welt import Client Client().connect() ``` Open the link it prints on your own computer and approve there. Access lasts until this Python session ends. Use `Client().connect(save=True)` to keep it. Rather use an API key? Create one with read and write access under Workspace → API keys at [welt.ergodic.dev](https://welt.ergodic.dev), then load it without writing it into your code: ``` import os from getpass import getpass os.environ["WELT_API_KEY"] = getpass("Welt API key: ") ``` ## Make your first prediction Try it on Iris, a classic practice table: 150 flowers, four measurements each, and a column called `target` that says which of three species each flower is. You'll show Welt 120 flowers and ask it to name the other 30. Running models uses workspace credits, so check yours under Workspace → Billing at [welt.ergodic.dev](https://welt.ergodic.dev) first. ``` from welt import Client data = Client().load_research_dataset( "asset-d839644b6de36fc5cafdda18c5daeca3" ) target = "target" data.head() ``` | Row | sepal-length | sepal-width | petal-length | petal-width | target | |---|---|---|---|---|---| | 0 | 4.6 | 3.6 | 1.0 | 0.2 | 0 | | 1 | 4.3 | 3.0 | 1.1 | 0.1 | 0 | | 2 | 5.0 | 3.2 | 1.2 | 0.2 | 0 | | 3 | 5.8 | 4.0 | 1.2 | 0.2 | 0 | | 4 | 4.4 | 3.0 | 1.3 | 0.2 | 0 | The first five rows. The target column holds the species, numbered 0 to 2. ``` from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report from welt import Classifier # hold back 30 flowers so you can check the answers train, test = train_test_split( data, test_size=0.2, random_state=9, stratify=data[target] ) X_train, y_train = train.drop(columns=target), train[target] X_test, y_test = test.drop(columns=target), test[target] model = Classifier(model="tabicl-v2", random_state=9) model.fit(X_train, y_train) # show it the 120 flowers you know predictions = model.predict(X_test) # ask about the 30 it hasn't seen print("accuracy:", accuracy_score(y_test, predictions)) print(classification_report(y_test, predictions, zero_division=0)) ``` ``` precision recall f1-score support 0 1.00 1.00 1.00 10 1 1.00 1.00 1.00 10 2 1.00 1.00 1.00 10 accuracy 1.00 30 macro avg 1.00 1.00 1.00 30 weighted avg 1.00 1.00 1.00 30 ``` That's from an earlier run with TabICLv2, which named all 30 held-back flowers correctly. Treat it as one result, not a promise. Nothing was trained on your computer: `fit` sent the 120 known rows to Welt and the prediction ran on Welt's servers. To use your own table, load your data instead and set `target` to the name of the column you want to predict. ## What do you want to do next? - [Predict with your own table](https://ergodic.dev/library/articles/guide-predict-with-your-own-table): load a CSV, Parquet file or DataFrame and name the column to predict. - [Predict a number](https://ergodic.dev/library/articles/guide-predict-a-number): a price, a delivery time or any other amount. - [Compare models](https://ergodic.dev/library/articles/guide-compare-models-with-cross-validation): test every model on your table and see how they rank. - [Find what drives what](https://ergodic.dev/library/articles/guide-causal-discovery): map cause and effect between the columns of your table. - [Find practice data](https://ergodic.dev/library/articles/guide-research-datasets): search and load real research tables. - [Reuse a predictor](https://ergodic.dev/library/articles/guide-reuse-a-fitted-predictor): predict again later without starting over. ## Which models you can use | Model | What it does | Largest table it reads (rows × columns) | |---|---|---| | TabICLv2 `tabicl-v2` | Predicts a category or a number | 8,000 × 20, 4,000 × 40, 2,000 × 80 | | Kumo Tabular Medium `kumo-medium` | Predicts a category or a number | 8,000 × 20, 4,000 × 40, 2,000 × 80 | | Mitra-v2 `mitra-v2` | Predicts a category or a number | 4,000 × 20, 2,000 × 40, 500 × 80 | | TabDPT 1.3 `tabdpt-1.3` | Predicts a category or a number | 500 × 20 | | Arrow `arrow` | Finds cause and effect | 8,000 × 20, 4,000 × 40, 2,000 × 80 | | CDFM `cdfm` | Finds cause and effect | 8,000 × 20, 4,000 × 40, 2,000 × 80 | | AVICI `avici` | Finds cause and effect | 1,000 × 20, 500 × 40 | Snapshot from 17 October 2026. Wider tables take fewer rows. Your table fits a model when its rows and columns both fit one of the listed shapes. For prediction, the column you're predicting doesn't count. Each call predicts up to 100 rows and up to 10 categories, and batch prediction handles more rows. If your table doesn't fit, Welt says so before anything runs. For live limits, run `Client().models()`. Forecasting with Chronos-2 and Timestral has its own [guide in the Python docs](https://ergodic-ai.github.io/welt-python/forecasting.html). ## Good to know If Python finds more than one way to sign in, it uses the first of these: an `api_key` you pass directly, then `WELT_API_KEY`, then a `connect()` from this Python session, then access saved by `welt login`. Saved access lives in `~/.config/welt` and only you can read it. On Windows, saved access isn't supported yet, so use `connect()` or `WELT_API_KEY`. Keep keys out of notebook cells, Git, logs and screenshots. The short code shown when you sign in is safe to compare with the one in your browser, but never share an API key. You can revoke access at any time under Workspace → API keys. No browser on the machine you're working on? Run `welt login --no-browser`, or `connect(open_browser=False)` in Python, and open the printed link on another device. To work in a specific workspace, name it when you connect: ``` from welt import Client client = Client().connect(workspace="acme-research") ``` --- # Connect Welt to Claude, ChatGPT and Your AI Assistant Page: https://ergodic.dev/library/articles/connect-welt-to-your-ai-assistant Once Welt is connected, you can ask your assistant things like "which of my customers are likely to leave?" and it runs Welt's models on your data for you. There's nothing to install. You add one web address to your assistant and sign in once. ``` https://welt.ergodic.dev/mcp ``` That address is Welt's MCP server. MCP is the standard way AI assistants plug into other tools, and it's switched on for every Welt workspace. You sign in with your Welt account through your browser, so you never paste a key into a chat. ## Claude on the web and Claude Desktop Custom connectors work on Claude's Free plan (one custom connector), Pro, Max, Team and Enterprise. A connector you add to your Claude account works in claude.ai and in Claude Desktop. 1. Open Customize → Connectors, click + Add, then Add custom connector. 2. Enter the name Welt and the URL `https://welt.ergodic.dev/mcp`, then click Continue. 3. Review the detected authentication settings and click Continue. 4. Under Authentication, choose Sign in now or Sign in when needed. Leave the OAuth client at its default and leave Request headers empty. 5. Click Add, then approve the Welt consent screen. In a chat, click + at the lower left, choose Connectors and switch Welt on for that conversation. On Team and Enterprise, an owner adds the connector once under Organization settings → Connectors → Add, chooses Custom, then Web, and enters the same URL. Members then open Customize → Connectors and click Connect. Each person signs in to Welt and picks their own workspace, so don't put an API key in an organization connector's headers. ## ChatGPT 1. Go to [chatgpt.com/plugins](https://chatgpt.com/plugins), select +, then Add custom MCP server. 2. Enter a name and description, and under Connection enter `https://welt.ergodic.dev/mcp`. 3. Choose OAuth authentication, review the warning and select I understand and want to continue. 4. Select Create as a plugin, review the tools it finds and approve the Welt consent screen. ChatGPT asks you to approve each tool call that uploads data, runs a model or cancels a job, and you can let it remember that approval for the conversation. Check your ChatGPT plan Welt hasn't confirmed which ChatGPT plans offer custom MCP servers, or whether an admin has to turn on developer mode first. If your workspace shows a developer mode setting under Settings → Apps, the connector may need it. ## Claude Code ``` claude mcp add --transport http welt https://welt.ergodic.dev/mcp ``` Then run `/mcp` in Claude Code and follow the sign-in steps in your browser. From a shell, `claude mcp login welt` does the same. You can also install the Welt plugin: ``` claude plugin marketplace add https://welt.ergodic.dev/plugin/marketplace.json claude plugin install welt@welt ``` ## OpenAI Codex ``` codex mcp add welt --url https://welt.ergodic.dev/mcp codex mcp login welt ``` ## Cursor Put this in `~/.cursor/mcp.json` for all projects, or `.cursor/mcp.json` for one project. Cursor starts the Welt sign-in when it first connects. ``` { "mcpServers": { "welt": { "url": "https://welt.ergodic.dev/mcp" } } } ``` ## VS Code with GitHub Copilot Put this in `.mcp.json` at the root of your workspace, or run MCP: Add Server from the Command Palette. VS Code opens your browser to sign in the first time you use it. ``` { "mcpServers": { "welt": { "type": "http", "url": "https://welt.ergodic.dev/mcp" } } } ``` ## What you approve when you sign in The first time your assistant uses Welt, a browser window opens at welt.ergodic.dev. You sign in if you need to, and a consent screen shows what the app is asking for. - The app's name and the host Welt sends access to, such as claude.ai. Only approve a connection you started. - Read access to your workspace, which is always included. The assistant can list and inspect datasets, models, predictors, jobs and results. - Write access, which you can untick. It lets the assistant upload data, run models and cancel jobs, and it spends credits within your workspace's spending cap. - The one workspace this connection can use. - How long access lasts: 1, 7, 30, 90 or 365 days, with 30 as the default. Every connection you approve appears in the Welt console under Settings → API keys, marked Connected app. Disconnect there ends it straight away. To switch workspace or change read and write access, disconnect and connect again. ## Getting your data in A file you attach in claude.ai or ChatGPT stays inside that app, so Welt can't read it. Upload it in the Welt console instead: Datasets → Upload a dataset, choose the CSV or Parquet file, set the target column if there is one, then Upload dataset. Your assistant can then find it by name. Assistants that can run commands, like Claude Code, can also create a one-time upload link, import a file from a public https URL, or send a small table of up to about 1,000 rows directly. ## Prompts to try Once Welt is connected, paste one of these and swap in your own file and column names. Your assistant reads Welt's live limits before it runs anything, and asks before it uploads. ``` Using Welt, check which models can run on data/customers.csv with the target column "churned", and tell me which ones it refuses and why. ``` ``` Using Welt, evaluate every eligible model on data/customers.csv predicting "churned". Show me the leaderboard, say whether the top two are tied, and create a report link that expires in one day. ``` ``` Using Welt's chronos-2 model, forecast the next 14 days of "sales" in data/sales.csv for each store, and show the middle estimate with the range around it. ``` ``` Using Welt's arrow model, map what causes what in data/survey.csv. List each cause and effect it finds, then tell me which ones I should test before trusting. ``` --- # Predict with Your Own Table Page: https://ergodic.dev/library/articles/guide-predict-with-your-own-table Train a model on your own labelled table and check it on rows it hasn't seen. You choose the task and name the target column; Welt doesn't guess either. You'll need - A labelled training DataFrame and a separate query DataFrame, from data you're approved to use. - The six-step workflow from [Your first prediction](https://ergodic.dev/library/articles/get-started-with-welt). Choose classification (`Classifier`) for discrete labels, or regression (`Regressor`) for numeric points. ## Declare the target Pass the name of your label column to `fit`. `fit(train, target="churn")` removes the named target from the features before upload. Pass exactly one of `y` or `target`. The original sklearn form `fit(X, y)` is still supported, including cloning, Pipeline and cross-validation within checked bounds. ``` # First run Start's real Iris walkthrough to learn the full six-step workflow. # For your own approved DataFrame, choose its target explicitly: from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report from welt import Classifier print(data.head()) data.info() target = "churn" # Replace with your own recorded label column. print(data[target].value_counts()) train, test = train_test_split(data, test_size=0.2, random_state=9, stratify=data[target]) query = test.drop(columns=target) y_test = test[target] model = Classifier(model="tabicl-v2", random_state=9) model.fit(train, target=target) predictions = model.predict(query) print("Test accuracy:", accuracy_score(y_test, predictions)) print(classification_report(y_test, predictions, zero_division=0)) ``` This continuation expects your approved `data` DataFrame with a `churn` label. [Start's real research examples](https://ergodic.dev/library/articles/get-started-with-welt) are complete and need no local dataset. For numeric targets, use `Regressor` and regression metrics instead. Keep test answers out of training Hold back test answers before fitting. Don't fit preprocessing on the test rows. ## Match the schema - DataFrame columns must be unique strings. - Named query columns can arrive in a different order: they are safely aligned to the fitted names. Missing or extra features are rejected. - Arrays use positional features, so keep their order. - Feature cells can be scalar numeric, categorical or missing values. Infinite values and nested objects are rejected. - Targets can't be missing. Regression targets must be finite numeric values. `target=` needs a DataFrame. Read a CSV or Parquet file into one before you use it. Can I pass a CSV or Parquet file instead? Estimators accept CSV and Parquet paths with an explicit `y`, as a convenience in-memory read. Parquet needs the optional `parquet` extra. File reading is not resumable upload or arbitrary-size execution. ## Keep evaluation explicit Separate training and query rows yourself. Respect the task's [qualified limits](https://ergodic-ai.github.io/welt-python/capabilities.html): Welt does not silently sample your table. - During cross-validation, preprocessing belongs inside each training fold. - When you compare models, use the same held-out rows and metric. - Keep model selection separate from unbiased assessment. Running cross-validation in parallel processes? Process-based parallel CV workers reauthenticate through `WELT_API_KEY` or an explicitly saved origin credential. Process-only connections are not serialized, and an explicit constructor key is intentionally not serialized either. ## Inspect the result `predict` returns an array in query row order. Classification probabilities follow `classes_` order; regression returns mean points in the target's units. For operation and version provenance, call `model.predict_details(query)`. To inspect pinned fit metadata, call `model.metadata()`. Not calibrated uncertainty Native probabilities are not conformal coverage, and regression mean points are not calibrated intervals. A new fit creates a new immutable predictor. Reuse the existing one for later queries, or [reopen it later](https://ergodic.dev/library/articles/guide-reuse-a-fitted-predictor). Switching model, configuration or task requires a new fit; [model selection](https://ergodic-ai.github.io/welt-python/model-selection.html) explains the task profiles. ## Next steps - [Reuse a predictor](https://ergodic.dev/library/articles/guide-reuse-a-fitted-predictor) reopen a fitted predictor without another fit. - [Select a model](https://ergodic-ai.github.io/welt-python/model-selection.html) compare task profiles fairly. - [Models and limits](https://ergodic-ai.github.io/welt-python/capabilities.html) the qualified limits for each task. --- # Predict a Number Page: https://ergodic.dev/library/articles/guide-predict-a-number Classification predicts a label; regression predicts a numeric target. Here you fit a `Regressor` on real Yacht data and measure its errors on held-out rows. You'll need - The Yacht train and test tables from [the complete Yacht walkthrough](https://ergodic-ai.github.io/welt-python/start.html#regression-predict-a-number). It downloads the real research table, prints its rows and schema, and splits train and test rows. ## Fit and measure Fit a `Regressor`, predict the held-out rows, then calculate MAE, RMSE and R²: ``` # Continue after preparing the Yacht train/test tables in Start. from welt import Regressor from sklearn.metrics import mean_absolute_error, root_mean_squared_error, r2_score model = Regressor(model="tabicl-v2", random_state=9) model.fit(train, target=target) predictions = model.predict(query) print("Test MAE:", mean_absolute_error(y_test, predictions)) print("Test RMSE:", root_mean_squared_error(y_test, predictions)) print("Test R²:", r2_score(y_test, predictions)) ``` - MAE and RMSE use the recorded target's units; smaller is better. - R² can be negative. Compare actual and predicted rows to understand the misses. Your measurements, not a benchmark These are held-out measurements, not a publisher benchmark or a guarantee. If you tune, use a separate validation split. ## What a regressor returns `predict` returns finite mean points in the target's units. It does not return class probabilities, calibrated intervals or conformal coverage. A task-specific available regression profile is required; there is no task or model fallback. Predictors keep their original task, version and configuration. ## Next steps - [Notebook examples](https://ergodic-ai.github.io/welt-python/notebooks.html) the full regression recipe in a notebook. - [Reuse a predictor](https://ergodic.dev/library/articles/guide-reuse-a-fitted-predictor) reopen a fitted predictor without another fit. - [Use your own table](https://ergodic.dev/library/articles/guide-predict-with-your-own-table) run the same workflow on your data. --- # Compare Models with Cross-Validation Page: https://ergodic.dev/library/articles/guide-compare-models-with-cross-validation An evaluation cross-validates one or more models on your table and ranks them. You get a leaderboard, per-fold metrics, out-of-fold predictions and an HTML report you can display in a notebook or share with a link. You'll need - `welt-client>=0.12.0`. - A workspace key with write permission, and credits for the evaluation. - A table with a target column, within the limits of the models you compare. ## Run an evaluation Pass a DataFrame and its target column. Welt uploads the table, assigns folds, evaluates every eligible model and returns when the results are ready. ``` import pandas as pd from welt import Client data = pd.read_csv("churn.csv") with Client() as client: evaluation = client.evaluate(data, "churned", task="classification", seed=7) print(evaluation.summary()) # leaderboard: one row per model, then the baseline folds = evaluation.folds() # long table: model_id, fold, rows, metric, value oof = evaluation.predictions() evaluation.show() # in Jupyter, displays the report ``` The first argument can also be an existing dataset ID (`"ds_…"`, which already names its target), a CSV or Parquet path, or a feature array with separate target values: `client.evaluate(X, y, task="regression")`. A string ending in `.csv`, `.parquet` or `.pq` is read as a file; any other string is a dataset ID. `evaluate` waits up to `timeout` seconds (600 by default). The evaluation keeps running if the wait stops; see [Wait, reconnect and cancel](https://ergodic-ai.github.io/welt-python/evaluations.html#wait-reconnect-and-cancel). ## What each model sees Welt assigns every row to one fold, once, from your `seed`. Every model is scored on the same folds; `to_dict()["fold_sha256"]` identifies them. For each fold, the model gets only the other folds as its context and predicts the held-out rows. A row is never predicted by a model that has seen it. Fold contexts are discarded; they are never saved as predictors. The boundary covers Welt's folds, not your preparation Anything you compute across the whole table before uploading, such as target encodings, scaling or features built from future rows, already contains the held-out answers. Prepare rows independently, or the scores will be optimistic. An ID column that tracks the target leaks the same way; drop it first. ## Choose models, or let Welt choose Name up to 8 models with `models=["tabicl-v2", "tabdpt-1.3"]`. Each one must be able to evaluate your table, otherwise the request is refused with that model's reason and nothing runs. Leave `models` empty and Welt evaluates every available catalogue model for the task whose limits admit your data. Hidden research models are never evaluated in this version. The others are listed with a reason in `evaluation.skipped`: ``` for model in evaluation.skipped: print(model["model_id"], model["reason"], model["message"]) ``` If no model can evaluate the table, submission raises `InvalidInputError` with `code="no_eligible_models"`; `error.details["skipped"]` explains each model. ## Choose a split `folds` sets the number of folds, from 2 to 10 (default 5). The `split` options are: | `split` | Folds | |---|---| | `"auto"` (default) | Stratified for classification, shuffled k-fold for regression. | | `"kfold"` | Shuffled k-fold. | | `"stratified"` | Keeps class shares in every fold. Classification only. | | `"group"` | With `group_column`: all rows of a group stay in one fold. | | `"custom"` | With `fold_column`: each distinct value is one fold. `folds`, if given, must equal their count. | Group and fold columns are removed from the features. The same seed and data give the same folds. For classification, every class must appear in every training fold; otherwise the request is refused before anything runs. Time-ordered splits are not available in this version. ## Read the results `summary()` makes no request. Its index is `model_id`, ranked models first, then the baseline: - `name` and `rank` (the baseline has no rank); - `_mean` and `_sd` across folds, for every metric of the task. Classification reports `roc_auc`, `log_loss`, `brier`, `accuracy`, `balanced_accuracy`, `f1_macro` and `ece`. Regression reports `rmse`, `mae`, `r2`, `mape` (only when no target is zero) and `median_ae`. Undefined values are `NaN`. Models are ranked by `primary_metric`: ROC AUC for binary classification, log loss for multiclass and RMSE for regression, unless you choose another. For binary tasks, `positive_class` sets the class used by ROC, precision to recall and calibration; the default is the second class in sorted order. - The baseline predicts the training-fold class shares or mean. It is a reference point, not a catalogue model. - `evaluation.comparison` compares the top two models fold by fold. `separated: False` means they are tied within fold-to-fold variation. - `evaluation.warnings` notes small datasets, class imbalance, skipped models and models that don't beat the baseline. `predictions()` returns one row per evaluated row: - `row_index` is the row's position in the uploaded table, then `fold` and `actual`; - one column per model (and `baseline`) with its out-of-fold prediction; - for classification, `:p()` probability columns. If labels of different types print alike (for example `1` and `"1"`), these columns use `repr()`: `p(1)` and `p('1')`. Predictions expire after seven days After seven days `predictions()` raises `ResultExpiredError`. The summary, fold metrics and report stay until you delete the evaluation. ## Display the report in a notebook `evaluation.show()` displays the report in Jupyter. An evaluation that is the last expression of a cell also displays it while its client is open. The report appears in a sandboxed frame: it can't run code, load anything or restyle your notebook. Scroll inside the frame to read all of it. An unfinished evaluation shows its status instead. `report_html()` returns the report as one self-contained HTML document. It contains no script and loads nothing. Save it as UTF-8: ``` from pathlib import Path Path("report.html").write_text(evaluation.report_html(), encoding="utf-8") ``` ## Share the report with a link ``` link = evaluation.report_link(days=7) print(link.url, link.expires_at) # the URL is shown once; store it safely ``` Anyone with the link can read the report The link opens the report without signing in, so share it like a password. It never opens the predictions, folds or other API data. The report itself includes the leaderboard, fold metrics and charts; for regression, the charts plot the actual and predicted values of up to 1,500 rows, which a reader can make out approximately. Unlike `predictions()`, the report is kept until you delete the evaluation. A link lasts the chosen 1 to 7 days (default 7). A link created from the SDK with an API key, or through an OAuth connection, never outlives that key and stops if the key is revoked. A link created in the console lasts the chosen days, even after an ordinary sign-out; "sign out everywhere", a password reset or account disablement revoke every link you created in the console. Every link stops working when it expires, when it is revoked, or when its creator is no longer a verified member of the workspace. Deleting the evaluation removes the report and its links. `report_links()` lists the evaluation's links without their URLs, and `revoke_report_link(link)` revokes one. Revoking needs a key with write permission; a read-only key can create links but not revoke them. Printing a `ReportLink` hides its URL, so it does not end up in saved notebook output by accident. ## Fit the model you chose ``` model = evaluation.fit() # the leaderboard's first model model = evaluation.fit("tabdpt-1.3") predictions = model.predict(new_rows) ``` `fit()` submits a new fit of that model on the full stored dataset, with the evaluation's seed, and returns a fitted `Classifier` or `Regressor`. It doesn't promote a fold context, and it is charged as a fit. The fit uses the model's current version. If the catalogue has moved on since the evaluation, `fit()` warns with an `EvaluationWarning` naming both versions; the evaluation's scores then describe the earlier version, so evaluate again to compare the current one. `model.model_version_` shows the fitted version. - If the evaluation used a `group_column` or `fold_column`, `fit()` refuses, because the stored dataset still contains that column. Fit an estimator on a table without it instead. - After a `sample_rows` evaluation, the fit uses every row of the dataset, which must be within the model's limits. ## Wait, reconnect and cancel Submit without waiting to keep the evaluation ID first: ``` from welt import Client, JobTimeoutError with Client() as client: evaluation = client.submit_evaluation(data, "churned", task="classification", idempotency_key="churn-eval-0001") saved_id = evaluation.id # retain before waiting print(saved_id, evaluation.estimated_credits) try: evaluation.wait(timeout=60) except JobTimeoutError: pass # The evaluation keeps running. Reconnect later; don't resubmit. with Client() as client: evaluation = client.evaluation(saved_id).wait() ``` - `wait()` raises `ExecutionError` when no model finished and `JobCancelledError` after cancellation. Some failed models give `partially_completed`: `wait()` returns normally with an `EvaluationWarning`, and `evaluation.models` explains each error. - `cancel()` stops every unfinished model; `delete()` removes a finished evaluation's results, report and links. `client.evaluations()` lists the workspace's evaluations. - An evaluation borrows its client. Read its results while the client is open, or reopen it with `client.evaluation(id)`. Replay a submission with its key The same `idempotency_key` with the same dataset and options returns the original evaluation instead of starting another. If the connection drops while submitting, the error names the dataset ID and key to replay with. A DataFrame is uploaded again on every call, so replay with the dataset ID from that message. ## Pricing and limits An evaluation is one priced operation (usage `kind: evaluate`) on the fit and predict rates of the active rate card: - each model that produced out-of-fold predictions costs the fit rate on (folds − 1) × rows × columns, target included, plus the predict rate on rows × features; - the total is rounded up once, with one five-credit minimum for the whole evaluation; - models that failed cost nothing, and a failed or cancelled evaluation releases its whole reservation. For example, on the current `2026-10-v2` card, 600 rows with 18 features plus the target, 5 folds and 4 models come to 20.4, so 21 credits. Read the current rates with `client.pricing()`, and see [usage and workspace credits](https://ergodic-ai.github.io/welt-python/usage.html#usage-and-workspace-credits) for balances and usage events. `evaluation.estimated_credits` is reserved at submission, and `evaluation.credits` is the settled charge once the evaluation finishes (`None` until then). `max_credits` refuses an evaluation whose estimate is higher (`InvalidInputError`, `code="budget_exceeded"`). The largest training fold (the rows minus the smallest fold, about rows × (folds − 1) / folds) must fit one of the model's [shapes](https://ergodic-ai.github.io/welt-python/capabilities.html#available-models), and classification takes up to 10 classes. With the default 5 folds, up to 20 features and a stratified or k-fold split (group and custom folds can be uneven), that is: | Model | Rows you can evaluate | |---|---| | TabICLv2, Kumo Tabular Medium | up to 10,000 | | Mitra-v2 | up to 5,000 | | TabDPT 1.3 | up to 625 | A larger table is never silently sampled. If a model you list does not fit, the evaluation is refused; with no models listed, Welt skips that model. To evaluate on a subset, opt in with `sample_rows`: `sample_rows=10000` fits TabICLv2 and Kumo Tabular Medium at up to 20 features. Welt draws a seeded sample (stratified for classification) and the report records it. Can I evaluate from async code? `AsyncClient` has the same `submit_evaluation`, `evaluate`, `evaluation` and `evaluations` methods, returning `AsyncEvaluation`. Await its `wait()`, `refresh()`, `folds()`, `predictions()`, `report_html()`, `report_link()`, `show()` and `fit()`; `summary()` needs no await. In a notebook, an `AsyncEvaluation` displays its report after you have awaited `show()` or `report_html()` once. What if the server doesn't offer evaluations? Evaluations need a Welt server release with the `/v1/evaluations` routes. On an older server, `submit_evaluation`, `evaluation` and `evaluations` raise `NotFoundError` with `code="evaluations_unavailable"`. If a table was already uploaded, the message names its dataset ID so you can reuse or delete it. ## Next steps - [Select a model](https://ergodic-ai.github.io/welt-python/model-selection.html) readiness, swapping and fair comparisons. - [Models and limits](https://ergodic-ai.github.io/welt-python/capabilities.html) every qualified task and its limits. - [Reuse a predictor](https://ergodic.dev/library/articles/guide-reuse-a-fitted-predictor) reopen the model you fitted. --- # Compare Four Tabular Foundation Models in One Call Page: https://ergodic.dev/library/articles/compare-four-tabular-foundation-models `client.evaluate` cross-validates up to eight tabular foundation models on the same seeded folds of your table, against a baseline, and tells you when the top two are tied. This tutorial runs TabICLv2, Kumo Tabular Medium, TabDPT 1.3 and Mitra-v2 on Iris, reads the leaderboard, shares the report and fits the top-ranked model. Comparing models by hand means four fits, four sets of predictions and a spreadsheet you'll get slightly wrong. This walkthrough does it in one call. It uses Iris from Welt's research catalogue because it's small enough for every model's limits and you already know what it looks like. Swap in your own table at step 3. The same steps run as a notebook: the "Compare models" notebook in the Welt docs holds out Iris test rows, cross-validates on the rest and fits the chosen model. ## 1. Install You need `welt-client` 0.12.0 or later for evaluations. Install the current release with the Parquet reader, which the research dataset loader needs: ``` pip install "welt-client[parquet]" ``` ## 2. Connect Evaluations need a workspace key with write permission and some credits. From a terminal, run `welt login`. In a notebook, connect from Python and approve the workspace in your browser: ``` from welt import Client client = Client() client.connect() ``` The connection lasts for the Python process unless you pass `save=True`. Keep the client open for the rest of the tutorial, because an evaluation borrows it for its reads. ## 3. Load a table Iris has a documented ID in the research catalogue, and its outcome column is `target`: ``` dataset_id = "asset-d839644b6de36fc5cafdda18c5daeca3" data = client.load_research_dataset(dataset_id) print(data.shape) print(data.head()) ``` To look for something else, search the catalogue. `research_datasets` takes `q`, `source`, `availability` and a `limit` from 1 to 50: ``` page = client.research_datasets(q="yacht", availability="available", limit=10) for item in page["items"]: print(item["id"], item["name"], item["rows"], item["columns"]) ``` Research downloads may use credits, so check Workspace, then Billing, before a big one. Now set some rows aside. The evaluation picks a model, and you want one honest check of that model on rows it never touched: ``` from sklearn.model_selection import train_test_split train, test = train_test_split(data, test_size=0.2, stratify=data["target"], random_state=0) ``` ## 4. Mind the leakage boundary Welt assigns every row to one fold from your seed, and for each fold a model sees only the other folds and predicts the held-out rows. A row is never predicted by a model that has seen it. That boundary covers Welt's folds. It doesn't cover anything you did to the table before uploading. If you compute target encodings, scaling or features from future rows across the whole table first, the held-out answers are already baked in and the scores will be optimistic. An ID column that tracks the target leaks the same way. Prepare rows independently and drop such columns before you call `evaluate`. Iris needs none of this, which is one reason it's a nice first table. ## 5. Run the evaluation Name the four models explicitly. Each must be able to evaluate your table, or the whole request is refused with that model's reason and nothing runs: ``` evaluation = client.evaluate( train, "target", task="classification", models=["tabicl-v2", "kumo-medium", "tabdpt-1.3", "mitra-v2"], seed=7, ) ``` Defaults worth knowing: 5 folds (`folds` takes 2 to 10), and `split="auto"`, which is stratified for classification. `evaluate` waits up to 600 seconds. If the wait stops, the evaluation keeps running and you can reconnect with `client.evaluation(id)`. Leave out `models` and Welt evaluates every available catalogue model whose limits admit your data, and lists the rest in `evaluation.skipped` with a reason. Planned models aren't evaluated either way. To cap spending, pass `max_credits`. An evaluation whose estimate is higher is refused with `code="budget_exceeded"`. ## 6. Read the leaderboard ``` summary = evaluation.summary() print(summary) ``` `summary()` makes no request. It's a DataFrame indexed by `model_id`, ranked models first and the baseline last. The columns are `name`, `rank` (empty for the baseline) and a `_mean` and `_sd` pair for every metric of the task. For classification that means `roc_auc`, `log_loss`, `brier`, `accuracy`, `balanced_accuracy`, `f1_macro` and `ece`. ``` (results pending) ``` Iris has three classes, so models are ranked by log loss, the default for multiclass. Binary tasks rank by ROC AUC and regression by RMSE. Pass `primary_metric` to choose another. The baseline predicts each training fold's class shares. It's there so you can see whether a model learned anything at all. On small or noisy tables, check it every time. Per-fold numbers come from `folds()`, a long table with `model_id`, `fold`, `rows`, `metric` and `value`: ``` folds = evaluation.folds() print(folds[folds["metric"] == "log_loss"]) ``` Out-of-fold predictions are in `evaluation.predictions()`, with a column per model and `:p()` probability columns. They expire after seven days. The summary, fold metrics and report stay until you delete the evaluation. ## 7. Check for ties and warnings ``` print(evaluation.comparison) for warning in evaluation.warnings: print(warning) ``` `evaluation.comparison` compares the top two models fold by fold. If it reports `separated: False`, they're tied within fold-to-fold variation, and the ranking between them is noise. Choose on something else, like cost or prediction latency. `evaluation.warnings` flags small datasets, class imbalance, skipped models and models that don't beat the baseline. (results pending) One more caution before you quote the `ece` column at anyone: native probabilities aren't calibrated intervals. ECE tells you how far off they are on this table. ## 8. Look at the report and share it In Jupyter, display the HTML report: ``` evaluation.show() ``` It renders in a sandboxed frame that can't run code or restyle your notebook. To keep a copy, save the self-contained HTML: ``` from pathlib import Path Path("report.html").write_text(evaluation.report_html(), encoding="utf-8") ``` To send it to a colleague, make a signed link that lasts 1 to 7 days: ``` link = evaluation.report_link(days=7) print(link.url, link.expires_at) # the URL is shown once; store it safely ``` Anyone with the link can read the report without signing in, so treat it like a password. It never opens the predictions or fold data. A link made with an API key never outlives that key. `report_links()` lists links and `revoke_report_link(link)` revokes one. ## 9. Fit the top-ranked model and check it once ``` model = evaluation.fit() # the leaderboard's first model # model = evaluation.fit("tabdpt-1.3") # or pick one yourself, say after a tie from sklearn.metrics import accuracy_score predictions = model.predict(test.drop(columns="target")) print("test accuracy:", accuracy_score(test["target"], predictions)) ``` `fit()` submits a new fit of that model on the full stored dataset, which here is `train`, with the evaluation's seed. It doesn't promote a fold context, and it's charged as a fit. If the catalogue has moved to a newer model version since the evaluation, you'll get an `EvaluationWarning` naming both versions, and the evaluation's scores describe the older one. The test rows were never uploaded, so this accuracy is one clean check on rows nobody has seen. Direct prediction takes up to 100 rows per call, which is plenty for Iris. Use batch prediction for more. ## What it costs An evaluation is one priced operation. Each model that produced out-of-fold predictions costs the fit rate on (folds minus 1) × rows × columns, target included, plus the predict rate on rows × features. The total is rounded up once, with a single five-credit minimum. Failed models cost nothing. The docs' example: on the `2026-10-v2` rate card, 600 rows with 18 features plus the target, 5 folds and 4 models come to 20.4, so 21 credits. Check today's rates with `client.pricing()` and the reserved estimate with `evaluation.estimated_credits` if you submit with `client.submit_evaluation`. ## How big a table you can evaluate The largest training fold, about rows × (folds − 1) / folds, has to fit one of the model's shapes. With the default 5 folds, up to 20 features and a stratified or k-fold split: | Model | Rows you can evaluate | |---|---| | TabICLv2, Kumo Tabular Medium | up to 10,000 | | Mitra-v2 | up to 5,000 | | TabDPT 1.3 | up to 625 | Wider tables take fewer rows. A larger table is never sampled silently. If a model you named doesn't fit, the request is refused. To evaluate on a subset, opt in with `sample_rows=10000`, which fits TabICLv2 and Kumo Tabular Medium at up to 20 features, and the report records the sample. If you name all four models on a 3,000-row table, TabDPT 1.3 will refuse it, so either drop it from the list or leave `models` empty and read `evaluation.skipped`. Time-ordered splits aren't available in this version. If your rows have a time order, k-fold will leak the future into training, so treat the scores with suspicion. ## Try it ``` pip install "welt-client[parquet]" ``` The full evaluation guide is at https://ergodic-ai.github.io/welt-python/evaluations.html. ## FAQ How many models can one evaluation compare? Up to eight classification or regression models, all on the same seeded folds, plus a baseline. Leave `models` empty to run every eligible one. What does `separated: False` mean? The top two models are tied within fold-to-fold variation. Don't treat the ranking between them as meaningful. Does `evaluation.fit()` reuse a model trained during cross-validation? No. Fold contexts are discarded. `fit()` submits a new fit on the full stored dataset and is charged as a fit. --- # Reuse a Fitted Predictor Page: https://ergodic.dev/library/articles/guide-reuse-a-fitted-predictor Fit once, then predict on new rows with the same predictor in your private workspace. Reopening fetches the pinned metadata; it doesn't upload training data or fit again. A predictor is the fitted model Welt keeps in your workspace after a successful `fit`. You reach it again through its predictor ID. ## Save the predictor ID After a successful fit, keep `model.predictor_id_` with your experiment metadata. ``` predictor_id = model.predictor_id_ metadata = model.export_metadata() print(predictor_id, metadata["model_version"]) ``` A predictor ID is an identifier, not a credential or a portable executable model. Metadata export returns authorized, JSON-compatible server provenance. It contains no API key, model weights or fitted training context. Keep data out of your repository Don't save prediction payloads, customer rows or credentials into your repository. ## Reopen in another session Configure your key again for the same workspace. Then use the ID you saved and the feature-only test table from [Start](https://ergodic.dev/library/articles/get-started-with-welt): ``` from welt import Classifier from sklearn.metrics import accuracy_score # Continue with the feature-only Iris test rows from Start. reopened = Classifier.from_predictor(predictor_id) repeat = reopened.predict(query) print("Test accuracy after reopening:", accuracy_score(y_test, repeat)) ``` For a regression predictor, use `Regressor.from_predictor(...)`. A mismatched task is rejected instead of changing what the predictions mean. Reopening keeps the model, configuration, version and seed pinned. Changing a constructor parameter does not upgrade a fit. A new task, model or configuration needs a new fit. ## Inspect your workspace List your predictors, fetch one predictor's metadata and read usage events: ``` from welt import Client with Client() as client: predictors = client.predictors() metadata = client.predictor(predictor_id) events = client.usage() ``` What persists Predictors and datasets persist until they are explicitly deleted. Idle native cache eviction is execution state, separate from durable ownership. Usage records show operation, attempt and lifecycle workload metadata. Several events may represent one fit, so count distinct `operation_id` values when you count logical operations. Usage is not a monetary price, credit balance or accuracy report. Does a successful reconnect prove the worker restarted? No. A reconnect check alone does not prove a worker restart or cold restoration. ## Next steps - [Notebook examples](https://ergodic-ai.github.io/welt-python/notebooks.html) the artifacts and usage notebook runs these checks. - [Wait and recover](https://ergodic-ai.github.io/welt-python/async-and-errors.html) what to do if a fit hasn't returned an ID. - [Use your own table](https://ergodic.dev/library/articles/guide-predict-with-your-own-table) fit a predictor on your data. --- # Discover a Causal Graph Page: https://ergodic.dev/library/articles/guide-causal-discovery Discover a causal graph from an observational table with a qualified model, then inspect its native edges and scores. You'll need - A target-free observational table. The example uses the Iris measurements you downloaded in [Your first prediction](https://ergodic.dev/library/articles/get-started-with-welt) (`data` and `target`). - A connected Welt workspace. See [Connect your workspace](https://ergodic-ai.github.io/welt-python/connect.html). ## Choose a model ArrowFM, CDFM and AVICI are observational previews. Arrow and CDFM take up to 8,000 rows × 20 variables, with measured wider shapes of 4,000 × 40 and 2,000 × 80. AVICI takes up to 1,000 × 20 (or 500 × 40). Every model needs at least 2 rows and 2 finite continuous variables. The service catalogue (`client.models()`) reports the current limits, shapes, version and readiness. | Model | Select with | Input and decoding | Native output | |---|---|---|---| | ArrowFM | `model="arrow"` | Original native DAG decoder, with separate scores. | Native DAG. | | CDFM | `model="cdfm"` | Original native adaptive threshold, with separate native scores. | Directed output, including possible cycles and reciprocal edges. | | AVICI | `model="avici"` | Preserves full observations and the native population z-score; strict probability > 0.5 decoding. | Directed output, including possible cycles and reciprocal edges. | You select every model through the same client interfaces. - CDFM does not relabel an acyclic directed result as a declared DAG. - AVICI's native PRNG key stays 0; request seeds are retained as provenance. It also refuses every non-declared-DAG Ergodic conversion. Scores are not causal confidence Native scores are not calibrated causal confidence or effects. Other causal engines remain gated. These interfaces perform no automatic ergodic or model download. ## Prepare observational data Use target-free observational datasets. Discovery preserves every uploaded column in its original order. It rejects target-labelled datasets instead of dropping their target. Nonempty constraints and unsupported input are rejected before model work. The [causal notebook](https://ergodic-ai.github.io/welt-python/notebooks.html) downloads and inspects the real data first. Iris has no ground-truth causal graph Inspect native edges and assumptions, without pretending class labels evaluate a graph or establish causal truth. ## Run discovery `Client` and `AsyncClient` provide `submit_discover(dataset_id, model='arrow', configuration='default', seed=0, constraints=None, model_version=None, idempotency_key=None)`, plus a blocking (or awaitable) `discover(..., timeout=600)`. Check readiness first. Capability and readiness checks come from the current `/v1/models` task profile, not a client-side list or a model being present in the catalogue. The example drops the encoded class column, checks ArrowFM's `causal_discovery` profile, uploads the four measurements and runs discovery. ``` from welt import Client # Continue after downloading/inspecting the real Iris data in Start. # Exclude the encoded classification target; keep all four measurements/150 rows. X = data.drop(columns=target) print(X.head()) print(X.shape) with Client() as client: profile = next(m for m in client.models() if m["id"] == "arrow") ready = any(p["task"] == "causal_discovery" and p["execution_available"] for p in profile["task_profiles"]) if ready: dataset = client.upload(columns=list(X.columns), rows=X.values.tolist(), target=None) job = client.submit_discover(dataset["id"], model="arrow", seed=42) result = job.result() scores = client.causal_scores(job.id) reopened = client.causal_result(job.id) ``` Submission returns the existing durable `Job` or `AsyncJob` handle. A successful discover job returns a `CausalResult`; successful supervised jobs keep their current return types. A timeout doesn't stop the job Timeout does not cancel server work. Reconnect with `client.job(job_id)`. ## Use the estimator interface `CausalDiscovery` has sklearn-style constructor parameters, cloning and `get_params`. Its modelling operation is discover, not supervised fit and predict. - `discover(X)` and `submit_discover(X)` accept a DataFrame, a 2D array, CSV or Parquet through the existing table converter. Or pass the keyword `dataset_id` without uploading. Supply exactly one table or reference. - Arrays receive `x0`, `x1`, … names. Named columns keep their original order. - Blocking `discover` closes its temporary HTTP client. A submitted job owns its client until you finish or reconnect and close `job.client` explicitly. ## Read the result `CausalResult` preserves immutable ordered variables, marks, the native graph type, model and configuration, and an opaque score reference. `to_dict` returns a fresh ordinary wire dictionary. The immutable `job_id`, `diagnostics`, `configuration_version`, `assumptions` and `decoder` accessors expose the original provenance. Blocking convenience calls return a result with `result.job_id`, so a new client can fetch scores or reopen it after the facade closes its HTTP client. Client reopening verifies this owned job identity. Use `client.causal_result(job_id)` and `client.causal_scores(job_id)` explicitly for authenticated reconnecting and score access. That way the result carries no hidden client or credentials. Score access checks the result identity, reference, original axes and finite native probability semantics. Scores never threshold or rewrite the graph. Typed malformed-result errors apply without repair. ## Convert to an Ergodic graph [ergodic](https://docs.ergodic.dev) is Ergodic's open-source causal library. It identifies and estimates effects on a graph. Install it with the `ergodic` extra: pip: ``` pip install "welt-client[ergodic]" ``` uv: ``` uv add "welt-client[ergodic]" ``` `result.to_ergodic()` converts a declared native DAG locally into an `ergodic.MixedGraph`. It keeps every isolate and the native tail and arrow directions. It refuses every graph not explicitly declared a native DAG, including acyclic directed graphs and cycles, without projection. ``` graph = result.to_ergodic() print(graph.is_dag()) ``` `MixedGraph` stores node sets. To keep the original axis order, inspect adjacency with `graph.to_adjacency(order=list(result.variables))`. How is the ergodic dependency checked? The extra installs `ergodic>=0.2,<0.4`. Conversion checks the graph format the installed package reads (`ergodic.GRAPH_FORMAT`, currently `ergodic.graph/1`), not its version. A missing package, or one without a supported format such as ergodic 0.1, raises a typed `OptionalDependencyError` that names the extra. Welt never downloads a dependency during conversion. CI tests conversion against the oldest and latest supported ergodic releases. CDFM and AVICI results stay native here. ergodic can decode their edge scores into a DAG locally, but only when you pass an explicit `decoder=` to `ergodic.welt.discover`; the graph is then labelled decoded, not native. Check which versions work together in [Compatibility with ergodic](https://ergodic-ai.github.io/welt-python/capabilities.html#compatibility-with-ergodic). Continue in ergodic The [ergodic guide to Welt](https://docs.ergodic.dev/welt.html) takes a converted graph through identification and effect estimation, and runs Welt models from inside ergodic. Discovered edges are not causal truth Conversion and local identification or effect estimation are separate scientific steps; a model's discovered edges do not establish causal truth. Native edge scores are neither calibrated confidence nor graph posterior probabilities. ## Delete results and datasets Retention and deletion of the primary graph and scores, and result quotas, are server contracts. They are independent of seven-day downloadable prediction payloads. Two explicit calls delete owned state: - `client.delete_causal_result(result.id)` explicitly deletes the retained primary graph and scores. - `client.delete_dataset(result.dataset_id)` separately deletes an upload, only if it has no retained predictor or result, and no queued or running job dependencies. `AsyncClient` exposes the same methods with `await`. There is no implicit deletion, cascade or expiry when a client closes or discovery times out. | Situation | Result | |---|---| | Successful deletion | Returns `None`. Repeat deletion of the same owned resource is safe. | | Foreign or missing identity | Raises `NotFoundError`. | | Dataset still has dependencies | Raises `ConflictError` with code `dependency_conflict`. | | Reading an explicitly deleted primary result or scores | Raises `ResultDeletedError`. Job, provenance and usage metadata remain. | | Payload removal returns retryable `deletion_pending` | Retry the same DELETE. Quota and dataset dependency remain reserved until it completes. | How were the deletion routes checked? These explicit server routes are deployed; dependency, race and tenant contracts were checked against temporary local state. Earlier bounded live acceptance retains its qualification results and does not delete hosted state. ## Next steps - [Discover in Welt, estimate in ergodic](https://docs.ergodic.dev/welt.html) identify and estimate effects on a discovered graph. - [Notebook examples](https://ergodic-ai.github.io/welt-python/notebooks.html) the causal notebook inspects the real data first. - [Models and limits](https://ergodic-ai.github.io/welt-python/capabilities.html) every qualified causal model and its limits. - [Wait and recover](https://ergodic-ai.github.io/welt-python/async-and-errors.html) reconnect to jobs and handle typed errors. --- # From a Table to an Effect: Discover in Welt, Estimate in Ergodic Page: https://ergodic.dev/library/articles/discover-in-welt-estimate-in-ergodic A correlation tells you what moves together. A policy question asks what happens if you change something. This walkthrough takes a 400-row public table and learns a candidate causal graph with Welt's Arrow model. Then it adds what you already know and estimates one effect in the open-source Ergodic package, and tries to break the estimate. ## Why a graph comes before the number Most of the tables scientists and policy analysts work with are observational. Nobody assigned the treatment. If you regress birthweight on the number of prenatal visits, you get a slope, and that slope mixes the effect of visits with everything that drives both visits and birthweight. A mother with more years of education might book more visits and also have heavier babies for other reasons. The question "what happens to birthweight if a mother has one more prenatal visit" is an intervention question. To answer it from observational data you need a claim about which variables cause which, so you know what to adjust for. That claim is a causal graph. We wrote about the long fight to separate the two kinds of question in; this post is the practical version. You can draw the graph yourself. You can also ask a model to propose one from the data. Welt does the second part. Ergodic does the rest. ## The split between Welt and Ergodic Welt runs hosted foundation models. For causal discovery the catalogue (snapshot of 17 Oct 2026) qualifies three of them, all as observational previews: | Model | Selected with | What it returns | Table shapes it takes (rows x variables) | |---|---|---|---| | Arrow / ArrowFM | `model="arrow"` | A native DAG, plus separate edge scores | 8,000 x 20, 4,000 x 40, 2,000 x 80 | | CDFM | `model="cdfm"` | Directed edges that may include cycles and two-way pairs, with an adaptive threshold | 8,000 x 20, 4,000 x 40, 2,000 x 80 | | AVICI | `model="avici"` | Directed edges that may include cycles and two-way pairs, decoded at probability > 0.5 | 1,000 x 20, 500 x 40 | Every model needs at least 2 rows and 2 finite continuous variables, with no target column. Check the live limits with `Client().models()` before you run anything, because the catalogue can change. Welt stops at the graph. It doesn't estimate effects. The Ergodic package is our open-source causal library (Apache-2.0). It identifies whether a graph can answer your question, estimates the effect with an interval and runs refutation checks, all locally. The difference between the three discovery models matters at the hand-off. Only Arrow declares its output a DAG, so only Arrow converts directly. `to_ergodic()` refuses CDFM and AVICI results, even when their output happens to have no cycles. Ergodic can decode their edge scores into a DAG, but only when you ask for it with `decoder=`, and it labels the result decoded. A decoded graph is the decoder's choice. It isn't the model's claim. ## Step 1: discover a graph in Welt The data is the birthweight extract bundled with Ergodic (Almond, Chay and Lee, 2005): 400 births and five continuous columns. Those are the mother's age, the father's age, the mother's years of education, the number of prenatal visits and the birthweight in grams. ``` from ergodic.datasets import load_birthweight from welt import CausalDiscovery births = load_birthweight() columns = ["mage", "medu", "nprenatal", "bweight", "fage"] data = births.data.select(columns).take(range(400)) # ergodic TabularData frame = data.to_pandas() result = CausalDiscovery(model="arrow", random_state=0).discover(frame) # one paid job graph = result.to_ergodic() print(graph.is_dag()) for edge in sorted(edge.glyph() for edge in graph.edges): print(edge) ``` You'll see one line per edge, such as `medu --> nprenatal`. Your edges depend on the Arrow version Welt serves, which the result records. We haven't published output here because the run needs a key: (results pending). Arrow's native scores are available with `client.causal_scores(job_id)`. They aren't calibrated confidence, and they aren't graph posterior probabilities. Don't read 0.8 as "80% sure". ## Step 2: add what you already know Arrow saw 400 rows and nothing else. You know things it doesn't. Parents' ages and education come before a pregnancy's prenatal visits, and visits come before the birth. Write that down: ``` from ergodic import DomainKnowledge from ergodic.welt import discover knowledge = DomainKnowledge().with_tiers( [["mage", "fage", "medu"], ["nprenatal"], ["bweight"]] ) informed = discover(data, model="arrow", knowledge=knowledge, seed=0) # a second paid job print(informed.diagnostics["knowledge_audit"]) ``` Welt itself runs without constraints. The knowledge applies to the local decoding of Arrow's scores, so `informed.graph` replaces Arrow's native DAG with one decoded under your tiers. The audit reports how the model's scores sit against each statement, which is the useful part. If the data strongly disagrees with a tier you were sure of, that's worth a second look at the data before you look at the model. ## Step 3: identify, then estimate Identification is a yes or no question asked before any estimate: can this graph and this data recover the effect of prenatal visits on birthweight? ``` from ergodic import estimate_effect, identify_effect graph = informed.graph print(identify_effect(graph, "nprenatal", "bweight")) estimate = estimate_effect( graph, data, "nprenatal", "bweight", strategy="dml", random_state=0 ) print(estimate) ``` If there's a directed path from `nprenatal` to `bweight`, Ergodic names the adjustment set it will use. If there isn't, it returns the `null` strategy, meaning that by this graph the effect is zero, and DML refuses to run. If Ergodic labels the decoded graph `mixed` and refuses it, the error tells you to call `graph.as_kind("dag")`. The estimate is an average change in grams per extra prenatal visit, with a standard error and a 95% interval: (results pending). You can put a Welt tabular model into the nuisance slots with `learner=WeltLearner("tabicl-v2", max_fits=4)`, as the [ergodic guide](https://docs.ergodic.dev/welt.html) shows, at four paid fits for two folds. ## Step 4: try to break it ``` from ergodic import refute_effect for method in ("placebo_treatment", "random_common_cause", "data_subset"): check = refute_effect( graph, data, "nprenatal", "bweight", method=method, strategy="dml", estimand_value=estimate.value, random_state=0, ) print(check) ``` Each check reruns the estimate under a perturbation. A placebo shuffles the treatment column and should make the effect vanish. A random common cause shouldn't move it. Subsets of 80% of the rows should give roughly the same number. We kept the local learners here on purpose. Each refutation reruns the estimate 100 times by default, and with a Welt learner every rerun would be paid fits. A failed check is a real warning. A passed check proves little. Ergodic's own documentation shows a confounded estimate that leaves out all 17 confounders passing the placebo test. ## The assumptions you're signing up to Every number above rests on claims the data can't check. Write them into your methods section. The data is observational, and the rows are independent units. Welt discovery reads finite continuous variables with no missing values, so categorical columns such as smoking status stay out of this graph, and anything they cause or confound is invisible to it. The DAG Arrow returns has no hidden-variable marks. When Ergodic identifies the effect by adjustment on it, it treats every common cause of visits and birthweight as measured. With five columns from a natality record, that's a strong assumption. Ergodic's assumptions page shows what happens to an estimate on the same data when you change your mind about confounders: on the full extract, the smoking effect moves from about 222 g to 275 g depending only on the graph you assume. Estimation assumes overlap, meaning that births at every level of the adjustment variables could have had more or fewer visits. And the discovered edges are a hypothesis. Arrow learned them from 400 rows. Ergodic's [Test a graph against data](https://docs.ergodic.dev/v0.3.0/test-a-graph.md) can reject a graph whose missing edges the data contradict, but a pass doesn't confirm it. ## Try it ``` pip install "welt-client[ergodic]" ``` Or start from Ergodic with `pip install "ergodic[welt]"` (Python 3.11 to 3.13), then run `welt login`. The full walkthrough, with the CDFM and AVICI decoding path, is [Discover in Welt, estimate in Ergodic](https://docs.ergodic.dev/welt.html). The Welt side is in the [causal discovery guide](https://ergodic-ai.github.io/welt-python/causal-discovery.html). ## FAQ ### Why can't I convert a CDFM graph that has no cycles? Because CDFM doesn't declare its output a DAG. `to_ergodic()` converts only what a model claims, and it never projects or relabels. Use `ergodic.welt.discover(data, model="cdfm", decoder="greedy")` to decode the scores yourself, and report that you did. ### Is the Welt graph better than PC or GES? We haven't shown that. On a benchmark with a known graph you can measure it, which is what our Sachs protein-signalling use case sets out to do. On your own data there's usually no ground truth, so treat every discovered graph as a draft for domain experts to argue with. ### Does Ergodic need Welt? No. Ergodic runs discovery methods such as PC and GES locally and never imports Welt unless you install the extra. --- # Find and Load Research Datasets Page: https://ergodic.dev/library/articles/guide-research-datasets Find a real table in Welt's research catalogue, then load it into a DataFrame or save it as a file. These are research examples; downloading a table does not upload it into your private workspace. You'll need - The SDK. Searching and inspecting the catalogue need no key; to download or load a table, connect your workspace first. See [Connect](https://ergodic-ai.github.io/welt-python/connect.html). - For downloads, check your credits in Workspace → Billing. Research downloads may consume them. ## Find a table Search the catalogue by keyword: ``` from welt import Client with Client() as client: page = client.research_datasets(q="iris", availability="available", limit=10) for item in page["items"]: print(item["id"], item["name"], item["rows"], item["columns"]) ``` Search filters include `q`, `source` and `availability`, with `limit` from 1 to 50. A listing returns `next_cursor`; pass it as `cursor` to get the next page. Use the dataset ID to inspect its columns and recorded targets: ``` dataset_id = "asset-d839644b6de36fc5cafdda18c5daeca3" with Client() as client: info = client.research_dataset(dataset_id) print([column["name"] for column in info["schema"]]) print(info["targets"]) ``` For this Iris table the outcome column is `target`. For Yacht Hydrodynamics it is `Residuary.resistance`. Use the names in the downloaded table and its metadata. ## Load a DataFrame Install the reader with `pip install "welt-client[parquet]"`, then load a table: ``` with Client() as client: data = client.load_research_dataset(dataset_id) print(data.head()) print(data.shape) ``` The loader downloads the current published content and verifies it. It then reads the table with pandas and removes its temporary file. It handles supported Parquet and archive content. Pass `metadata=True` when you also want the table's column descriptions: ``` with Client() as client: data, meta = client.load_research_dataset(dataset_id, metadata=True) print(meta.name) print(meta.column_descriptions) ``` Ready to model? Continue with [your first prediction](https://ergodic.dev/library/articles/get-started-with-welt) to split Iris into training and test rows, fit a classifier and evaluate its predictions. ## Save a file To keep a copy on disk, download the table to a new path: ``` from pathlib import Path from tempfile import mkdtemp path = Path(mkdtemp(prefix="welt-research-")) / "iris.parquet" with Client() as client: client.download_research_dataset(dataset_id, path) print(path) ``` - With no version argument, the SDK downloads the current published content. - It verifies the byte size and SHA-256 before the file appears at your path. Interrupted downloads leave no partial destination. - An existing file or symlink raises `FileExistsError`. Choose a new path to save another copy. Pass `metadata=True` to also save `.metadata.json`. You get back a `ResearchDownload` containing both paths and the dataset metadata: ``` with Client() as client: saved = client.download_research_dataset( dataset_id, Path(mkdtemp(prefix="welt-research-")) / "iris.parquet", metadata=True) print(saved.path, saved.metadata_path) ``` `download_research_dataset` saves the served file as-is. Check `info["content"]["media_type"]` to choose how to open it. To read supported archives directly into a DataFrame, use `load_research_dataset` instead. Size limit The default download size limit is 128 MiB. Pass `max_bytes` for a larger table, up to 2 GiB. A dataset whose `content` is `None` has no downloadable file. ## Async downloads `AsyncClient` offers the same download: ``` from welt import AsyncClient async def fetch(dataset_id, path): async with AsyncClient() as client: return await client.download_research_dataset(dataset_id, path) ``` Both clients use your workspace credentials and the same download checks. ## Next steps Before fitting, inspect the model's limits. Keep test rows separate from training rows, and select a target explicitly. - [Models and limits](https://ergodic-ai.github.io/welt-python/capabilities.html) check what a model accepts before you fit. - [Your first prediction](https://ergodic.dev/library/articles/get-started-with-welt) train and evaluate on a research table. - [Notebook examples](https://ergodic-ai.github.io/welt-python/notebooks.html) complete classification, regression, async and causal workflows. --- # Run Welt from the CLI or an Agent Page: https://ergodic.dev/library/articles/guide-welt-cli-for-agents Run Welt from a terminal, a script or an agent. Successful commands print one JSON value on stdout. Check the exit status before you parse it. Install the current `welt-client` release to use these commands. Model readiness, file formats and limits depend on the connected service. `welt --help`, `welt COMMAND --help` and `welt capabilities` describe the complete command tree. `python -m welt` uses the same entry point. ## Connect and choose a workspace ``` welt workspaces create # opens /workspaces/new; finish the browser form welt login --workspace acme-research # exact slug or workspace ID welt login --workspace ws_other --no-browser welt workspaces list # saved local profiles, expiry and active status welt workspaces use acme-research # verifies saved key then changes local default welt whoami # actual key workspace, role and limits welt datasets list --workspace ws_other welt logout --workspace ws_other # forgets local profile; does not revoke server key ``` To create a Team or Academic workspace and switch browser context, use the console's New workspace navigation entry or its topbar switcher. Your Personal workspace already exists. - A new shared workspace is billed separately and starts with zero credits. Creating one does not require a payment method. - Invite colleagues in Members; they must accept explicitly. - Owners, admins and members can authorize their own client. Approval shows the requested workspace and rejects a different one. Every command accepts `--base-url`, `--workspace` and `--timeout`. `WELT_BASE_URL` and `WELT_WORKSPACE` provide defaults. Credential precedence is: an explicit SDK key, then `WELT_API_KEY`, then the process or saved profile. - The workspace option verifies that credential's tenant before sending private input. It cannot retarget a bearer key. - Unset `WELT_API_KEY` and `WELT_WORKSPACE` if they override the default you selected with `workspaces use`. - Use explicit per-command selection for concurrent agents. The shared active profile is a convenience for interactive use. - CLI origins must be HTTPS or explicit localhost HTTP. Redirects and cross-origin requests never receive bearer credentials. Where are my credentials stored? Credentials are stored privately in `WELT_CONFIG_DIR` (default `~/.config/welt`): the POSIX directory is 0700 and files are 0600, with atomic writes, private per-origin lock files and no symlink following. Profile updates are serialized across CLI processes. Each origin retains multiple workspace keys; `login` and `use` select the local default. Old single-credential files still load. When you save a login, the CLI links any old single credential to its tenant with a read-only API probe and keeps that previous key. If the probe is unavailable, the CLI keeps the unknown credential privately until it can be linked. `--no-save` retains access only during the CLI process. `Client().connect()` keeps credentials in the Python process unless `save=True` is explicit. Paid work uses workspace credits Before paid work, check Workspace → Billing for available credits, pending reservations and spend caps. [Usage and recovery](https://ergodic-ai.github.io/welt-python/usage.html#usage-and-workspace-credits) explains current accounting and HTTP 402 conditions. ## Durable modelling workflow ``` welt models list welt models get tabicl-v2 welt datasets upload --input train.json # {columns, rows, target, name} welt fit --dataset ds_train --model tabicl-v2 --task classification --seed 19 --idempotency-key fit-run-00000001 welt jobs get job_fit welt jobs wait job_fit --timeout 600 welt predictors get pred_fitted welt predict --predictor pred_fitted --input query.json welt batch --predictor pred_fitted --dataset ds_query --idempotency-key batch-run-000001 welt jobs result job_batch # row coverage, failures, version, expiry welt jobs payload job_batch # authenticated payload, original row positions welt usage --model tabicl-v2 --since 2026-10-11T00:00:00Z ``` - Use the IDs returned by earlier commands. - `models list` reports actual availability, qualified tasks and configurations, and limits. Commands do not activate held models. - You can supply table JSON on stdin with `--input -`. Prediction input contains `columns` and `rows`; request probabilities explicitly with `--probabilities`. - Fit returns a durable job ID and replay key immediately. `jobs wait` times out locally while accepted work continues; reconnect with the job ID. Unsure whether a submission went through? Inspect jobs before submitting again. To retry, reuse the original idempotency key and an identical payload. Replay keys, including generated ones, are printed to stderr before submission. Writes are not automatically retried; bounded transient retries apply to GETs. ## Resume a supervised file upload ``` welt uploads create train.csv --target outcome --schema schema.json welt uploads get upload_id welt uploads file train.csv --target outcome --schema schema.json --upload-id upload_id ``` Use `uploads create` first when recovery matters, and keep the upload ID before sending bytes. `uploads file` verifies the file's checksum, size, format, schema and target against a resumed session. It skips acknowledged chunks and completes validation. `uploads chunk ID INDEX FILE` and `uploads complete ID` expose the lower-level contract. A schema looks like `{"columns":["x","outcome"],"types":["number","string"]}`. Types follow the API file schema (`number`, `boolean`, `string`); use `string` for categorical columns. The completed upload returns a dataset ID for a supervised fit. That target-labelled dataset cannot be used for causal discovery. File formats vary by deployment CSV and Parquet support depends on the deployed server configuration and its qualified parser and envelope. Do not assume every deployment enables Parquet. ## Causal discovery with target-free observations Prepare a separate table containing only the numeric variables to study. For example, save the Iris measurements loaded in [Start](https://ergodic.dev/library/articles/get-started-with-welt), dropping the class label before you create the upload JSON: ``` # Continue with the Iris data and target from Start. from pathlib import Path import json observations = data.drop(columns=target) Path("observations.json").write_text(json.dumps({ "columns": list(observations.columns), "rows": observations.values.tolist(), "target": None, "name": "Iris measurements", }), encoding="utf-8") ``` Then upload the table and run discovery: ``` welt datasets upload --input observations.json # Replace ds_observations with the dataset ID returned above. welt discover --dataset ds_observations --model arrow --seed 19 --idempotency-key graph-run-000001 welt jobs result job_graph welt jobs scores job_graph ``` Arrow accepts at least 2 rows and 2 finite continuous variables, up to 8,000 × 20 (or 4,000 × 40, 2,000 × 80; see `welt models get arrow`), without a supervised target. Its current path does not support nonempty required or forbidden edges, or temporal constraints, so this recipe omits `--constraints`. There is no ground truth here A graph inferred from these measurements has no ground-truth causal graph for accuracy evaluation. Native scores are method-defined, not normalized graph posterior probabilities. Python provides validated graph objects and optional local Ergodic conversion; see [Causal discovery](https://ergodic.dev/library/articles/guide-causal-discovery). ## Other commands and authority Inspect resources with `datasets list/get`, `predictors list/get`, `jobs list/get`, `research list/get/download` and `pricing`. - Research search is paginated; pass its `next_cursor` as `--cursor`. - Preserve the exact version and checksum provenance of downloads. `research download ID PATH --max-bytes LIMIT` selects the current published file and makes a verified download to a new local file. The configured server may meter downloads. - `jobs cancel ID --yes`, `datasets delete ID --yes` and `causal-results delete ID --yes` are explicit mutations. - Dataset deletion refuses retained dependencies; the CLI never cascades. Primary result deletion retains job and usage metadata. Deletion needs an exact request Never delete real customer state without an exact user request. Account changes, workspace creation, invitations and member administration, key administration and billing need browser account authority. Use `welt console account|workspace|members|keys|billing|create [--no-browser]` to open the corresponding control. - Signed-in browser state determines the console's active workspace, independently of CLI profiles. - `workspaces list` shows local saved connections. It is not an account-wide membership query. - Payments require explicit completion of browser Checkout or Portal. `pricing` only reads public offers. ## Output, errors and exit codes Successful commands emit one JSON value on stdout. Login links and codes, submission replay keys and errors go to stderr; secrets never appear. A script should parse stdout only when the exit status is zero. `capabilities` is a machine-readable command inventory. Error JSON has `error.code`, `message`, `status_code`, `request_id`, `job_id`, `retryable`, `retry_after` and `idempotency_key` where available. | Exit status | Meaning | |---|---| | 0 | Success. If the command submitted a job, that job is still pending; inspect it separately. | | 1 | API, local file, credential, validation or wait failure. | | 2 | Command syntax error (argparse usage text on stderr). | | 130 | Interrupted locally; server job state is unchanged. | Batch wait returns a manifest for `succeeded` or `partially_completed`. Inspect failed ranges and payload errors rather than counting missing rows as predictions. An entirely failed or cancelled job raises its terminal error. Manifests remain inspectable after payload retention expires; payload retrieval returns explicit expiry errors. Use the server's `expires_at` and version fields. ## Hidden model runs and forecasting ``` welt models get chronos-2 welt run --input forecast.json --idempotency-key forecast-00000001 welt forecast --input request.json --idempotency-key forecast-00000002 # servers with the forecasting task welt jobs wait job_returned --timeout 600 welt model-runs delete job_returned --yes welt forecasts delete forecast_job_returned --yes ``` `forecast.json` uses the task payload in [Hidden model runs](https://ergodic-ai.github.io/welt-python/model-runs.html). `welt forecast` submits a `POST /v1/forecasts` request body (history and future as dataset IDs or inline tables, column roles, horizon) and returns its job ID and idempotency key the same way. It sends the body as written: for `timestral-209m` and `timestral-28m`, which forecast one series per request, the server refuses a history with more than one series with `unsupported_capability` (JSON on stderr, exit status 1). `models list` stays curated; inspect a hidden model by its exact ID. The server enforces workspace access. `run` returns a durable job, and `jobs wait` returns its native task-specific JSON result. These bounded runs create no reusable fitted predictor. Deleting a terminal run explicitly purges both its private input and result, while job, replay and usage metadata remain. `welt forecasts delete ID --yes` (`Client.delete_forecast(id)`) does the same for a finished forecast; workspace datasets it read are not deleted. See [forecasting](https://ergodic-ai.github.io/welt-python/forecasting.html#submit-now-collect-later). ## Next steps - [Wait and recover](https://ergodic-ai.github.io/welt-python/async-and-errors.html) what each error means and what to do next. - [Workspace resources](https://ergodic-ai.github.io/welt-python/usage.html) usage events, credits and HTTP 402 conditions. - [Causal discovery](https://ergodic.dev/library/articles/guide-causal-discovery) validated graph objects in Python. - [Hidden model runs](https://ergodic-ai.github.io/welt-python/model-runs.html) task payloads for bounded runs. --- # What Does 70% Mean? How to Score a Probabilistic Prediction Page: https://ergodic.dev/library/articles/what-seventy-percent-means A single 70% forecast can't be graded. A set of them can. The Brier score measures squared distance from what happened, and log loss punishes confident misses hard. Calibration asks whether your 70%s happen 70% of the time. Always compare with a baseline, because a forecaster can be calibrated and still useless. ## A forecast you can't grade on its own A forecaster says there's a 70% chance a bill passes. It fails. Was the forecaster wrong? Not on that result alone. A 70% forecast says that in situations like this one, the thing happens about seven times in ten. One outcome can't tell you much. Many outcomes can. That's the whole idea behind proper scoring rules. You collect a forecaster's probabilities and what happened, and you compute a number that rewards honest probabilities. "Proper" means the forecaster gets the best expected score by reporting what they believe. Shading a 70% up to 90% to sound decisive makes the expected score worse. ## The Brier score Definition: for each forecast, take the probability given to the event, subtract the outcome (1 if it happened, 0 if it didn't), and square the result. Average across all forecasts. Lower is better. Zero is perfect. Worked example. Forecaster A makes ten forecasts, all at 70%, and seven of the events happen. For each of the seven that happened, the error is 0.7 minus 1, which is -0.3. Squared, that's 0.09. For each of the three that didn't, the error is 0.7 minus 0, which is 0.7. Squared, that's 0.49. Total: 7 x 0.09 = 0.63, plus 3 x 0.49 = 1.47, gives 2.10. Divide by ten forecasts. Forecaster A's Brier score is 0.21. Is 0.21 good? That depends on the comparison. Someone who says 50% on everything scores 0.25 every time, because 0.5 squared is 0.25 whichever way it goes. So A beats a coin. Now forecaster B looks at the same ten events and says 90% on the seven that happened and 20% on the three that didn't. The errors are 0.1 squared (0.01) seven times and 0.2 squared (0.04) three times. That's 0.07 plus 0.12, or 0.19, divided by ten: a Brier score of 0.019. B wins because A said the same number for every event and B told the events apart. ## The baseline that catches lazy forecasts Here's the trap in forecaster A. Seven of the ten events happened, so the base rate was 70%. Anyone who knew the base rate and said 70% every time would score exactly 0.21, the same as A. A added nothing beyond the base rate. So a score is only meaningful next to a baseline. The usual one is the base rate itself, sometimes called climatology after weather forecasting, where it began. A forecaster earns credit only for beating it. Welt's evaluations build this in: every leaderboard ends with a baseline that predicts the training fold's class shares, and the warnings list any model that doesn't beat it. ## Log loss Definition: for each forecast, take the probability given to what happened, and take its negative natural log. Average across forecasts. Lower is better. For forecaster A, the probability on the outcome was 0.7 seven times and 0.3 three times. The negative log of 0.7 is 0.357, and of 0.3 is 1.204. That's 7 x 0.357 = 2.497, plus 3 x 1.204 = 3.612, giving 6.109 across ten forecasts, or 0.611 each. A coin-flipper scores the negative log of 0.5, which is 0.693. The two scores usually agree. They part ways on confident misses. Say 99% on something that doesn't happen. The Brier penalty is 0.99 squared, or 0.98, which is bad but bounded. The log-loss penalty is the negative log of 0.01, or 4.61, more than six times a coin-flipper's. At 100% on a miss, log loss is infinite. If your forecasters are tempted to round 97% up to "certain", log loss is the score that tells them off. ## Calibration and ECE Calibration asks a narrower question: when you say 70%, does it happen about 70% of the time? To check it, group forecasts into bins by probability, then compare each bin's average forecast with how often its events happened. On a calibration plot, a calibrated forecaster's points sit on the diagonal. Expected calibration error (ECE) sums those gaps, weighting each bin by its share of forecasts. Worked example: twenty forecasts. Ten were at 80%, and five of those happened, so that bin's gap is 0.8 minus 0.5, or 0.3. Ten were at 20%, and two happened, so that gap is 0.2 minus 0.2, which is zero. Each bin holds half the forecasts, so ECE = 0.5 x 0.3 + 0.5 x 0 = 0.15. This forecaster's high-confidence calls are badly overconfident, and the low ones are fine. Forecaster A's ECE is zero. Every forecast was 70% and 70% happened. That's the point of the baseline section again: calibration is necessary and nowhere near sufficient. A forecaster can be perfectly calibrated by saying the base rate every time. Kalshi's research team published a calibration analysis of 2.24 million of its markets, reporting a Brier score that falls from about 0.08 three months before close to about 0.02 at close ([Kalshi](https://kalshi.com/research/kalshi-research-calibration.pdf)). It's a useful template for how to present calibration. It's also self-published by the exchange, and an independent study has disputed how accurate prediction markets are ([DL News](https://www.dlnews.com/articles/markets/polymarket-kalshi-prediction-markets-not-so-reliable-says-study)). Read both before you quote either. ## Why accuracy alone misleads Accuracy rounds every forecast to yes or no and counts the hits. It throws away the probability, which is the part you were trying to grade. Take an event with a 5% base rate. A forecaster who always says "no" is 95% accurate and has told you nothing. In Brier terms, someone who always says 5% scores 0.0475 (0.05 x 0.95 squared, plus 0.95 x 0.05 squared), and that number only looks good until you notice it's the baseline. Accuracy also can't tell a 51% forecast from a 99% one. Both round to "yes". ## Common misreadings "The forecast said 70% and it didn't happen, so the model failed." One outcome can't grade a probability. Look at the record. "A Brier score of 0.19 beats 0.21, so that forecaster is better." Only if they forecast the same events. Scores on different question sets aren't comparable, because some sets are easier. Compare on the shared questions. "One forecaster beat another by 0.002, so they're the better forecaster." Maybe not. Small differences sit inside the noise of which questions happened to resolve which way. Put an interval on the difference, by bootstrapping over questions, before you call a winner. When the interval includes zero, it's a tie. FRI's ForecastBench write-ups report p-values next to every parity claim for this reason ([FRI](https://forecastingresearch.substack.com/p/ai-models-have-likely-reached-parity)). ## How to compute it For your own forecasts, you need nothing beyond pandas. With a column of probabilities `p` and a column of outcomes `y` (1 or 0): ``` import numpy as np import pandas as pd df = pd.read_csv("my_forecasts.csv") # columns: p, y brier = ((df.p - df.y) ** 2).mean() eps = 1e-15 # avoid log(0) p = df.p.clip(eps, 1 - eps) log_loss = -(df.y * np.log(p) + (1 - df.y) * np.log(1 - p)).mean() baseline = ((df.y.mean() - df.y) ** 2).mean() # always say the base rate print(brier, log_loss, baseline) ``` When you're comparing models that make probabilistic predictions on a table, Welt's `client.evaluate` reports these scores for you. For classification it returns `brier`, `log_loss` and `ece` with `roc_auc`, `accuracy` and others, as a mean and standard deviation across folds in `summary()`, and fold by fold in `folds()`. Every model gets the same seeded folds, and a row is never predicted by a model that has seen it. `evaluation.comparison` says whether the top two models are separated or tied within fold-to-fold variation. Two limits apply. Welt's evaluations don't support time-ordered splits yet, so they shuffle rows into folds. For questions that resolve over time, that isn't a forward-looking track record. And a model's native probabilities aren't calibrated just because they're probabilities. ECE is how you find out. ## Try it ``` pip install "welt-client[parquet]" ``` Then follow [Compare models with cross-validation](https://ergodic-ai.github.io/welt-python/evaluations.html) to run `client.evaluate` on your own table and read `brier`, `log_loss` and `ece` per fold. ## FAQ ### Which score should I report? Report Brier, because readers know it and it's bounded. Add log loss if overconfidence is a concern, and a calibration plot whenever you have more than a few dozen forecasts. Always print the baseline next to them. ### Is a Brier score of 0.1 good? It depends on the questions. On events with a 50% base rate it's strong. On events with a 2% base rate, the baseline alone scores about 0.02, so 0.1 is poor. ### Can Welt score forecasts I made by hand? No. Welt's evaluations score models it runs on your table. For hand-made or published forecasts, use the pandas lines above. --- # Small Tables, Real Decisions: A Brief for Public-Sector Analysts Page: https://ergodic.dev/library/articles/policy-brief-small-tables Public-sector questions often come with a few hundred rows, one per local authority or month. A new class of models can predict from tables that small without a training project, and a related class proposes which variables drive which. Neither replaces judgement. Both need documenting, with the uncertainty shown and a named person accountable for the decision. ## What these models do A tabular foundation model is pretrained before it sees your data. You give it your table as context, and it predicts the rows you ask about, with no model-building project in between. Welt runs several from different labs, including TabICLv2 (Inria), Mitra-v2 (Amazon) and TabDPT 1.3. Each is qualified for specific table sizes. TabDPT 1.3, for instance, takes up to 500 rows and 20 columns as context, and TabICLv2 up to 8,000 rows and 20 columns (catalogue, 17 Oct 2026). Small tables are where this matters. A table of 300 local authorities is too small for many conventional machine-learning workflows to be tuned reliably, and it's the size of table a policy team has. The honest position is that these models sometimes beat a well-built regression on small data and sometimes don't. The only way to know is to test them on your table, against a plain baseline, with rows the model hasn't seen. Welt's evaluation does that and reports when a model fails to beat the baseline. For time series, such as monthly referrals or weekly admissions, forecasting models (Chronos-2 from Amazon and Timestral from Mistral AI) return a central forecast with a range. That range is the model's own estimate. It isn't a calibrated interval, so check its coverage on your own past data before you rely on it. ## Where causal discovery helps Prediction answers "what will happen if things carry on". Policy asks "what happens if we change X". Those are different questions, and a model that predicts well can give the wrong answer to the second one. Causal discovery models propose a graph of which variables plausibly affect which, from observational data. That graph is a hypothesis. It's useful for making assumptions visible and for arguing about them with subject experts, who will spot an arrow that runs the wrong way. The open-source Ergodic package then checks whether the graph can answer a specific "what if" question and estimates the effect with an interval. If an important common cause isn't in the data, no method can fix that, and the brief to ministers should say so. ## Human oversight The UK government's AI Playbook sets out 10 principles for using AI, including meaningful human control ([Burges Salmon](https://www.burges-salmon.com/articles/102jzoi/artificial-intelligence-playbook-for-the-uk-government-published/)). For small-table work, oversight means a named analyst reviews every model output before it informs a decision, with the power to discard it. It also means the analyst can see how the model was tested and how it did against the baseline. ## Document it The Algorithmic Transparency Recording Standard (ATRS) is mandatory for tools that significantly influence decisions ([techUK](https://www.techuk.org/resource/launch-of-the-algorithmic-transparency-recording-standard-hub.html)). Even where it isn't required, an ATRS-style record keeps a small project honest. A template: | Field | What to write | |---|---| | Name and owner | Tool name, team, senior responsible owner, contact | | Purpose | The decision it informs, in one sentence, and the decision it must not make | | Human role | Who reviews outputs, and when they can override or discard them | | Data | Source tables, dates, row count, known gaps, personal data (yes or no) | | Model | Model name, provider and version, as recorded by the service | | Testing | Validation method, folds or holdout, baseline used, scores with spread | | Uncertainty | How ranges are shown, and whether their coverage was checked | | Causal claims | Any graph used and who reviewed it | | Risks | Known failure cases, groups the data under-represents | | Review date | When the record and the model's performance are next checked | ## Showing uncertainty doesn't cost trust Analysts often fear that a range makes a forecast look weak. The evidence points the other way. An experiment on UK GDP communication found that showing intervals improved the public's understanding and didn't reduce trust ([CEPR DP16417](https://causalclaims.trfetzer.com/paper/DP16417.html)). Show the range on every chart. Say in words what it does and doesn't mean. ## What not to do Don't use these models to make automated decisions about individuals, such as eligibility, risk scores for a person or prioritising one family over another. Small-table models in public policy belong at the level of areas, services and time periods, informing human planning. Don't present a discovered graph as "the cause". Don't quote a single accuracy figure without the baseline. Don't validate a forecast by shuffling months into random folds. Welt's evaluations don't support time-ordered splits yet, so test forecasts on a held-out later period yourself. ## Questions to ask before you procure an AI forecast 1. Which model and version is it, and will you tell us when it changes? 2. Was it tested on our data, with rows it hadn't seen, against a simple baseline? Can we see the scores and their spread? 3. If the data has a time order, was it tested on a later period than it learned from? 4. Are the ranges calibrated, and how was their coverage checked? 5. Is any claim about causes based on a graph that a domain expert has reviewed, and are its assumptions written down? 6. Will any output be used to decide something about an individual? 7. Who in our team can override the output, and how is that recorded? 8. Can we keep the evaluation report, and rerun it ourselves next year? 9. Where is our data processed and stored, and how do we delete it? ## Try it ``` pip install "welt-client[parquet]" ``` Start with [Compare models with cross-validation](https://ergodic-ai.github.io/welt-python/evaluations.html) on a public table such as the English Indices of Deprivation, and keep the HTML report as your testing record. For a working session on your own question,. --- # Will This Customer Churn? Page: https://ergodic.dev/use-cases/will-this-customer-churn.html Which of your customers are about to cancel, and how likely is each one to go? A retention team can only call so many people a week, so it needs the list ranked by risk, with a probability next to each name. ## The table The IBM Telco churn table has 7,043 customers and 19 columns about each one: how long they've been a customer, their contract, what they pay, which services they use. The last column, Churn, says whether they left. Some cells are text and a few are blank, and Welt takes both as they are. ## Walkthrough 1. ### Load the table Read the public CSV and drop the ID column, which tells a model nothing about churn. ``` import pandas as pd from welt import Client url = "https://raw.githubusercontent.com/IBM/telco-customer-churn-on-icp4d/master/data/Telco-Customer-Churn.csv" customers = pd.read_csv(url).drop(columns="customerID") customers["TotalCharges"] = pd.to_numeric(customers["TotalCharges"], errors="coerce") print(customers.shape, customers["Churn"].value_counts().to_dict()) ``` 2. ### Pick the customers Set aside 20 customers to score at the end, and keep the rest for the models to learn from. ``` new_rows = customers.sample(20, random_state=1) table = customers.drop(new_rows.index) ``` 3. ### Compare the models and score TabICLv2 and Kumo Tabular Medium compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each customer's chance of leaving next to what they did. ``` with Client() as client: evaluation = client.evaluate(table, "Churn", task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns="Churn") print(pd.DataFrame({"actual": new_rows["Churn"].values, "chance of leaving": model.predict_proba(features)[:, 1]})) ``` ## What you get **A ranked call list**: Every customer has a probability of leaving, highest first. **The right model for this table**: The leaderboard shows which model won and whether it beat the runner-up by more than chance. **A report to share**: evaluation.report_link() gives a link your manager can open without an account. ## Try it Use Open with to run the evaluation notebook in Colab, Kaggle or Jupyter, or paste the code above into your own notebook after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Customers - **Question:** Will This Customer Churn? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** IBM Telco customer churn, 7,043 customers - **For:** Data scientists and retention teams - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/evaluation.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/evaluation.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/evaluation.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-evaluation.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Customers - [How Much Will Each Store Sell in the Next Two Weeks?](https://ergodic.dev/use-cases/how-much-will-we-sell.html) - [How Many Will This Machine Sell Today?](https://ergodic.dev/use-cases/machine-product-sales.html) - [Is This Client a Restaurant or a Shop?](https://ergodic.dev/use-cases/wholesale-client-type.html) - [What Should This Camera Cost?](https://ergodic.dev/use-cases/camera-price.html) - [What Should This Car Cost?](https://ergodic.dev/use-cases/car-price.html) --- # How Much Will Each Store Sell in the Next Two Weeks? Page: https://ergodic.dev/use-cases/how-much-will-we-sell.html How much stock should each store order for the next fortnight? Order too little and shelves go empty at the weekend. Order too much and cash sits in the stockroom. A planner needs a number for each store and each day, and a sense of how wrong it could be. ## The table One row per store per day: the date, the store and the units sold. The walkthrough builds a year of daily sales for three stores so it runs anywhere. Swap in your own history with the same three columns. ## Walkthrough 1. ### Get the history A year of daily sales for three stores, busier at weekends. ``` import numpy as np import pandas as pd rng = np.random.default_rng(0) days = pd.date_range("2025-01-01", periods=365, freq="D") history = pd.concat([pd.DataFrame({ "date": days, "store": store, "sales": level * (1 + 0.3 * (days.dayofweek >= 5)) + rng.normal(0, 5, len(days)), }) for store, level in {"north": 120, "south": 90, "east": 60}.items()], ignore_index=True) ``` 2. ### Forecast every store at once Chronos-2 reads all three series in one request. ``` from welt import Forecast model = Forecast(model="chronos-2").fit(history, time="date", id="store", target=["sales"]) result = model.forecast(14, quantile_levels=[0.1, 0.5, 0.9]) ``` 3. ### Read the plan and its range The median is the plan. The 10% and 90% columns show a low and a high day to plan stock around. ``` plan = result.to_frame() print(plan[["id", "timestamp", "median", "q_0.1", "q_0.9"]].head(14)) ``` ## What you get **A daily plan per store**: Fourteen days for each store, from one request. **A range for every day**: Order for the middle and keep safety stock for the high end. **Room for what you already know**: Add bank holidays or promotions as known-future columns and the forecast uses them. ## Try it Use Open with to run the forecasting notebook in Colab, Kaggle or Jupyter, or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Customers - **Question:** How Much Will Each Store Sell in the Next Two Weeks? - **Model:** Chronos-2 - **Data:** A year of daily sales for three stores, built in the notebook - **For:** Planners and operations analysts - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/forecasting-with-covariates.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/forecasting-with-covariates.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/forecasting-with-covariates.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-forecasting-with-covariates.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Customers - [Will This Customer Churn?](https://ergodic.dev/use-cases/will-this-customer-churn.html) - [How Many Will This Machine Sell Today?](https://ergodic.dev/use-cases/machine-product-sales.html) - [Is This Client a Restaurant or a Shop?](https://ergodic.dev/use-cases/wholesale-client-type.html) - [What Should This Camera Cost?](https://ergodic.dev/use-cases/camera-price.html) - [What Should This Car Cost?](https://ergodic.dev/use-cases/car-price.html) --- # How Many Will This Machine Sell Today? Page: https://ergodic.dev/use-cases/machine-product-sales.html Given the day, the weather, holidays, the temperature and whether the product was in stock, how many will sell from this machine? Restocking to the forecast avoids empty slots and wasted trips. ## The table Daily product sales from machines with calendar, weather, holiday, temperature and availability columns. It's in Welt's research catalogue as Sales Dataset, 10,738 rows by 15 columns, licensed CC0. The catalogue measures its signal at 0.69. At 10,738 rows and 14 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="sales dataset machine weather holiday", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A sales estimate**: Per product and day. **Smarter restocking**: Fill the machines that will run out first. **A clear signal**: The catalogue measures a good signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "sales dataset machine weather holiday", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Customers - **Question:** How Many Will This Machine Sell Today? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Sales Dataset, 10,738 rows - **For:** Retail and vending operators - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Customers - [Will This Customer Churn?](https://ergodic.dev/use-cases/will-this-customer-churn.html) - [How Much Will Each Store Sell in the Next Two Weeks?](https://ergodic.dev/use-cases/how-much-will-we-sell.html) - [Is This Client a Restaurant or a Shop?](https://ergodic.dev/use-cases/wholesale-client-type.html) - [What Should This Camera Cost?](https://ergodic.dev/use-cases/camera-price.html) - [What Should This Car Cost?](https://ergodic.dev/use-cases/car-price.html) --- # Is This Client a Restaurant or a Shop? Page: https://ergodic.dev/use-cases/wholesale-client-type.html From a year of spending on fresh food, milk, groceries, frozen goods, detergents and delicatessen, is this client a hotel or restaurant, or a retailer? Getting the channel right decides which sales team calls. ## The table 440 clients of a Portuguese wholesaler with annual spending by product category and region, labelled Horeca or Retail. It's in Welt's research catalogue as Wholesale Customers Annual Spending, 440 rows by 9 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.83. At 440 rows and 8 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="wholesale customers annual spending", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A channel per client**: With a probability. **Better targeting**: Route each client to the right team. **Small data handled**: 440 rows suit every model in the collection. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "wholesale customers annual spending", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Customers - **Question:** Is This Client a Restaurant or a Shop? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Wholesale Customers Annual Spending, 440 rows - **For:** Wholesale sales teams and marketing analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Customers - [Will This Customer Churn?](https://ergodic.dev/use-cases/will-this-customer-churn.html) - [How Much Will Each Store Sell in the Next Two Weeks?](https://ergodic.dev/use-cases/how-much-will-we-sell.html) - [How Many Will This Machine Sell Today?](https://ergodic.dev/use-cases/machine-product-sales.html) - [What Should This Camera Cost?](https://ergodic.dev/use-cases/camera-price.html) - [What Should This Car Cost?](https://ergodic.dev/use-cases/car-price.html) --- # What Should This Camera Cost? Page: https://ergodic.dev/use-cases/camera-price.html From its release year, resolution, zoom, focus range, storage, weight and size, what price does this camera's spec suggest? Buyers use a fair-price estimate to spot bargains and overpriced stock. ## The table 1,038 camera models with release year, resolution, zoom, focus range, storage, weight and dimensions, and their price. It's in Welt's research catalogue as 1000 Cameras Dataset, 1,038 rows by 13 columns, licensed CC BY-SA 3.0. The catalogue measures its signal at 0.52. At 1,038 rows and 12 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="1000 cameras", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A fair price**: For any camera spec. **Over- and under-priced models**: Compare the estimate with the list price. **Small data handled**: About a thousand rows fit without sampling. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "1000 cameras", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Customers - **Question:** What Should This Camera Cost? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** 1000 Cameras Dataset, 1,038 rows - **For:** Retail buyers and pricing analysts - **Licence:** CC BY-SA 3.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Customers - [Will This Customer Churn?](https://ergodic.dev/use-cases/will-this-customer-churn.html) - [How Much Will Each Store Sell in the Next Two Weeks?](https://ergodic.dev/use-cases/how-much-will-we-sell.html) - [How Many Will This Machine Sell Today?](https://ergodic.dev/use-cases/machine-product-sales.html) - [Is This Client a Restaurant or a Shop?](https://ergodic.dev/use-cases/wholesale-client-type.html) - [What Should This Car Cost?](https://ergodic.dev/use-cases/car-price.html) --- # What Should This Car Cost? Page: https://ergodic.dev/use-cases/car-price.html From its make, body style, dimensions, engine and fuel economy, what price does this car's spec suggest? With only 201 cars and 68 columns, it shows how foundation models handle small, wide tables. ## The table 201 cars with make, body style, dimensions, engine size, horsepower and fuel economy, and their list price. It's in Welt's research catalogue as Automobile Specifications and Prices, Fixed Version, 201 rows by 69 columns, licensed CC0. The catalogue measures its signal at 0.87. At 201 rows and 68 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="automobile specifications prices", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A fair price**: For any car's spec. **Small, wide data handled**: 201 rows and 68 features, no tuning. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "automobile specifications prices", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Customers - **Question:** What Should This Car Cost? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Automobile Specifications and Prices, Fixed Version, 201 rows - **For:** Car dealers, buyers and pricing analysts - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Customers - [Will This Customer Churn?](https://ergodic.dev/use-cases/will-this-customer-churn.html) - [How Much Will Each Store Sell in the Next Two Weeks?](https://ergodic.dev/use-cases/how-much-will-we-sell.html) - [How Many Will This Machine Sell Today?](https://ergodic.dev/use-cases/machine-product-sales.html) - [Is This Client a Restaurant or a Shop?](https://ergodic.dev/use-cases/wholesale-client-type.html) - [What Should This Camera Cost?](https://ergodic.dev/use-cases/camera-price.html) --- # Which Credit Score Band Is This Customer In? Page: https://ergodic.dev/use-cases/credit-score-band.html From income, accounts, loans, payment delays and debt, is this customer's credit score poor, standard or good? A consistent band helps a lender decide who to offer what. ## The table Customer records with income, number of accounts and cards, loans, payment delays and outstanding debt, and a credit score band. It's in Welt's research catalogue as Credit Score Classification, 100,000 rows by 28 columns, licensed CC0. The catalogue measures its signal at 0.46. At 100,000 rows and 27 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="credit score classification", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A band per customer**: Poor, standard or good, with a probability. **Consistent decisions**: The same method for every applicant. **Large tables handled**: A seeded sample keeps the run within the model limits. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "credit score classification", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Which Credit Score Band Is This Customer In? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Credit Score Classification, 100,000 rows - **For:** Credit analysts and lenders - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) - [Will This Company Go Bankrupt Within Three Years?](https://ergodic.dev/use-cases/company-bankruptcy.html) --- # What Credit Rating Will This Company Get? Page: https://ergodic.dev/use-cases/corporate-credit-rating.html From a handful of financial ratios and its size, which rating class is this company likely to get? An early estimate shows a treasurer where a firm stands before the agencies decide. ## The table 5,000 companies with financial ratios and size and the credit rating class each one holds. It's in Welt's research catalogue as Multiclass Classification for Corporate Credit Ratings, 5,000 rows by 8 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.78. At 5,000 rows and 7 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="multiclass classification corporate credit ratings", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A rating per company**: With a probability for each class. **Before the agencies**: An estimate ahead of a formal rating. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "multiclass classification corporate credit ratings", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What Credit Rating Will This Company Get? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Multiclass Classification for Corporate Credit Ratings, 5,000 rows - **For:** Credit analysts and corporate treasurers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) - [Will This Company Go Bankrupt Within Three Years?](https://ergodic.dev/use-cases/company-bankruptcy.html) --- # Will This Small-Business Loan Be Repaid? Page: https://ergodic.dev/use-cases/sba-loan-default.html From the bank, the industry, the term, the jobs supported and the government guarantee, will this SBA-backed loan default? Lenders and the agency both carry the risk. ## The table 2,102 Small Business Administration loans in California with borrower, bank, industry, term, jobs and guarantee details, and whether the loan was repaid. It's in Welt's research catalogue as SBA Small Business Loan Outcomes, California, 2,102 rows by 35 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.88. At 2,102 rows and 34 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="SBA small business loan California", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A default probability**: For every loan in the book. **Risk by industry**: See where defaults cluster. **A strong signal**: The catalogue measures one of its highest signals. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "SBA small business loan California", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Will This Small-Business Loan Be Repaid? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** SBA Small Business Loan Outcomes, California, 2,102 rows - **For:** Lenders and small-business finance analysts - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) - [Will This Company Go Bankrupt Within Three Years?](https://ergodic.dev/use-cases/company-bankruptcy.html) --- # Will This Home-Equity Loan Default? Page: https://ergodic.dev/use-cases/home-equity-default.html From the loan amount, the property value, the borrower's job and their credit history, will this home-equity loan go bad? It's the standard teaching table for credit scoring. ## The table 5,960 home-equity loans with loan and property values, job, years in job, delinquencies, credit lines and debt-to-income ratio, and whether the loan defaulted. It's in Welt's research catalogue as HMEQ Loan Default Data, 5,960 rows by 21 columns, licensed Public. The catalogue measures its signal at 0.66. At 5,960 rows and 20 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="HMEQ loan default", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A default probability**: Per loan, with calibration you can check. **Missing values handled**: Gaps in credit history go in as they are. **A teaching benchmark**: Compare with the many published scorecards. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "HMEQ loan default", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Will This Home-Equity Loan Default? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** HMEQ Loan Default Data, 5,960 rows - **For:** Credit risk analysts - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) - [Will This Company Go Bankrupt Within Three Years?](https://ergodic.dev/use-cases/company-bankruptcy.html) --- # Will This Personal Loan Be Paid Back? Page: https://ergodic.dev/use-cases/personal-loan-default.html From the loan's purpose, grade, amount and rate and the borrower's income and employment, will it default? A good score lets a lender price risk rather than refuse it. ## The table 32,581 personal loans with purpose, grade, amount, interest rate, income, home ownership and length of employment, and whether the loan defaulted. It's in Welt's research catalogue as Credit Risk Dataset, 32,581 rows by 12 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.71. At 32,581 rows and 11 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="credit risk dataset", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A default probability**: For each application. **Risk-based pricing**: Set rates from the predicted risk. **A clear signal**: The catalogue measures a good signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "credit risk dataset", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Will This Personal Loan Be Paid Back? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Credit Risk Dataset, 32,581 rows - **For:** Lenders and credit risk analysts - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) - [Will This Company Go Bankrupt Within Three Years?](https://ergodic.dev/use-cases/company-bankruptcy.html) --- # Which Risk Grade Will the Bank Give This Loan? Page: https://ergodic.dev/use-cases/bank-loan-risk-grade.html From the loan, its guarantee and collateral and the household's finances, which of five risk grades does the bank assign? Predicting the grade helps check that grading is consistent across branches. ## The table Bank loans in China with loan terms, guarantees, collateral and household attributes, and the bank's five-category risk grade. It's in Welt's research catalogue as Credit Risk China, 27,522 rows by 28 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.28. At 27,522 rows and 27 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="credit risk China", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A grade per loan**: With a probability for each grade. **Consistency checks**: Loans graded far from the prediction stand out. **An honest signal**: The catalogue measures a weak signal, so read the baseline comparison. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "credit risk China", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Which Risk Grade Will the Bank Give This Loan? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Credit Risk China, 27,522 rows - **For:** Bank risk teams and credit analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Will This Company Go Bankrupt Within Three Years?](https://ergodic.dev/use-cases/company-bankruptcy.html) --- # Will This Company Go Bankrupt Within Three Years? Page: https://ergodic.dev/use-cases/company-bankruptcy.html From 64 financial ratios in its accounts, will this Polish company go bankrupt in the next three years? Spotting distress early protects lenders, suppliers and staff. ## The table 10,503 Polish companies with 64 financial ratios from their accounts and whether each went bankrupt within three years. It's in Welt's research catalogue as Polish Companies Bankruptcy, Three-Year Horizon, 10,503 rows by 65 columns, licensed CC0. The catalogue measures its signal at 0.30. At 10,503 rows and 64 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Polish companies bankruptcy three-year", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A bankruptcy probability**: For every company in the table. **Wide tables handled**: All 64 ratios go in without selection. **An honest signal**: Bankruptcy is rare and hard to predict, and the score says how hard. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Polish companies bankruptcy three-year", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Will This Company Go Bankrupt Within Three Years? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Polish Companies Bankruptcy, Three-Year Horizon, 10,503 rows - **For:** Credit analysts, auditors and investors - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # Should the Auditors Look at This Firm? Page: https://ergodic.dev/use-cases/audit-risk-firm.html From its sector, location, the discrepancies found and its history, is this firm high-risk? Audit offices have more firms than inspectors, so they need to choose. ## The table Firms reviewed by an Indian audit office, with sector, location, discrepancy amounts and history scores, labelled high-risk or not. It's in Welt's research catalogue as Audit Data Fraudulent Firm Classification, 1,552 rows by 37 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.60. At 1,552 rows and 36 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="audit data fraudulent firm", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A risk score per firm**: Rank firms for inspection. **Better use of auditors**: Visit the likely cases first. **A clear signal**: The catalogue measures a good signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "audit data fraudulent firm", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Should the Auditors Look at This Firm? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Audit Data Fraudulent Firm Classification, 1,552 rows - **For:** Auditors and public-sector finance teams - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # Where Could Bitcoin's Price Go in the Next Two Weeks? Page: https://ergodic.dev/use-cases/crypto-price-forecast.html From each coin's daily closing price, what range could Bitcoin, Ethereum and Litecoin trade in over the next 14 days? The width of the range matters more than the middle line. ## The table Daily closing prices and trading volume for the top 100 cryptocurrencies in 2020. It's in Welt's research catalogue as Top 100 Cryptocurrency Daily Market Prices 2020, 40,100 rows by 9 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.55, in time order. Chronos-2 forecasts the 3 series named below in one request and needs no training. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client, Forecast with Client() as client: item = client.research_datasets(q="top 100 cryptocurrency 2020", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the history Keep the time column and the target, for the series you want. ``` time, series = "date", "name" history = data[data[series].isin(["Bitcoin", "Ethereum", "Litecoin"])][[series, time, target]].dropna() history[time] = pd.to_datetime(history[time]) ``` 3. ### Forecast with a range Ask for the next 14 steps, one per day. The median is the forecast, and the 10% and 90% columns give a low and a high case. ``` model = Forecast(model="chronos-2").fit(history, time=time, id=series, target=[target]) result = model.forecast(14, quantile_levels=[0.1, 0.5, 0.9]) print(result.to_frame()[["id", "timestamp", "median", "q_0.1", "q_0.9"]].head(14)) ``` ## What you get **Two weeks ahead**: A daily range for each coin. **Risk in plain sight**: The gap between the 10% and 90% lines shows how volatile each coin is. **Several coins at once**: One request covers all three. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "top 100 cryptocurrency 2020", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Where Could Bitcoin's Price Go in the Next Two Weeks? - **Model:** Chronos-2 - **Data:** Top 100 Cryptocurrency Daily Market Prices 2020, 40,100 rows - **For:** Crypto analysts and finance students - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # Will US Unemployment Be Higher in Three Months? Page: https://ergodic.dev/use-cases/will-unemployment-rise.html Forecasting tournaments and prediction markets ask questions like this every week: will a public number be above its latest value on a given date? Answering well means putting a probability on it, and a probability needs a forecast with a range, not a single guess. ## The table The US civilian unemployment rate from FRED: one row per month since January 1948, about 945 rows, with two columns, the date and the rate. It's free to download with no account. ## Walkthrough 1. ### Download the series Read FRED's CSV straight into pandas. ``` import pandas as pd url = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=UNRATE" rate = pd.read_csv(url, parse_dates=["observation_date"]) ``` 2. ### Forecast three months with a range Ask Chronos-2 for several quantiles, so you can see the whole spread of outcomes. ``` from welt import Forecast levels = [0.05, 0.1, 0.5, 0.9, 0.95] model = Forecast(model="chronos-2").fit( rate, time="observation_date", target=["UNRATE"], frequency="MS") month3 = model.forecast(3, quantile_levels=levels).to_frame().iloc[-1] ``` 3. ### Turn the range into a probability Find where today's rate falls inside the forecast's spread. The share of outcomes above it is the probability of "higher". ``` import numpy as np today = rate["UNRATE"].iloc[-1] values = [month3[f"q_{q}"] for q in levels] p_higher = 1 - np.interp(today, values, levels) print(f"Chance unemployment is higher in three months: {p_higher:.0%}") ``` ## What you get **A probability for the question**: Ready to submit, trade on or report. **The reasoning behind it**: The forecast's range shows how much the number could move. **A repeatable method**: The same three steps answer any question about a public series. ## Try it Use Open with to run the forecasting notebook in Colab, Kaggle or Jupyter and swap in the FRED series, or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** Will US Unemployment Be Higher in Three Months? - **Model:** Chronos-2 - **Data:** FRED civilian unemployment rate (UNRATE), monthly since 1948 - **For:** Forecasters, prediction-market traders and journalists - **Licence:** Public domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/forecasting-with-covariates.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/forecasting-with-covariates.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/forecasting-with-covariates.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-forecasting-with-covariates.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # What Will This Bengaluru Home Sell For? Page: https://ergodic.dev/use-cases/bengaluru-home-price.html Given the area type, location, size, square footage, bathrooms and balconies, what's a fair price? Agents and buyers want a quick, consistent estimate before they negotiate. ## The table 13,320 listings from Bengaluru with seven columns about each home and the listed price. It's in Welt's research catalogue as Bengaluru Real Estate Prices, 13,320 rows by 8 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.47. At 13,320 rows and 7 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="bengaluru real estate prices", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A fair-price estimate**: A price for any listing in seconds. **Over- and under-priced homes**: Compare the estimate with the asking price. **Consistent valuations**: The same method for every home on the market. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "bengaluru real estate prices", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What Will This Bengaluru Home Sell For? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Bengaluru Real Estate Prices, 13,320 rows - **For:** Property analysts, agents and buyers - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # What's a Fair Rent for This Munich Flat? Page: https://ergodic.dev/use-cases/munich-rent.html From living area, year built, location, bathroom, kitchen, heating and district, what net rent does this flat command? Munich's rent index is built from exactly this kind of table. ## The table 3,082 Munich flats from the 1999 rent index survey with size, year built, location quality, fittings and district, and the net rent. It's in Welt's research catalogue as Munich Rent Index (1999) Apartments, 3,082 rows by 9 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.45. At 3,082 rows and 8 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Munich rent index", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A rent estimate**: For any flat in the table. **Above or below the index**: Compare the estimate with the rent charged. **A well-known table**: Used in statistics teaching for decades. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Munich rent index", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What's a Fair Rent for This Munich Flat? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Munich Rent Index (1999) Apartments, 3,082 rows - **For:** Tenants, landlords and housing analysts - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # What's a Typical Home Worth in This California Neighbourhood? Page: https://ergodic.dev/use-cases/california-house-value.html From income, housing age, rooms, population and location, what is the median house value in this block group? It's the 1990 census table that most data scientists meet first. ## The table 20,640 California census block groups with median income, housing age, rooms, bedrooms, population, households and coordinates, and the median house value. It's in Welt's research catalogue as Houses, 20,640 rows by 9 columns, licensed MIT (PMLB collection). The catalogue measures its signal at 0.78. At 20,640 rows and 8 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="houses California median value", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A value per neighbourhood**: From census figures alone. **Where location matters**: See how much coordinates add. **A classic benchmark**: Compare with countless published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "houses California median value", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What's a Typical Home Worth in This California Neighbourhood? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Houses, 20,640 rows - **For:** Housing analysts, planners and students - **Licence:** MIT (PMLB collection) - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # What Property Tax Rate Will This City Charge? Page: https://ergodic.dev/use-cases/property-tax-rate.html From the state, the population, the median home value and household income, what's the effective property tax rate in this US city? Buyers comparing places want the number before they look at houses. ## The table 10,058 US cities with state, population, median home value and median household income, and the effective property tax rate. It's in Welt's research catalogue as US Property Tax Rates 2026 by City, 10,058 rows by 10 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.77. At 10,058 rows and 9 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="US property tax rates 2026 by city", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A rate per city**: For cities in the table and ones like them. **Unusual rates**: Cities far from the estimate stand out. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "US property tax rates 2026 by city", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What Property Tax Rate Will This City Charge? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** US Property Tax Rates 2026 by City, 10,058 rows - **For:** Homebuyers, relocation advisers and local-finance analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # What Should This Riga Flat Be Listed At? Page: https://ergodic.dev/use-cases/riga-flat-price.html From the offer type, district, rooms, area, floor and building type, what's a sensible listing price? A quick estimate helps an agent advise a seller on day one. ## The table 4,219 Riga property listings with offer type, district, street, rooms, area, floor and building series, and the price. It's in Welt's research catalogue as Riga Real Estate Listings, 4,219 rows by 13 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.87. At 4,219 rows and 12 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Riga real estate listings", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A listing price**: For any flat you can describe. **Sale or rent**: The offer type is a column, so one model covers both. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Riga real estate listings", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What Should This Riga Flat Be Listed At? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Riga Real Estate Listings, 4,219 rows - **For:** Estate agents and property investors in the Baltics - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # What's This Dubai Apartment Worth? Page: https://ergodic.dev/use-cases/dubai-apartment-price.html From the neighbourhood, size, rooms and a long list of amenities, what price does this apartment's listing suggest? Investors compare it with the asking price before they bid. ## The table 1,905 Dubai apartment listings with neighbourhood, coordinates, size, bedrooms, bathrooms and amenities such as a pool, gym or sea view, and the price. It's in Welt's research catalogue as Dubai Apartment Properties, 1,905 rows by 37 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.81. At 1,905 rows and 36 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Dubai apartment properties", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A price estimate**: For any listing. **What amenities are worth**: Compare predictions with and without each one. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Dubai apartment properties", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** What's This Dubai Apartment Worth? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Dubai Apartment Properties, 1,905 rows - **For:** Property investors and agents in the Gulf - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # How Much Is a Home Near a Metro Station Worth? Page: https://ergodic.dev/use-cases/taipei-price-per-area.html From the sale date, the building's age, the distance to the nearest MRT station, the number of shops nearby and the location, what's the price per unit area? It puts a number on what living near the metro is worth. ## The table 414 home sales in Sindian District, New Taipei City, with date, house age, distance to the MRT, convenience stores and coordinates, and the price per unit area. It's in Welt's research catalogue as Real Estate Valuation, Sindian District, 414 rows by 7 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.65. At 414 rows and 6 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="real estate valuation Sindian", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A price per area**: For any home in the district. **The metro effect**: See how price falls with distance to the station. **Small data handled**: Every model in the collection can take 414 rows. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "real estate valuation Sindian", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Finance - **Question:** How Much Is a Home Near a Metro Station Worth? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Real Estate Valuation, Sindian District, 414 rows - **For:** Property valuers and transport planners - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Finance - [Which Credit Score Band Is This Customer In?](https://ergodic.dev/use-cases/credit-score-band.html) - [What Credit Rating Will This Company Get?](https://ergodic.dev/use-cases/corporate-credit-rating.html) - [Will This Small-Business Loan Be Repaid?](https://ergodic.dev/use-cases/sba-loan-default.html) - [Will This Home-Equity Loan Default?](https://ergodic.dev/use-cases/home-equity-default.html) - [Will This Personal Loan Be Paid Back?](https://ergodic.dev/use-cases/personal-loan-default.html) - [Which Risk Grade Will the Bank Give This Loan?](https://ergodic.dev/use-cases/bank-loan-risk-grade.html) --- # Is This Patient at Risk of Heart Disease? Page: https://ergodic.dev/use-cases/is-this-patient-at-risk.html A clinic has a few hundred patient records and wants a risk score for each new patient. Small tables are where most models struggle, and a clinician needs to know the score is better than a guess before using it. ## The table The UCI Cleveland heart disease table has 303 patients and 13 measurements each, such as age, cholesterol, resting blood pressure and maximum heart rate. The last column records whether heart disease was found. It's small enough for every prediction model in the collection. ## Walkthrough 1. ### Load the records Read the UCI file, name the columns, and turn the outcome into yes or no. ``` import pandas as pd from welt import Client url = "https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data" cols = ["age", "sex", "cp", "trestbps", "chol", "fbs", "restecg", "thalach", "exang", "oldpeak", "slope", "ca", "thal", "disease"] patients = pd.read_csv(url, names=cols, na_values="?") patients["disease"] = (patients["disease"] > 0).map({True: "yes", False: "no"}) print(patients.shape, patients["disease"].value_counts().to_dict()) ``` 2. ### Pick the patients Set aside 20 patients to score at the end, and keep the rest for the models to learn from. ``` new_rows = patients.sample(20, random_state=1) table = patients.drop(new_rows.index) ``` 3. ### Test all four models and score On a table this small, every prediction model in the collection can take part, and the baseline line shows what a guess would score. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each patient's risk next to their diagnosis. ``` with Client() as client: evaluation = client.evaluate(table, "disease", task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns="disease") print(pd.DataFrame({"actual": new_rows["disease"].values, "risk": model.predict_proba(features)[:, 1]})) ``` ## What you get **A risk score per patient**: A probability, not just a yes or no. **Proof it beats a guess**: Every model is ranked against the baseline on records it never saw. **The right model for small data**: The leaderboard shows which model handles 303 rows best. ## Try it Use Open with to run the evaluation notebook in Colab, Kaggle or Jupyter, or run the code above after `pip install "welt-client[parquet]"`. For a clinical study, report the model using the TRIPOD+AI checklist. - **Type:** Use case - **Area:** Healthcare - **Question:** Is This Patient at Risk of Heart Disease? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** UCI Heart Disease (Cleveland), 303 patients - **For:** Clinical researchers and health data scientists - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/evaluation.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/evaluation.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/evaluation.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-evaluation.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) - [Is This Mammogram Mass Malignant?](https://ergodic.dev/use-cases/mammogram-mass.html) --- # Does This Patient Have Gum Disease? Page: https://ergodic.dev/use-cases/periodontal-diagnosis.html Can lifestyle, hygiene habits and dental indices flag periodontal disease before a full examination? A clinic with a couple of hundred records wants a screening score it can trust. ## The table 224 patients with 19 columns on lifestyle, oral hygiene, dental indices and teeth status, and a periodontal diagnosis. It's in Welt's research catalogue as French Dental and Lifestyle Records, 224 rows by 20 columns, licensed CC0. The catalogue measures its signal at 0.47. At 224 rows and 19 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="french dental lifestyle periodontal", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A screening score**: A probability of gum disease for each patient. **Small data handled**: Foundation models are built for tables this size. **Ready to report**: Leaderboard and calibration figures for a write-up. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "french dental lifestyle periodontal", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Does This Patient Have Gum Disease? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** French Dental and Lifestyle Records, 224 rows - **For:** Dental researchers and clinicians - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) - [Is This Mammogram Mass Malignant?](https://ergodic.dev/use-cases/mammogram-mass.html) --- # Does This Eye Scan Show Diabetic Retinopathy? Page: https://ergodic.dev/use-cases/diabetic-retinopathy.html From features measured on a retinal image, does this patient show signs of diabetic retinopathy? Screening programmes see far more images than specialists can grade by hand. ## The table Retinal images from the Messidor set, each with lesion counts, optic disc and image-quality features, and whether retinopathy was present. It's in Welt's research catalogue as Diabetic Retinopathy Debrecen, 1,151 rows by 20 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.35. At 1,151 rows and 19 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="diabetic retinopathy Debrecen", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per scan**: Send the likely cases to a specialist first. **An honest signal**: The catalogue measures a modest signal, so check the baseline comparison. **Calibrated scores**: The Brier score shows whether the probabilities can be trusted. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "diabetic retinopathy Debrecen", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Does This Eye Scan Show Diabetic Retinopathy? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Diabetic Retinopathy Debrecen, 1,151 rows - **For:** Ophthalmology researchers and screening programmes - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) - [Is This Mammogram Mass Malignant?](https://ergodic.dev/use-cases/mammogram-mass.html) --- # Does This Patient Have an Underactive Thyroid? Page: https://ergodic.dev/use-cases/hypothyroid.html From age, sex, medication history and thyroid test results, does this patient have hypothyroidism? Most tests come back normal, so a score that flags the likely cases saves clinicians time. ## The table Patient records with medication and treatment history and thyroid hormone tests, labelled hypothyroid or not. It's in Welt's research catalogue as Hypothyroid, 3,163 rows by 26 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.70. At 3,163 rows and 25 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="hypothyroid", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per patient**: Flag the cases most likely to need treatment. **Rare cases checked**: The leaderboard shows how the models handle the smaller class. **Missing tests handled**: Records with gaps go in as they are. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "hypothyroid", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Does This Patient Have an Underactive Thyroid? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Hypothyroid, 3,163 rows - **For:** Endocrinology researchers and clinical analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) - [Is This Mammogram Mass Malignant?](https://ergodic.dev/use-cases/mammogram-mass.html) --- # Is This Baby's Heart Trace Healthy? Page: https://ergodic.dev/use-cases/fetal-health.html From the measurements of a cardiotocography trace, is the baby's health normal, suspect or pathological? Midwives read these traces around the clock, and a consistent score helps on a busy night. ## The table 2,126 cardiotocography traces with baseline heart rate, accelerations, decelerations and variability measures, classified by obstetricians. It's in Welt's research catalogue as Cardiotocography (CTG) Fetal Health Dataset, 2,126 rows by 23 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.84. At 2,126 rows and 22 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="cardiotocography fetal health", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A class per trace**: Normal, suspect or pathological, with a probability. **The worrying traces first**: Sort by the chance of a pathological result. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "cardiotocography fetal health", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Is This Baby's Heart Trace Healthy? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Cardiotocography (CTG) Fetal Health Dataset, 2,126 rows - **For:** Obstetric researchers and maternity clinicians - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) - [Is This Mammogram Mass Malignant?](https://ergodic.dev/use-cases/mammogram-mass.html) --- # Is This Breast Biopsy Malignant? Page: https://ergodic.dev/use-cases/breast-cytology.html From nine cell characteristics scored by a pathologist, is this fine-needle biopsy malignant or benign? It's one of the oldest medical tables in machine learning and still a good first test. ## The table 699 biopsies with nine cell features scored from 1 to 10, such as clump thickness and cell size, and a benign or malignant result. It's in Welt's research catalogue as Breast Cancer Wisconsin Cytology Features (Original), 699 rows by 10 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.91. At 699 rows and 9 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="breast cancer Wisconsin original", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per biopsy**: Benign or malignant, with a probability. **A strong signal**: The catalogue measures one of its highest signals here. **A classic benchmark**: Compare with decades of published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "breast cancer Wisconsin original", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Is This Breast Biopsy Malignant? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Breast Cancer Wisconsin Cytology Features (Original), 699 rows - **For:** Pathology researchers and clinicians - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Mammogram Mass Malignant?](https://ergodic.dev/use-cases/mammogram-mass.html) --- # Is This Mammogram Mass Malignant? Page: https://ergodic.dev/use-cases/mammogram-mass.html From the radiologist's BI-RADS assessment, the patient's age and the mass's shape, margin and density, is it malignant? A better estimate could spare some women an unnecessary biopsy. ## The table 961 masses found on mammograms with the BI-RADS score, age, shape, margin and density, and the biopsy result. It's in Welt's research catalogue as Mammographic Mass, 961 rows by 6 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.59. At 961 rows and 5 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="mammographic mass", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A malignancy probability**: For each mass before biopsy. **Fewer unnecessary biopsies**: See how many benign masses fall below a safe threshold. **Calibrated scores**: The Brier score shows how far to trust each probability. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "mammographic mass", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Is This Mammogram Mass Malignant? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Mammographic Mass, 961 rows - **For:** Radiology researchers and screening programmes - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) --- # What Will Medicare Pay for This Hospital Stay? Page: https://ergodic.dev/use-cases/medicare-hospital-payment.html For a given diagnosis group and hospital, what is Medicare's average payment per stay? Hospitals and researchers use the estimate to spot unusual prices and plan budgets. ## The table US hospitals in 2019 with diagnosis group, location, rural or urban status and discharges, and the average Medicare payment. It's in Welt's research catalogue as Medicare Inpatient Hospitals by Provider and Service (2019), 188,806 rows by 13 columns, licensed Public. The catalogue measures its signal at 0.45. At 188,806 rows and 12 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Medicare inpatient hospitals provider service 2019", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A payment estimate**: For any hospital and diagnosis group. **Unusual prices**: Payments far from the estimate stand out. **Text columns handled**: Diagnosis groups and locations go in as they are. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Medicare inpatient hospitals provider service 2019", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** What Will Medicare Pay for This Hospital Stay? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Medicare Inpatient Hospitals by Provider and Service (2019), 188,806 rows - **For:** Health economists and hospital finance teams - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) --- # How Well Will This Person's Kidneys Work in Four Years? Page: https://ergodic.dev/use-cases/kidney-function.html From a 2011 kidney test, blood fat levels, diabetes, blood pressure and lifestyle, what will this person's kidney function be in 2015? Spotting decline early is when treatment works best. ## The table 5,779 adults with kidney function (eGFR) measured in 2011, a blood-fat ratio called AIP, diabetes status, blood pressure and lifestyle, and eGFR again in 2015. It's in Welt's research catalogue as AIP, Cumulative AIP, Type 2 Diabetes and CKD: Complete-Case Analysis, 5,779 rows by 23 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.39. At 5,779 rows and 22 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="AIP cumulative type 2 diabetes CKD", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A four-year estimate**: Kidney function predicted from today's checks. **Who to watch**: Rank people by predicted decline. **An honest signal**: The catalogue measures a modest signal, so read the baseline comparison. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "AIP cumulative type 2 diabetes CKD", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** How Well Will This Person's Kidneys Work in Four Years? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** AIP, Cumulative AIP, Type 2 Diabetes and CKD: Complete-Case Analysis, 5,779 rows - **For:** Nephrology researchers and population health teams - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) --- # How Many COVID-19 Cases Will a Country Report Next Month? Page: https://ergodic.dev/use-cases/covid-cases-forecast.html From each country's daily history, how many new cases will France, Germany and Italy report over the next four weeks? Health services plan beds and staff around a range, not a single number. ## The table Daily COVID-19 cases, deaths, tests and vaccinations for every country, from Our World in Data. It's in Welt's research catalogue as Data on COVID-19 (Coronavirus) Country Statistics, 170,646 rows by 67 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.83, in time order. Chronos-2 forecasts the 3 series named below in one request and needs no training. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client, Forecast with Client() as client: item = client.research_datasets(q="Data on COVID-19 country statistics", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the history Keep the time column and the target, for the series you want. ``` time, series = "date", "location" history = data[data[series].isin(["France", "Germany", "Italy"])][[series, time, target]].dropna() history[time] = pd.to_datetime(history[time]) ``` 3. ### Forecast with a range Ask for the next 28 steps, one per day. The median is the forecast, and the 10% and 90% columns give a low and a high case. ``` model = Forecast(model="chronos-2").fit(history, time=time, id=series, target=[target]) result = model.forecast(28, quantile_levels=[0.1, 0.5, 0.9]) print(result.to_frame()[["id", "timestamp", "median", "q_0.1", "q_0.9"]].head(28)) ``` ## What you get **Four weeks ahead**: Daily cases per country with a range. **Several countries at once**: Chronos-2 reads up to eight series in one request. **Plan for the high case**: The 90% line is the number to staff for. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Data on COVID-19 country statistics", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** How Many COVID-19 Cases Will a Country Report Next Month? - **Model:** Chronos-2 - **Data:** Data on COVID-19 (Coronavirus) Country Statistics, 170,646 rows - **For:** Public-health analysts and data journalists - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) --- # Are This Person's Eyes Open or Closed? Page: https://ergodic.dev/use-cases/eeg-eye-state.html From 14 EEG electrode readings, are the person's eyes open or closed? It's a simple first test for any device that reads the brain. ## The table 14,980 readings from a 14-electrode EEG headset over 117 seconds, labelled with eye state from video. It's in Welt's research catalogue as EEG Eye State, 14,980 rows by 15 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.75. At 14,980 rows and 14 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="EEG eye state", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **Eye state per reading**: Open or closed, with a probability. **A first brain-computer test**: Check a headset's signal quality. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "EEG eye state", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** Are This Person's Eyes Open or Closed? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** EEG Eye State, 14,980 rows - **For:** Neuroscientists and brain-computer interface developers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) --- # How Many COVID-19 Doses Will This Person Have Taken? Page: https://ergodic.dev/use-cases/vaccine-uptake-survey.html Which attitudes and circumstances go with lower vaccine uptake? A model that predicts doses from survey answers shows public-health teams where trust is weakest and outreach would help most. ## The table 31,676 survey responses from Japan covering populist party support, trust in medicine, attitudes to risk and demographics, with the number of COVID-19 doses received. It's in Welt's research catalogue as Populist Party Support, Medical Trust and COVID-19 Vaccine Uptake in Japan Survey, 31,676 rows by 32 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.34. At 31,676 rows and 31 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="populist party support medical trust COVID-19 vaccine Japan", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted uptake**: Estimate doses for groups you didn't survey. **Where to focus**: See which groups the model expects to lag. **A defensible method**: Every score is checked against a baseline on rows the model never saw. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "populist party support medical trust COVID-19 vaccine Japan", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Healthcare - **Question:** How Many COVID-19 Doses Will This Person Have Taken? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Populist Party Support, Medical Trust and COVID-19 Vaccine Uptake in Japan Survey, 31,676 rows - **For:** Public-health researchers and policy analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Healthcare - [Is This Patient at Risk of Heart Disease?](https://ergodic.dev/use-cases/is-this-patient-at-risk.html) - [Does This Patient Have Gum Disease?](https://ergodic.dev/use-cases/periodontal-diagnosis.html) - [Does This Eye Scan Show Diabetic Retinopathy?](https://ergodic.dev/use-cases/diabetic-retinopathy.html) - [Does This Patient Have an Underactive Thyroid?](https://ergodic.dev/use-cases/hypothyroid.html) - [Is This Baby's Heart Trace Healthy?](https://ergodic.dev/use-cases/fetal-health.html) - [Is This Breast Biopsy Malignant?](https://ergodic.dev/use-cases/breast-cytology.html) --- # Is It a Mammal, a Bird or a Fish? Page: https://ergodic.dev/use-cases/zoo-animal-class.html From simple yes-or-no traits like hair, feathers, eggs, milk and number of legs, which class does this animal belong to? It's a friendly first table for seeing how a model reasons from examples. ## The table 101 animals with 16 traits such as hair, feathers, eggs, milk, fins and legs, and their class. It's in Welt's research catalogue as Zoo Animal Types, 101 rows by 17 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.83. At 101 rows and 16 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="zoo animal", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A class per animal**: With a probability for each class. **A tiny table**: Every model in the collection can take 101 rows. **Easy to explain**: Every column is something a child could check. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "zoo animal", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Is It a Mammal, a Bird or a Fish? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Zoo Animal Types, 101 rows - **For:** Teachers, students and anyone new to machine learning - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) - [Which Forest Grows on This Patch of Land?](https://ergodic.dev/use-cases/forest-cover-type.html) --- # Where in the Cell Does This Protein Go? Page: https://ergodic.dev/use-cases/yeast-protein-location.html From eight scores computed from its sequence, which part of the yeast cell does this protein end up in? Knowing where a protein works is a first clue to what it does. ## The table 1,484 yeast proteins with eight sequence-derived signal scores and the cell compartment each is found in. It's in Welt's research catalogue as Yeast Protein Localization, 1,484 rows by 9 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.38. At 1,484 rows and 8 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="yeast protein localization", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A location per protein**: With a probability for each compartment. **Many classes**: Ten locations, all within the collection's limits. **An honest signal**: The catalogue measures a modest signal here. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "yeast protein localization", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Where in the Cell Does This Protein Go? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Yeast Protein Localization, 1,484 rows - **For:** Molecular biologists and bioinformaticians - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) - [Which Forest Grows on This Patch of Land?](https://ergodic.dev/use-cases/forest-cover-type.html) --- # Will This Snail Choose to Mate? Page: https://ergodic.dev/use-cases/snail-mating.html Given the species, populations, shell sizes and trial conditions, will a male periwinkle snail mount the female he's paired with? Who mates with whom is how new species begin to split. ## The table 940 mating trials between Littoraria snails, with species, populations, sizes and conditions, and whether mounting happened. It's in Welt's research catalogue as Assortative Mating and Genital Divergence in Littoraria, 940 rows by 23 columns, licensed CC0. The catalogue measures its signal at 0.35. At 940 rows and 22 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="assortative mating Littoraria", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A mating probability**: For any pairing in the trials. **Size or species**: Compare models to see what drives choice. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "assortative mating Littoraria", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Will This Snail Choose to Mate? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Assortative Mating and Genital Divergence in Littoraria, 940 rows - **For:** Evolutionary biologists and ecologists - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) - [Which Forest Grows on This Patch of Land?](https://ergodic.dev/use-cases/forest-cover-type.html) --- # Will Whooping Cranes Stop Here? Page: https://ergodic.dev/use-cases/whooping-crane-stopover.html From the mix of wetland, cropland and grassland around a spot, will migrating whooping cranes use it as a stopover? There are only a few hundred of these birds in the wild, so protecting the right places matters. ## The table Locations along the cranes' migration route with land-cover composition at several distances and the date, labelled by whether cranes stopped there. It's in Welt's research catalogue as Whooping Crane Stopover Habitat, 30,407 rows by 57 columns, licensed CC0. The catalogue measures its signal at 0.50. At 30,407 rows and 56 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="whooping crane stopover", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A stopover probability**: For any location along the route. **Where to protect**: Rank sites for conservation. **Many features handled**: Land cover at several distances goes in as it is. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "whooping crane stopover", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Will Whooping Cranes Stop Here? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Whooping Crane Stopover Habitat, 30,407 rows - **For:** Conservation biologists and land managers - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) - [Which Forest Grows on This Patch of Land?](https://ergodic.dev/use-cases/forest-cover-type.html) --- # What Is This Squirrel Doing? Page: https://ergodic.dev/use-cases/red-squirrel-behaviour.html From a collar's acceleration and temperature readings, is the squirrel feeding, travelling, grooming or resting? Tags record for months, and nobody can watch that much video. ## The table Readings from tags worn by wild red squirrels, with three-axis acceleration, temperature and window statistics, labelled with the behaviour seen on video. It's in Welt's research catalogue as Red Squirrel Acceleration and Behaviour Data, 24,300 rows by 25 columns, licensed CC0. The catalogue measures its signal at 0.62. At 24,300 rows and 24 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="red squirrel acceleration", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A behaviour per window**: Months of tag data labelled automatically. **Time budgets**: How long each squirrel spends feeding or travelling. **Fewer hours of video**: Label a sample, predict the rest. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "red squirrel acceleration", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** What Is This Squirrel Doing? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Red Squirrel Acceleration and Behaviour Data, 24,300 rows - **For:** Wildlife ecologists and animal-tag researchers - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) - [Which Forest Grows on This Patch of Land?](https://ergodic.dev/use-cases/forest-cover-type.html) --- # Will This Tree Survive to the Next Survey? Page: https://ergodic.dev/use-cases/tree-survival.html Given its size, its condition last time, its species and how well the climate suits it, will this tree still be alive at the next forest inventory? Foresters plan planting and thinning around exactly this. ## The table Trees measured in repeated forest inventories, with previous status and size, species, plot and climatic suitability, and whether each tree survived. It's in Welt's research catalogue as Local Neighbourhood and Regional Climate Explain Tree Performance, 7,277 rows by 14 columns, licensed CC0. The catalogue measures its signal at 0.81. At 7,277 rows and 13 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="tree performance climate suitability", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A survival probability**: For every tree in the inventory. **Climate risk**: See how survival changes as suitability falls. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "tree performance climate suitability", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Will This Tree Survive to the Next Survey? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Local Neighbourhood and Regional Climate Explain Tree Performance, 7,277 rows - **For:** Foresters and ecologists - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Which Forest Grows on This Patch of Land?](https://ergodic.dev/use-cases/forest-cover-type.html) --- # Which Forest Grows on This Patch of Land? Page: https://ergodic.dev/use-cases/forest-cover-type.html From elevation, slope, distance to water and roads, wilderness area and soil type, which type of forest covers this 30-metre patch of Colorado? Mapping cover from maps alone saves sending crews to remote ground. ## The table 30-metre cells in Colorado's Roosevelt National Forest with cartographic measurements and the forest cover type recorded for each. It's in Welt's research catalogue as Forest Cover Type Prediction from Cartographic Variables (Covertype), 110,393 rows by 55 columns, licensed Public. The catalogue measures its signal at 0.42. At 110,393 rows and 54 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="forest cover type covertype", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A cover type per cell**: With a probability for each type. **Maps without fieldwork**: Predict cover for cells nobody has visited. **A classic benchmark**: One of the most used tables in machine learning. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "forest cover type covertype", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Which Forest Grows on This Patch of Land? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Forest Cover Type Prediction from Cartographic Variables (Covertype), 110,393 rows - **For:** Foresters, ecologists and land managers - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # Which Variety Is This Dry Bean? Page: https://ergodic.dev/use-cases/dry-bean-variety.html From the size and shape measured in a photograph, which of seven varieties is this bean? Sorting by camera keeps seed lots pure without anyone checking beans by eye. ## The table 13,611 beans photographed and measured for area, perimeter, axis lengths, roundness and other shape features, labelled with their variety. It's in Welt's research catalogue as Dry Bean Grain Shape Dataset, 13,611 rows by 17 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.92. At 13,611 rows and 16 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="dry bean", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A variety per bean**: With a probability for each variety. **Automatic sorting**: Grade a whole lot from photos. **A very strong signal**: The catalogue measures one of its highest signals. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "dry bean", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Which Variety Is This Dry Bean? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Dry Bean Grain Shape Dataset, 13,611 rows - **For:** Seed producers and food-processing engineers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # Is This Rice Grain Cammeo or Osmancik? Page: https://ergodic.dev/use-cases/rice-variety.html From seven measurements of its shape in a photograph, which of two Turkish rice varieties is this grain? Mixed lots sell for less, so buyers want a quick check. ## The table 3,810 rice grains measured from images for area, perimeter, axis lengths, eccentricity, convex area and extent, labelled by variety. It's in Welt's research catalogue as Rice Grain Varieties Cammeo and Osmancik, 3,810 rows by 8 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.82. At 3,810 rows and 7 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="rice Cammeo Osmancik", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A variety per grain**: With a probability. **A purity check**: Estimate how mixed a lot is from a sample. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "rice Cammeo Osmancik", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Is This Rice Grain Cammeo or Osmancik? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Rice Grain Varieties Cammeo and Osmancik, 3,810 rows - **For:** Grain traders and food-quality inspectors - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # Is This Raisin Kecimen or Besni? Page: https://ergodic.dev/use-cases/raisin-variety.html From seven size and shape measurements, which of two raisin varieties grown in Turkey is this one? Machine vision grading saves sorting by hand. ## The table 900 raisins measured from images for area, perimeter, axis lengths, eccentricity, convex area and extent, labelled by variety. It's in Welt's research catalogue as Raisin Grain Classification, 900 rows by 8 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.71. At 900 rows and 7 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="raisin grain", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A variety per raisin**: With a probability. **Small data handled**: 900 rows fit three of the four models without sampling. **A clear signal**: The catalogue measures a good signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "raisin grain", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Is This Raisin Kecimen or Besni? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Raisin Grain Classification, 900 rows - **For:** Dried-fruit graders and food engineers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # Is This Wheat Short of Water? Page: https://ergodic.dev/use-cases/wheat-water-stress.html From texture features of a chlorophyll fluorescence image, how water-stressed is this wheat plant? Catching stress early lets a farmer water before yield is lost. ## The table 1,188 wheat images described by texture features from chlorophyll fluorescence, labelled by water-stress class. It's in Welt's research catalogue as Wheat Water Stress Texture Features, 1,188 rows by 23 columns, licensed CC0. The catalogue measures its signal at 0.30. At 1,188 rows and 22 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="wheat water stress texture", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A stress class per plant**: With a probability for each level. **Earlier watering**: Spot stress before it shows to the eye. **An honest signal**: The catalogue measures a modest signal, so read the baseline comparison. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "wheat water stress texture", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Is This Wheat Short of Water? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Wheat Water Stress Texture Features, 1,188 rows - **For:** Crop scientists and precision-farming teams - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # How Good Will Tasters Say This Wine Is? Page: https://ergodic.dev/use-cases/white-wine-quality.html From acidity, sugar, sulphur, alcohol and other lab measurements, what score will a tasting panel give this white wine? Lab tests are cheap and quick, and panels aren't. ## The table 4,898 Portuguese vinho verde white wines with eleven lab measurements and the median score from expert tasters. It's in Welt's research catalogue as White Wine Quality, 4,898 rows by 12 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.45. At 4,898 rows and 11 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="white wine quality", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted score**: For any wine with lab results. **What drives quality**: Compare models to see which measurements matter. **A well-known table**: Compare with many published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "white wine quality", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** How Good Will Tasters Say This Wine Is? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** White Wine Quality, 4,898 rows - **For:** Winemakers and food scientists - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # Is This Jar of Spread Contaminated? Page: https://ergodic.dev/use-cases/cocoa-jar-contamination.html From 30 sensor measurements taken on the line, does this jar of cocoa-hazelnut spread contain a foreign body? A missed jar means a recall, and a false alarm wastes product. ## The table 2,400 jars scanned on a production line with 30 sensor measurements each, labelled clean or contaminated. It's in Welt's research catalogue as Contaminant Detection in Cocoa Hazelnut Spread Jars, 2,400 rows by 31 columns, licensed CC BY-SA. The catalogue measures its signal at 0.81. At 2,400 rows and 30 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="contaminant detection cocoa hazelnut", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per jar**: Reject the jars most likely to be contaminated. **Fewer false alarms**: Set the threshold from the out-of-fold scores. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "contaminant detection cocoa hazelnut", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** Is This Jar of Spread Contaminated? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Contaminant Detection in Cocoa Hazelnut Spread Jars, 2,400 rows - **For:** Food-safety and production-line engineers - **Licence:** CC BY-SA - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # How Much Will This District Harvest? Page: https://ergodic.dev/use-cases/tamil-nadu-crop.html Given the crop, the season, the year and the area planted, how much will a district in Tamil Nadu produce? State planners use estimates like this to plan storage and prices. ## The table Crop records for districts in Tamil Nadu with crop, season, year and cultivated area, and the production recorded. It's in Welt's research catalogue as Tamil Nadu Crop Production, 13,547 rows by 7 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.36. At 13,547 rows and 6 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Tamil Nadu crop production", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A production estimate**: For any district, crop and season. **Unusual harvests**: Seasons far from the estimate stand out. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Tamil Nadu crop production", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Biology - **Question:** How Much Will This District Harvest? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Tamil Nadu Crop Production, 13,547 rows - **For:** Agricultural planners and food-security analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Biology - [Is It a Mammal, a Bird or a Fish?](https://ergodic.dev/use-cases/zoo-animal-class.html) - [Where in the Cell Does This Protein Go?](https://ergodic.dev/use-cases/yeast-protein-location.html) - [Will This Snail Choose to Mate?](https://ergodic.dev/use-cases/snail-mating.html) - [Will Whooping Cranes Stop Here?](https://ergodic.dev/use-cases/whooping-crane-stopover.html) - [What Is This Squirrel Doing?](https://ergodic.dev/use-cases/red-squirrel-behaviour.html) - [Will This Tree Survive to the Next Survey?](https://ergodic.dev/use-cases/tree-survival.html) --- # How Much CO2 Will Mauna Loa Measure Next Year? Page: https://ergodic.dev/use-cases/mauna-loa-co2.html Given every weekly reading since the 1970s, what will the CO2 level at Mauna Loa be over the next 52 weeks? The record climbs every year and rises and falls with the seasons, a good test of any forecast. ## The table Weekly average atmospheric CO2 measured at the Mauna Loa Observatory in Hawaii. It's in Welt's research catalogue as Mauna Loa Weekly Atmospheric CO2 Averages, 2,225 rows by 7 columns, licensed CC0. The catalogue measures its signal at 0.57, in time order. Chronos-2 forecasts the series in one request and needs no training. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client, Forecast with Client() as client: item = client.research_datasets(q="Mauna Loa weekly CO2", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the history Keep the time column and the target. ``` time = "date" history = data[[time, target]].dropna() history[time] = pd.to_datetime(history[time]) history = history.sort_values(time) ``` 3. ### Forecast with a range Ask for the next 52 steps, one per week. The median is the forecast, and the 10% and 90% columns give a low and a high case. ``` model = Forecast(model="chronos-2").fit(history, time=time, target=[target]) result = model.forecast(52, quantile_levels=[0.1, 0.5, 0.9]) print(result.to_frame()[["timestamp", "median", "q_0.1", "q_0.9"]].head(52)) ``` ## What you get **A year ahead**: Weekly CO2 with a range around each week. **The seasons kept**: The forecast follows the yearly rise and fall. **One series, no set-up**: Chronos-2 reads the history as it is. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Mauna Loa weekly CO2", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Much CO2 Will Mauna Loa Measure Next Year? - **Model:** Chronos-2 - **Data:** Mauna Loa Weekly Atmospheric CO2 Averages, 2,225 rows - **For:** Climate scientists, teachers and data journalists - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) - [How Polluted Is Beijing's Air This Hour?](https://ergodic.dev/use-cases/beijing-air-pollution.html) --- # How Warm Is the Pacific at This Buoy? Page: https://ergodic.dev/use-cases/pacific-sea-temperature.html From the buoy's position, the date, the winds and the humidity, what is the sea surface temperature? Buoys fail and leave gaps, and El Niño studies need a complete record. ## The table Readings from moored buoys across the equatorial Pacific, with location, date, winds and humidity and the sea surface temperature. It's in Welt's research catalogue as El Nino Equatorial Pacific Buoy Readings, 178,080 rows by 11 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.90. At 178,080 rows and 10 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="El Nino buoy", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **Temperature per reading**: An estimate wherever a buoy has the other readings. **Gaps filled**: Complete the record when a sensor drops out. **A strong signal**: The catalogue measures one of its highest signals here. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "El Nino buoy", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Warm Is the Pacific at This Buoy? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** El Nino Equatorial Pacific Buoy Readings, 178,080 rows - **For:** Climate scientists and oceanographers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) - [How Polluted Is Beijing's Air This Hour?](https://ergodic.dev/use-cases/beijing-air-pollution.html) --- # How Much Water Will This Soil Hold? Page: https://ergodic.dev/use-cases/soil-water-content.html From its sand, silt and clay, organic carbon, density, pH and depth, how much water does this soil hold at field capacity? Measuring it in a lab is slow, so an estimate from cheaper measurements helps every irrigation and flood model. ## The table Soil samples from around the world with texture, organic carbon, bulk density, pH and depth, and the water content measured at 33 kPa. It's in Welt's research catalogue as SoilHydroDB: Global Soil Hydraulic Properties, 155,649 rows by 38 columns, licensed CC BY-SA. The catalogue measures its signal at 0.82. At 155,649 rows and 37 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="SoilHydroDB", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **Water content per sample**: An estimate from routine soil measurements. **Fewer lab tests**: Measure the cheap properties and predict the expensive one. **A strong signal**: The catalogue measures a high signal for this table. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "SoilHydroDB", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Much Water Will This Soil Hold? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** SoilHydroDB: Global Soil Hydraulic Properties, 155,649 rows - **For:** Soil scientists, agronomists and hydrologists - **Licence:** CC BY-SA - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) - [How Polluted Is Beijing's Air This Hour?](https://ergodic.dev/use-cases/beijing-air-pollution.html) --- # How Far Off Is the Temperature Forecast? Page: https://ergodic.dev/use-cases/weather-forecast-correction.html How wrong will the national weather model's temperature forecast for Aarhus be, and in which direction? Correcting the forecast with recent local observations is how forecasters squeeze out extra accuracy. ## The table Forecasts from the Danish Meteorological Institute for Aarhus, with forecast fields, lead time and recent observations, and the error each forecast turned out to have. It's in Welt's research catalogue as DMI Aarhus Weather Data: Training Matrix, 64,568 rows by 76 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.88. At 64,568 rows and 75 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="DMI Aarhus weather", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A forecast correction**: Add the predicted error to get a better forecast. **Local knowledge**: The model learns where the national forecast goes wrong for one city. **A strong signal**: The catalogue measures a high signal for this table. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "DMI Aarhus weather", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Far Off Is the Temperature Forecast? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** DMI Aarhus Weather Data: Training Matrix, 64,568 rows - **For:** Meteorologists and forecast users - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) - [How Polluted Is Beijing's Air This Hour?](https://ergodic.dev/use-cases/beijing-air-pollution.html) --- # How Windy Is It at This Irish Station? Page: https://ergodic.dev/use-cases/irish-wind-speed.html If you know today's wind speed at eleven weather stations across Ireland, what is it at the twelfth? Filling in one site from its neighbours is how wind farm planners estimate places without a mast. ## The table Daily average wind speeds at twelve Irish weather stations over 18 years, with the date. It's in Welt's research catalogue as Wind 503 Regression, 6,574 rows by 15 columns, licensed StatLib. The catalogue measures its signal at 0.77. At 6,574 rows and 14 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="wind 503", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A wind speed per day**: Estimated from the neighbouring stations. **A site without a mast**: The same approach estimates places with no measurements. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "wind 503", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Windy Is It at This Irish Station? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Wind 503 Regression, 6,574 rows - **For:** Wind energy analysts and meteorologists - **Licence:** StatLib - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) - [How Polluted Is Beijing's Air This Hour?](https://ergodic.dev/use-cases/beijing-air-pollution.html) --- # How Murky Is the Water at the Bottom of the Canyon? Page: https://ergodic.dev/use-cases/canyon-turbidity.html From currents, temperature, pressure and the weather at the surface, how cloudy is the water deep in Barkley Canyon? Turbidity shows how much material sinks to the deep sea, which matters for how the ocean stores carbon. ## The table Hourly readings from instruments deep in Barkley Canyon off Canada and a surface weather buoy, with the turbidity measured at depth. It's in Welt's research catalogue as Oceanic Biological Pump Barkley Canyon, 5,089 rows by 31 columns, licensed CC0. The catalogue measures its signal at 0.84. At 5,089 rows and 30 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Barkley Canyon biopump", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **Turbidity per hour**: An estimate from the other instruments. **Gaps filled**: Keep the record going when a sensor is fouled. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Barkley Canyon biopump", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Murky Is the Water at the Bottom of the Canyon? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Oceanic Biological Pump Barkley Canyon, 5,089 rows - **For:** Ocean scientists and marine engineers - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Polluted Is Beijing's Air This Hour?](https://ergodic.dev/use-cases/beijing-air-pollution.html) --- # How Polluted Is Beijing's Air This Hour? Page: https://ergodic.dev/use-cases/beijing-air-pollution.html From the dew point, temperature, pressure, wind, snow and rain, how much fine particulate matter is in Beijing's air? Weather explains a lot of pollution, and knowing how much helps a city tell weather from emissions. ## The table Five years of hourly weather readings at the US embassy in Beijing, with the PM2.5 concentration for each hour. It's in Welt's research catalogue as Beijing PM2.5 Air Quality and Weather, 43,824 rows by 13 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.57. At 43,824 rows and 12 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Beijing PM2.5", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **PM2.5 per hour**: An estimate from the weather alone. **Weather or emissions**: Hours far above the estimate point to a source, not the weather. **A clear comparison**: The leaderboard shows how much weather explains. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Beijing PM2.5", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How Polluted Is Beijing's Air This Hour? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Beijing PM2.5 Air Quality and Weather, 43,824 rows - **For:** Air-quality scientists and city health teams - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) --- # How High Will Ozone Climb in Los Angeles Today? Page: https://ergodic.dev/use-cases/la-ozone.html From the date and the morning's weather readings, what will the day's maximum ozone level be in Los Angeles? Health warnings go out when it's likely to be high. ## The table Every day of 1976 in the Los Angeles basin, with calendar fields and meteorological readings, and the day's maximum ozone level. It's in Welt's research catalogue as Los Angeles Ozone Pollution Data (1976), 366 rows by 13 columns, licensed CC0. The catalogue measures its signal at 0.71. At 366 rows and 12 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Los Angeles ozone 1976", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A daily ozone estimate**: From readings available that morning. **Earlier warnings**: Flag days likely to cross the health limit. **Small data handled**: Every model in the collection can take 366 rows. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Los Angeles ozone 1976", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** How High Will Ozone Climb in Los Angeles Today? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Los Angeles Ozone Pollution Data (1976), 366 rows - **For:** Air-quality analysts and public health teams - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) --- # What's on the Ground in This Part of Ouagadougou? Page: https://ergodic.dev/use-cases/urban-land-cover.html From its Sentinel-2 satellite bands, is this spot in Ouagadougou buildings, roads, bare soil, vegetation or water? Fast-growing cities need up-to-date maps, and ground surveys can't keep pace. ## The table Points in Ouagadougou with their Sentinel-2 band values and spectral indices, labelled by land-cover class. It's in Welt's research catalogue as Trusted Urban Land-Cover Training Labels, 46 African Cities: Ouagadougou, 5,013 rows by 19 columns, licensed CC0 1.0. The catalogue measures its signal at 0.64. At 5,013 rows and 18 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="urban land-cover Ouagadougou", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A class per point**: Land cover with a probability for each class. **Maps that keep up**: Classify new satellite passes as they arrive. **Checked labels**: Trained on labels people verified on the ground. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "urban land-cover Ouagadougou", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** What's on the Ground in This Part of Ouagadougou? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Trusted Urban Land-Cover Training Labels, 46 African Cities: Ouagadougou, 5,013 rows - **For:** Urban planners and remote-sensing analysts - **Licence:** CC0 1.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) --- # What Land Does This Satellite Pixel Show? Page: https://ergodic.dev/use-cases/satellite-land-cover.html From the four spectral bands of a small patch of Landsat image, is it red soil, cotton crop, grey soil, damp soil, vegetation stubble or very damp soil? It's the classic test for turning satellite pixels into a land map. ## The table Three-by-three pixel neighbourhoods from a Landsat image, with 36 multispectral values and the land-cover class of the centre pixel. It's in Welt's research catalogue as Satellite Image Attributes, 6,435 rows by 37 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.86. At 6,435 rows and 36 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="satellite image attributes", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A class per pixel**: With a probability for each type of land. **A strong signal**: The catalogue measures a high signal. **A classic benchmark**: Compare with decades of published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "satellite image attributes", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Climate - **Question:** What Land Does This Satellite Pixel Show? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Satellite Image Attributes, 6,435 rows - **For:** Remote-sensing analysts and geographers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Climate - [How Much CO2 Will Mauna Loa Measure Next Year?](https://ergodic.dev/use-cases/mauna-loa-co2.html) - [How Warm Is the Pacific at This Buoy?](https://ergodic.dev/use-cases/pacific-sea-temperature.html) - [How Much Water Will This Soil Hold?](https://ergodic.dev/use-cases/soil-water-content.html) - [How Far Off Is the Temperature Forecast?](https://ergodic.dev/use-cases/weather-forecast-correction.html) - [How Windy Is It at This Irish Station?](https://ergodic.dev/use-cases/irish-wind-speed.html) - [How Murky Is the Water at the Bottom of the Canyon?](https://ergodic.dev/use-cases/canyon-turbidity.html) --- # What Load Is the Steel Plant Running? Page: https://ergodic.dev/use-cases/steel-plant-load-type.html Is the plant running a light, medium or maximum load right now? Knowing the load from the meters alone lets an energy manager shift heavy work to cheaper hours and spot waste without walking the floor. ## The table Readings from a steel plant every 15 minutes for a year: energy used, reactive power, power factor, CO2 and the time of day, with the load type recorded for each reading. It's in Welt's research catalogue as Steel Industry Energy Consumption, 35,040 rows by 10 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.76. At 35,040 rows and 9 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="steel industry energy consumption", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **Load from the meter**: Each new reading gets a load type and a probability. **Cheaper scheduling**: Heavy loads at peak price stand out at once. **Proof it works**: The leaderboard shows the score against a simple guess. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "steel industry energy consumption", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** What Load Is the Steel Plant Running? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Steel Industry Energy Consumption, 35,040 rows - **For:** Energy managers and industrial engineers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) - [How Much NOx Is the Gas Turbine Emitting?](https://ergodic.dev/use-cases/gas-turbine-nox.html) --- # How Much Power Will Tetouan Draw? Page: https://ergodic.dev/use-cases/tetouan-power-demand.html Given the temperature, humidity, wind and sunlight, how much power will zone 1 of Tetouan use? A city utility plans its supply around exactly this number. ## The table A year of readings every ten minutes from Tetouan in Morocco, with weather measurements and the power used in the city's first zone. It's in Welt's research catalogue as Power Consumption of Tetouan City, 52,416 rows by 7 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.35. At 52,416 rows and 6 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="power consumption Tetouan", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **Demand from the weather**: An estimate for any weather reading. **A plan for hot days**: See how demand moves with temperature. **An honest signal**: Weather alone explains part of demand, and the score shows how much. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "power consumption Tetouan", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** How Much Power Will Tetouan Draw? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Power Consumption of Tetouan City, 52,416 rows - **For:** Grid operators and energy analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) - [How Much NOx Is the Gas Turbine Emitting?](https://ergodic.dev/use-cases/gas-turbine-nox.html) --- # How Much Sunlight Will Reach the Panels? Page: https://ergodic.dev/use-cases/solar-radiation.html From the time of day, temperature, pressure, humidity and wind, how much solar radiation is reaching the ground? Solar operators use the estimate to plan output and fill gaps when a sensor is down. ## The table Readings from a weather station in Hawaii, with time of day, sunrise and sunset, temperature, pressure, humidity and wind, and measured solar radiation. It's in Welt's research catalogue as Solar Radiation Prediction, 32,686 rows by 11 columns, licensed ODbL. The catalogue measures its signal at 0.82. At 32,686 rows and 10 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="solar radiation prediction", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A radiation estimate**: Watts per square metre from routine weather readings. **Gaps filled**: Estimate radiation when the pyranometer is offline. **A strong signal**: The catalogue measures a high signal for this table. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "solar radiation prediction", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** How Much Sunlight Will Reach the Panels? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Solar Radiation Prediction, 32,686 rows - **For:** Solar farm operators and energy forecasters - **Licence:** ODbL - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) - [How Much NOx Is the Gas Turbine Emitting?](https://ergodic.dev/use-cases/gas-turbine-nox.html) --- # Is This Smart Grid Stable? Page: https://ergodic.dev/use-cases/smart-grid-stability.html With these reaction times, power balances and price responses, will a four-node smart grid stay stable? Simulating every case is slow, so a fast prediction helps designers test many set-ups. ## The table 10,000 simulated grids with the reaction time, power produced or used and price elasticity at each node, labelled stable or unstable. It's in Welt's research catalogue as Electrical Grid Stability Simulated Classification, 10,000 rows by 13 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.82. At 10,000 rows and 12 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="electrical grid stability", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **Stable or not, in seconds**: A probability for any grid set-up. **Fewer simulations**: Simulate only the borderline cases. **A clear signal**: The catalogue measures a strong signal here. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "electrical grid stability", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** Is This Smart Grid Stable? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Electrical Grid Stability Simulated Classification, 10,000 rows - **For:** Power systems engineers and energy researchers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) - [How Much NOx Is the Gas Turbine Emitting?](https://ergodic.dev/use-cases/gas-turbine-nox.html) --- # How Much Electricity Did Spain Use Today? Page: https://ergodic.dev/use-cases/spain-daily-electricity.html From how much each type of power station generated, what was Spain's total electricity use that day? A year of daily figures is a small table, which is where foundation models do well. ## The table A year of daily figures for Spain in 2003, with energy from each generation source and the day's consumption. It's in Welt's research catalogue as Daily Electric Energy in Spain (2003), 365 rows by 7 columns, licensed CC0. The catalogue measures its signal at 0.83. At 365 rows and 6 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="daily electric energy Spain", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A daily estimate**: Consumption from the generation mix. **Small data handled**: 365 rows are enough for every model to compete. **A clear signal**: The catalogue measures a strong signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "daily electric energy Spain", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** How Much Electricity Did Spain Use Today? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Daily Electric Energy in Spain (2003), 365 rows - **For:** Energy analysts and students - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) - [How Much NOx Is the Gas Turbine Emitting?](https://ergodic.dev/use-cases/gas-turbine-nox.html) --- # What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour? Page: https://ergodic.dev/use-cases/electricity-price-forecast.html From the recent price history, what will the next 48 half-hourly electricity prices be? A business that can shift its use to the cheap hours saves real money. ## The table Half-hourly electricity prices from the ICON 2014 forecasting challenge, with calendar fields, load and wind forecasts, weather and the day-ahead price. It's in Welt's research catalogue as Electricity Prices from the ICON 2014 Forecasting Challenge, 38,014 rows by 18 columns, licensed Public. The catalogue measures its signal at 0.38, in time order. Chronos-2 forecasts the series in one request and needs no training. Chronos-2 reads up to 8,000 steps of history per series, so the walkthrough keeps the latest 8,000. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client, Forecast with Client() as client: item = client.research_datasets(q="electricity prices ICON 2014", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the history Keep the time column and the target. ``` time = "datetime" history = data[[time, target]].dropna() history[time] = pd.to_datetime(history[time]) history = history.sort_values(time).tail(8000) ``` 3. ### Forecast with a range Ask for the next 48 steps, one per half-hour. The median is the forecast, and the 10% and 90% columns give a low and a high case. ``` model = Forecast(model="chronos-2").fit(history, time=time, target=[target]) result = model.forecast(48, quantile_levels=[0.1, 0.5, 0.9]) print(result.to_frame()[["timestamp", "median", "q_0.1", "q_0.9"]].head(48)) ``` ## What you get **Tomorrow's prices**: Every half hour with a range. **The cheap hours**: Plan flexible use around the low points. **An honest signal**: Prices are hard to forecast, and the range says how hard. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "electricity prices ICON 2014", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour? - **Model:** Chronos-2 - **Data:** Electricity Prices from the ICON 2014 Forecasting Challenge, 38,014 rows - **For:** Energy traders and large power users - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [How Much NOx Is the Gas Turbine Emitting?](https://ergodic.dev/use-cases/gas-turbine-nox.html) --- # How Much NOx Is the Gas Turbine Emitting? Page: https://ergodic.dev/use-cases/gas-turbine-nox.html From the weather and the turbine's operating readings, how much nitrogen oxide is the plant putting out? A good estimate backs up the emissions analyser and helps tune the turbine to stay within limits. ## The table Five years of hourly readings from a gas turbine power plant, with ambient conditions, turbine operating values and measured NOx. It's in Welt's research catalogue as Gas Turbine CO and NOx Emissions (2011-2015), 36,733 rows by 12 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.83. At 36,733 rows and 11 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="gas turbine CO NOx emissions", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **An emissions estimate**: NOx predicted from routine readings. **A check on the analyser**: Spot hours when the measured value looks wrong. **Settings to try**: See how predicted emissions change with operating conditions. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "gas turbine CO NOx emissions", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** How Much NOx Is the Gas Turbine Emitting? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Gas Turbine CO and NOx Emissions (2011-2015), 36,733 rows - **For:** Power plant engineers and environmental managers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) --- # How Much Steam Is the Boiler Making? Page: https://ergodic.dev/use-cases/boiler-steam-flow.html From the feed water flow, temperature and pressure, how much steam is the refinery boiler producing? A model that tracks it gives operators a second opinion when a flow meter drifts. ## The table Sensor readings from an industrial boiler at a Turkish refinery, with feed water flow, temperature and pressure and the steam output flow. It's in Welt's research catalogue as TUPRAS Boiler Sensor Measurements, 44,643 rows by 8 columns, licensed CC0. The catalogue measures its signal at 0.76. At 44,643 rows and 7 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="TUPRAS boiler", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A virtual steam meter**: An estimate of steam flow from the other sensors. **Drift spotted**: A gap between the estimate and the meter flags a sensor to check. **Small table, quick answer**: Seven inputs, no tuning. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "TUPRAS boiler", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** How Much Steam Is the Boiler Making? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** TUPRAS Boiler Sensor Measurements, 44,643 rows - **For:** Process and plant engineers - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) --- # How Much Energy Are This Home's Appliances Using? Page: https://ergodic.dev/use-cases/appliance-energy-use.html From room-by-room temperature and humidity and the weather outside, how much energy are the appliances in this house drawing? It tests how much a smart home can learn from cheap sensors. ## The table Readings every ten minutes from a low-energy house in Belgium, with temperature and humidity in each room, outdoor weather and appliance energy use. It's in Welt's research catalogue as Appliances Energy Prediction, 19,735 rows by 28 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.27. At 19,735 rows and 27 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="appliances energy prediction", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **An energy estimate**: Appliance use predicted from room sensors. **A realistic test**: The catalogue measures a weak signal, so the baseline comparison is the point. **Which rooms matter**: Compare models to see how much the sensors explain. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "appliances energy prediction", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Energy - **Question:** How Much Energy Are This Home's Appliances Using? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Appliances Energy Prediction, 19,735 rows - **For:** Smart-home and building energy researchers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Energy - [What Load Is the Steel Plant Running?](https://ergodic.dev/use-cases/steel-plant-load-type.html) - [How Much Power Will Tetouan Draw?](https://ergodic.dev/use-cases/tetouan-power-demand.html) - [How Much Sunlight Will Reach the Panels?](https://ergodic.dev/use-cases/solar-radiation.html) - [Is This Smart Grid Stable?](https://ergodic.dev/use-cases/smart-grid-stability.html) - [How Much Electricity Did Spain Use Today?](https://ergodic.dev/use-cases/spain-daily-electricity.html) - [What Will Electricity Cost Tomorrow, Half-Hour by Half-Hour?](https://ergodic.dev/use-cases/electricity-price-forecast.html) --- # What Will This Yacht's Resistance Be? Page: https://ergodic.dev/use-cases/predict-a-number.html Given a hull's shape and speed, how much will the water push back? Testing every design in a tank is slow and expensive, so engineers want a number they can trust before the test. The same pattern fits any measurement you'd like to predict from a few hundred rows: a yield, a delivery time, a price. ## The table Yacht Hydrodynamics has 308 tank tests. Six columns describe the hull and its speed, and the seventh, Residuary.resistance, is the number to predict. It's in Welt's research catalogue, so you can load it in one line. ## Walkthrough 1. ### Load the table Search the research catalogue and load the table into a DataFrame. ``` from welt import Client with Client() as client: page = client.research_datasets(q="yacht", availability="available", limit=5) yachts = client.load_research_dataset(page["items"][0]["id"]) ``` 2. ### Hold some rows back Keep 30% of the tests aside, so you can check the predictions against real measurements. ``` from sklearn.model_selection import train_test_split target = "Residuary.resistance" train, test = train_test_split(yachts, test_size=0.3, random_state=9) ``` 3. ### Predict and check Fit on the training rows and predict the held-back ones. There's nothing to tune. ``` from welt import Regressor from sklearn.metrics import mean_absolute_error model = Regressor(model="tabicl-v2", random_state=9) model.fit(train, target=target) predictions = model.predict(test.drop(columns=target)) print("Average error:", mean_absolute_error(test[target], predictions)) ``` ## What you get **A prediction for every new design**: Each one comes back in the same units as the measurement. **An honest error figure**: The average error on rows the model never saw tells you how far to trust it. **A model you can reuse**: The fitted predictor stays in your workspace, so tomorrow's designs need no refit. ## Try it Use Open with to run the regression notebook in Colab, Kaggle or Jupyter, or run the code above after `pip install "welt-client[parquet]" scikit-learn`. - **Type:** Use case - **Area:** Engineering - **Question:** What Will This Yacht's Resistance Be? - **Model:** TabICLv2 - **Data:** Yacht Hydrodynamics, 308 hull tests, from Welt's research catalogue - **For:** Engineers and analysts predicting a measurement - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/regression.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/regression.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/regression.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-regression.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) - [Is This School Bus Broken Down or Just Late?](https://ergodic.dev/use-cases/nyc-school-bus-delays.html) --- # What State Is the Shuttle's System In? Page: https://ergodic.dev/use-cases/shuttle-sensor-state.html From nine sensor readings, which operating state is the system in? Engineers need to catch the rare abnormal states quickly, without a hand-built rule for each one. ## The table 58,000 rows of nine numeric sensor attributes from NASA's shuttle, each labelled with the system's state. It's in Welt's research catalogue as Statlog Shuttle, 58,000 rows by 10 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.67. At 58,000 rows and 9 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="statlog shuttle", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A state per reading**: Every new set of readings gets a state and a probability. **Rare states caught**: Check the per-class scores for the states that matter most. **No rules to maintain**: The model learns the boundaries from the data. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "statlog shuttle", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** What State Is the Shuttle's System In? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Statlog Shuttle, 58,000 rows - **For:** Reliability engineers and sensor analysts - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) - [Is This School Bus Broken Down or Just Late?](https://ergodic.dev/use-cases/nyc-school-bus-delays.html) --- # Will This Machine Fail? Page: https://ergodic.dev/use-cases/machine-failure.html Given its temperatures, speed, torque and tool wear, is this milling machine about to fail? Catching failures before they happen turns an emergency stop into a planned repair. ## The table 10,000 machine readings with product type, air and process temperature, rotational speed, torque and tool wear, and whether the machine failed. It's in Welt's research catalogue as AI4I 2020 Predictive Maintenance, 10,000 rows by 7 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.45. At 10,000 rows and 6 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="AI4I 2020 predictive maintenance", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A failure risk per reading**: Each new reading gets a probability of failure. **Planned repairs**: Book maintenance for the machines most at risk. **Rare events checked**: The leaderboard shows how well failures are caught, not just overall accuracy. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "AI4I 2020 predictive maintenance", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Will This Machine Fail? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** AI4I 2020 Predictive Maintenance, 10,000 rows - **For:** Maintenance engineers and plant managers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) - [Is This School Bus Broken Down or Just Late?](https://ergodic.dev/use-cases/nyc-school-bus-delays.html) --- # How Long Has This Engine Got Left? Page: https://ergodic.dev/use-cases/engine-remaining-life.html How many more cycles can this jet engine run before it needs attention? An estimate of remaining life lets an operator plan maintenance around the engine instead of the calendar. ## The table Simulated turbofan engines run to failure, with 21 sensor readings at every cycle and the number of cycles each engine had left. It's in Welt's research catalogue as NASA PHM2008 Dataset 1, 45,918 rows by 22 columns, licensed BSD. The catalogue measures its signal at 0.61. At 45,918 rows and 21 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="NASA PHM2008", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **Cycles left per engine**: A number you can plan maintenance around. **Worst engines first**: Sort the fleet by predicted remaining life. **Sensor data as it comes**: The model reads the 21 readings without hand-built health indicators. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "NASA PHM2008", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** How Long Has This Engine Got Left? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** NASA PHM2008 Dataset 1, 45,918 rows - **For:** Reliability and aerospace engineers - **Licence:** BSD - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) - [Is This School Bus Broken Down or Just Late?](https://ergodic.dev/use-cases/nyc-school-bus-delays.html) --- # How Badly Would an Earthquake Damage This Building? Page: https://ergodic.dev/use-cases/earthquake-building-damage.html From its age, height, footprint, materials and use, which damage grade is this building likely to reach in an earthquake? Planners want to know which buildings to inspect or strengthen before the next one. ## The table Buildings surveyed after an earthquake, with region, number of floors, age, area, structure, materials and use, and the damage grade each one suffered. It's in Welt's research catalogue as BMC Training Data: Building Characteristics, 177,640 rows by 40 columns, licensed CC0. The catalogue measures its signal at 0.35. At 177,640 rows and 39 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="BMC building characteristics", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A damage grade per building**: With a probability for each grade. **Where to inspect first**: Rank buildings by their chance of heavy damage. **An honest signal**: The catalogue measures a modest signal here, so the comparison with a simple guess matters. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "BMC building characteristics", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** How Badly Would an Earthquake Damage This Building? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** BMC Training Data: Building Characteristics, 177,640 rows - **For:** Structural engineers and disaster planners - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) - [Is This School Bus Broken Down or Just Late?](https://ergodic.dev/use-cases/nyc-school-bus-delays.html) --- # How Should the F-16's Ailerons Move? Page: https://ergodic.dev/use-cases/aileron-control.html Given the aircraft's current state, what aileron command would the pilot give next? Learning that mapping from flight data is a classic test for building autopilot assistance. ## The table Readings from a simulated F-16 in flight, with 33 attributes describing the aircraft's state and the aileron control action taken. It's in Welt's research catalogue as Ailerons Control Problem, 13,750 rows by 34 columns, licensed Public. The catalogue measures its signal at 0.83. At 13,750 rows and 33 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="ailerons", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted control action**: A number for each flight state. **A strong signal**: The catalogue measures a high signal, so expect a tight fit. **A classic benchmark**: Compare with published results on the same table. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "ailerons", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** How Should the F-16's Ailerons Move? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Ailerons Control Problem, 13,750 rows - **For:** Control engineers and aerospace researchers - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [Is This School Bus Broken Down or Just Late?](https://ergodic.dev/use-cases/nyc-school-bus-delays.html) --- # Is This School Bus Broken Down or Just Late? Page: https://ergodic.dev/use-cases/nyc-school-bus-delays.html From the reason given, the route, the run type, the borough and the bus company, is this incident a breakdown or a delay? Breakdowns need a replacement bus, and delays need a message to parents. ## The table School bus incidents reported in New York City from 2015 to 2017, with reason, route, run type, borough and company, labelled breakdown or running late. It's in Welt's research catalogue as Bus Breakdown and Delays in NYC, 2015 to 2017, 147,972 rows by 21 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.86. At 147,972 rows and 20 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="bus breakdown delays NYC", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A label per incident**: Breakdown or delay, with a probability. **Faster dispatch**: Send a replacement bus as soon as a breakdown is likely. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "bus breakdown delays NYC", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Is This School Bus Broken Down or Just Late? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Bus Breakdown and Delays in NYC, 2015 to 2017, 147,972 rows - **For:** Transport planners and school operations teams - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # How Badly Will People Be Hurt in This Crash? Page: https://ergodic.dev/use-cases/crash-injury-severity.html From seat-belt use, ejection, seating position and other crash details, how severe were the injuries? Knowing what makes the difference helps safety agencies decide where to campaign. ## The table Person records from the US Fatality Analysis Reporting System, with restraint use, ejection, position, crash details and test fields, and the injury severity. It's in Welt's research catalogue as FARS Motor Vehicle Crash Person Records (PMLB), 100,968 rows by 30 columns, licensed MIT (PMLB collection). The catalogue measures its signal at 0.43. At 100,968 rows and 29 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="FARS motor vehicle crash person", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A severity per person**: With a probability for each level. **What protects people**: Compare predictions with and without restraints. **Large tables handled**: A seeded sample keeps the run within the limits. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "FARS motor vehicle crash person", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** How Badly Will People Be Hurt in This Crash? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** FARS Motor Vehicle Crash Person Records (PMLB), 100,968 rows - **For:** Road-safety researchers and transport agencies - **Licence:** MIT (PMLB collection) - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # Is That Sonar Echo a Mine or a Rock? Page: https://ergodic.dev/use-cases/sonar-mine-or-rock.html From the energy in 60 frequency bands of a sonar return, did the pulse bounce off a metal cylinder or a rock? With 208 echoes and 60 features, it's a small, wide table. ## The table 208 sonar returns with energy in 60 frequency bands, labelled mine (metal cylinder) or rock. It's in Welt's research catalogue as Sonar: Mines versus Rocks, 208 rows by 61 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.67. At 208 rows and 60 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="sonar mines rocks", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per echo**: Mine or rock. **Small, wide data handled**: 208 rows and 60 features, no tuning. **A classic benchmark**: Compare with published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "sonar mines rocks", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Is That Sonar Echo a Mine or a Rock? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Sonar: Mines versus Rocks, 208 rows - **For:** Signal-processing engineers and students - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # Is This a Bus, a Van or a Car? Page: https://ergodic.dev/use-cases/vehicle-silhouette.html From 18 measurements of its silhouette, is this vehicle a double-decker bus, a van, or one of two car models? It shows how far shape alone gets you. ## The table 846 vehicle silhouettes with 18 shape measurements such as compactness, circularity and scatter, labelled with one of four vehicle types. It's in Welt's research catalogue as Vehicle Shape Features, 846 rows by 19 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.71. At 846 rows and 18 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="vehicle shape features", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A type per vehicle**: With a probability for each type. **Which cars get confused**: Read the per-class scores. **Small data handled**: 846 rows fit three of the four models without sampling. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "vehicle shape features", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Is This a Bus, a Van or a Car? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Vehicle Shape Features, 846 rows - **For:** Computer-vision students and engineers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # Which Phase of a Gesture Is the Hand In? Page: https://ergodic.dev/use-cases/gesture-phase.html From the velocity and acceleration of the hands and wrists, is the speaker resting, preparing a gesture, making the stroke, holding it or returning? Splitting gestures into phases is how researchers study how people talk with their hands. ## The table 2,000 frames from videos of people telling stories, with hand and wrist velocity and acceleration, labelled by gesture phase. It's in Welt's research catalogue as Gesture Phase Segmentation, 2,000 rows by 33 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.34. At 2,000 rows and 32 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="gesture phase segmentation", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A phase per frame**: With a probability for each phase. **Faster annotation**: Label a sample by hand and predict the rest. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "gesture phase segmentation", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Which Phase of a Gesture Is the Hand In? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Gesture Phase Segmentation, 2,000 rows - **For:** Human-computer interaction and sign-language researchers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # Which Wave Made This Noisy Signal? Page: https://ergodic.dev/use-cases/noisy-waveform.html Each signal is a blend of two of three simple wave shapes with random noise added. From its 21 values, which of the three classes produced it? Because the noise is known, you can see how close a model gets to the best possible score. ## The table 5,000 noisy signals, each sampled at 21 points, labelled with which of three wave classes generated it. It's in Welt's research catalogue as Waveform 21, 5,000 rows by 22 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.77. At 5,000 rows and 21 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="waveform 21", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A class per signal**: With a probability for each class. **A known ceiling**: The best possible accuracy is known, so the gap is easy to read. **A classic benchmark**: Compare with decades of published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "waveform 21", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Which Wave Made This Noisy Signal? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Waveform 21, 5,000 rows - **For:** Signal-processing students and ML researchers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # Which Digit Is This Faulty Display Showing? Page: https://ergodic.dev/use-cases/led-digit.html Each of the seven segments on this display is on or off, and some are flipped by mistake. Which digit was it meant to show? It's a neat way to see how models cope with noise. ## The table 500 readings of a seven-segment display with each segment on or off, about one in ten flipped at random, labelled with the digit intended. It's in Welt's research catalogue as LED Display Digits (7 Segments), 500 rows by 8 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.67. At 500 rows and 7 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="LED display digits", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A digit per reading**: With a probability for each digit. **Noise handled**: See how close the score gets to the best possible. **Small data handled**: Every model in the collection can take 500 rows. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "LED display digits", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Engineering - **Question:** Which Digit Is This Faulty Display Showing? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** LED Display Digits (7 Segments), 500 rows - **For:** Teachers, students and anyone new to machine learning - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Engineering - [What Will This Yacht's Resistance Be?](https://ergodic.dev/use-cases/predict-a-number.html) - [What State Is the Shuttle's System In?](https://ergodic.dev/use-cases/shuttle-sensor-state.html) - [Will This Machine Fail?](https://ergodic.dev/use-cases/machine-failure.html) - [How Long Has This Engine Got Left?](https://ergodic.dev/use-cases/engine-remaining-life.html) - [How Badly Would an Earthquake Damage This Building?](https://ergodic.dev/use-cases/earthquake-building-damage.html) - [How Should the F-16's Ailerons Move?](https://ergodic.dev/use-cases/aileron-control.html) --- # Is This Telescope Flash a Gamma Ray? Page: https://ergodic.dev/use-cases/gamma-ray-telescope.html Did this flash of light in the telescope come from a gamma ray or from ordinary cosmic-ray noise? Telling them apart quickly is how a ground telescope finds the rare gamma-ray sources it's built to study. ## The table Simulated flashes recorded by the MAGIC telescope, each described by ten shape measurements of its image, labelled gamma or hadron. It's in Welt's research catalogue as MAGIC Gamma Telescope, 19,020 rows by 11 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.66. At 19,020 rows and 10 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="MAGIC gamma telescope", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per flash**: Rank events by how likely each is to be a gamma ray. **Cleaner signal**: Throw away the background before any deeper analysis. **A known benchmark**: Compare the result with years of published work on this table. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "MAGIC gamma telescope", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Is This Telescope Flash a Gamma Ray? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** MAGIC Gamma Telescope, 19,020 rows - **For:** Physicists and astronomy students - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) - [How Will This Student Finish the Course?](https://ergodic.dev/use-cases/student-final-performance.html) --- # Is This Collision a Higgs Boson? Page: https://ergodic.dev/use-cases/higgs-boson-signal.html Does this simulated collision contain a Higgs boson, or is it background that only looks similar? Separating the two is the first filter in any search for new particles. ## The table Simulated particle collisions with the measured momentum of each particle and a set of derived masses, labelled signal or background. It's in Welt's research catalogue as Higgs Boson Detection Data (Monte Carlo Simulation), 98,050 rows by 29 columns, licensed Public. The catalogue measures its signal at 0.63. At 98,050 rows and 28 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Higgs boson detection", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A signal score per event**: Every collision gets a probability of being a Higgs event. **A fast first cut**: Keep the likely events and set the rest aside. **No feature engineering**: The model reads the raw and derived columns as they are. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Higgs boson detection", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Is This Collision a Higgs Boson? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Higgs Boson Detection Data (Monte Carlo Simulation), 98,050 rows - **For:** Particle physicists and ML researchers - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) - [How Will This Student Finish the Course?](https://ergodic.dev/use-cases/student-final-performance.html) --- # Is This Detector Event a Neutrino? Page: https://ergodic.dev/use-cases/neutrino-event-signal.html Was this flash in the MiniBooNE detector caused by the electron neutrino the experiment was looking for? The detector records far more background than signal, so a good filter decides what the physicists get to study. ## The table Events from the MiniBooNE neutrino experiment at Fermilab, each with 50 particle-identification measurements and a signal or background label. It's in Welt's research catalogue as MiniBooNE Particle Event Measurements, 130,064 rows by 51 columns, licensed CC0. The catalogue measures its signal at 0.77. At 130,064 rows and 50 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="MiniBooNE particle", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per event**: Sort events from most to least signal-like. **Background removed**: Spend analysis time on the events that matter. **Wide tables handled**: Fifty measurements go in without picking features first. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "MiniBooNE particle", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Is This Detector Event a Neutrino? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** MiniBooNE Particle Event Measurements, 130,064 rows - **For:** Particle physicists and detector analysts - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) - [How Will This Student Finish the Course?](https://ergodic.dev/use-cases/student-final-performance.html) --- # How Well Will This Compound Dissolve in Water? Page: https://ergodic.dev/use-cases/aqueous-solubility.html From descriptors computed from its structure, what is this compound's solubility in water? Poorly soluble drug candidates fail late and expensively, so chemists screen for it early. ## The table 9,982 compounds with 2D molecular descriptors computed by RDKit and their measured aqueous solubility (log S). It's in Welt's research catalogue as AqSolDB Aqueous Solubility Dataset, 9,982 rows by 25 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.74. At 9,982 rows and 24 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="AqSolDB aqueous solubility", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A solubility estimate**: For any compound you can describe. **Earlier screening**: Drop poorly soluble candidates before synthesis. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "AqSolDB aqueous solubility", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** How Well Will This Compound Dissolve in Water? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** AqSolDB Aqueous Solubility Dataset, 9,982 rows - **For:** Medicinal chemists and materials scientists - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) - [How Will This Student Finish the Course?](https://ergodic.dev/use-cases/student-final-performance.html) --- # Is This Glass from a Building Window? Page: https://ergodic.dev/use-cases/glass-type.html From its refractive index and oxide contents, is this glass fragment the most common type, building window glass? Forensic teams use exactly this kind of test on glass left at a scene. ## The table 214 glass samples with refractive index and the share of sodium, magnesium, aluminium, silicon and other oxides, labelled by whether they're the majority type. It's in Welt's research catalogue as Glass Binarized, 214 rows by 10 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.60. At 214 rows and 9 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="glass binarized", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per fragment**: Window glass or not. **Small data handled**: Every model in the collection can take 214 rows. **A classic forensic table**: Compare with published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "glass binarized", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Is This Glass from a Building Window? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Glass Binarized, 214 rows - **For:** Forensic scientists and materials students - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) - [How Will This Student Finish the Course?](https://ergodic.dev/use-cases/student-final-performance.html) --- # Which Way Will the Scale Tip? Page: https://ergodic.dev/use-cases/balance-scale.html Given the weight and distance on each side, does the scale tip left, tip right or balance? There's a simple rule behind it, so you can see whether a model finds it. ## The table 625 set-ups of a balance scale, with weight and distance on each side, labelled left, right or balanced. It's in Welt's research catalogue as Balance Scale, 625 rows by 5 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.51. At 625 rows and 4 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="balance scale", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A result per set-up**: With a probability for each outcome. **A known rule**: Check the model against the physics. **Small data handled**: Three of the four models take all 625 set-ups. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "balance scale", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Which Way Will the Scale Tip? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Balance Scale, 625 rows - **For:** Teachers, students and anyone new to machine learning - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [How Will This Student Finish the Course?](https://ergodic.dev/use-cases/student-final-performance.html) --- # How Will This Student Finish the Course? Page: https://ergodic.dev/use-cases/student-final-performance.html From earlier marks and study habits, family support and wellbeing, which performance class will this postgraduate student end up in? Tutors want to know who needs help while there's still time. ## The table 3,892 postgraduate students with earlier marks and study, family and wellbeing factors, and their final performance class. It's in Welt's research catalogue as Student Performance Analysis 1, 3,892 rows by 36 columns, licensed CC0. The catalogue measures its signal at 0.56. At 3,892 rows and 35 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="student performance analysis", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A predicted class**: For each student, with a probability. **Help where it's needed**: Contact the students most at risk. **A clear signal**: The catalogue measures a good signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "student performance analysis", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** How Will This Student Finish the Course? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Student Performance Analysis 1, 3,892 rows - **For:** University staff and education researchers - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) --- # Did This Really Happen, or Was It Imagined? Page: https://ergodic.dev/use-cases/recalled-or-imagined-story.html From the writer's ratings, the time they took and the event they described, is this story a real memory, an imagined one or a retelling? It's a window on how memory and imagination differ. ## The table 6,854 stories with the writer's ratings of the event, timing, a summary and demographics, labelled recalled, imagined or retold. It's in Welt's research catalogue as Human Memory and Cognition Storytelling Dataset, 6,854 rows by 23 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.74. At 6,854 rows and 22 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="human memory cognition storytelling", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A label per story**: Recalled, imagined or retold, with a probability. **How memory differs**: Compare models to see what separates them. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "human memory cognition storytelling", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Did This Really Happen, or Was It Imagined? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Human Memory and Cognition Storytelling Dataset, 6,854 rows - **For:** Psychologists and language researchers - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) --- # Which Sentence Answers the Question? Page: https://ergodic.dev/use-cases/reading-relevance.html From how a reader's eyes moved over a word, is it irrelevant, relevant, or part of the answer they were looking for? Search tools could one day use gaze to learn what people find useful. ## The table Words read by people answering questions, with fixation, saccade and pupil measures, labelled irrelevant, relevant or correct answer. It's in Welt's research catalogue as Eye Movements Relevance, 10,936 rows by 28 columns, licensed Public. The catalogue measures its signal at 0.44. At 10,936 rows and 27 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="eye movements relevance", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A label per word**: With a probability for each class. **Gaze as feedback**: See how much eye movements reveal. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "eye movements relevance", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Science - **Question:** Which Sentence Answers the Question? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Eye Movements Relevance, 10,936 rows - **For:** Cognitive scientists and search-engine researchers - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Science - [Is This Telescope Flash a Gamma Ray?](https://ergodic.dev/use-cases/gamma-ray-telescope.html) - [Is This Collision a Higgs Boson?](https://ergodic.dev/use-cases/higgs-boson-signal.html) - [Is This Detector Event a Neutrino?](https://ergodic.dev/use-cases/neutrino-event-signal.html) - [How Well Will This Compound Dissolve in Water?](https://ergodic.dev/use-cases/aqueous-solubility.html) - [Is This Glass from a Building Window?](https://ergodic.dev/use-cases/glass-type.html) - [Which Way Will the Scale Tip?](https://ergodic.dev/use-cases/balance-scale.html) --- # Which Heuristic Will Prove This Theorem Fastest? Page: https://ergodic.dev/use-cases/theorem-proving-heuristic.html A theorem prover has several search heuristics, and the right one depends on the problem. Picking it from the problem's features before the search starts can save hours of compute. ## The table 2,000 first-order problems, each described by 51 numeric features, with the heuristic that solved it fastest as the label. It's in Welt's research catalogue as First-Order Theorem Proving, 2,000 rows by 52 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.31. At 2,000 rows and 51 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="first-order theorem proving", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A heuristic per problem**: Choose the search strategy before the prover starts. **An honest signal**: The catalogue measures a modest signal here, so the baseline comparison matters. **Compute saved**: Better first picks mean fewer wasted runs. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "first-order theorem proving", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** Which Heuristic Will Prove This Theorem Fastest? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** First-Order Theorem Proving, 2,000 rows - **For:** Researchers in automated reasoning and algorithm selection - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) - [Will This Kaggle Dataset Win a Medal?](https://ergodic.dev/use-cases/kaggle-dataset-medal.html) --- # How Well Will This Optimiser Do on a New Problem? Page: https://ergodic.dev/use-cases/optimiser-performance.html Before running an expensive optimiser, can you predict how well it will do from the landscape of the problem? A good prediction lets you pick the right algorithm without trying them all. ## The table 1,120 benchmark problems described by 45 landscape-analysis features, with DiagonalCMA's AUCC performance score as the number to predict. It's in Welt's research catalogue as MA-BBOB Algorithm Performance (DiagonalCMA), 1,120 rows by 46 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.44. At 1,120 rows and 45 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="MA-BBOB DiagonalCMA", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted score**: Know roughly how the optimiser will do before you run it. **Algorithm choice**: Compare predictions across optimisers to pick one. **Fewer wasted runs**: Skip runs that are predicted to fail. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "MA-BBOB DiagonalCMA", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** How Well Will This Optimiser Do on a New Problem? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** MA-BBOB Algorithm Performance (DiagonalCMA), 1,120 rows - **For:** Optimisation and AutoML researchers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) - [Will This Kaggle Dataset Win a Medal?](https://ergodic.dev/use-cases/kaggle-dataset-medal.html) --- # How Long Will the Solver Take to Tidy This Container Yard? Page: https://ergodic.dev/use-cases/container-solver-runtime.html Before a port's planner runs a solver to reorder its stacked containers, can it tell how long the solver will take? Knowing the runtime up front stops an overnight job from running into the morning shift. ## The table Container pre-marshalling problems, each described by its features and the solver used, with the time the solver took. It's in Welt's research catalogue as Container Pre-Marshalling Algorithm Runtimes (CPMP 2015), 2,108 rows by 27 columns, licensed Public. The catalogue measures its signal at 0.37. At 2,108 rows and 26 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="container pre-marshalling", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted runtime**: Seconds per problem and solver, before you run it. **Better scheduling**: Fit the slow jobs into the quiet hours. **An honest signal**: The catalogue measures a modest signal, and the baseline comparison shows how much it helps. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "container pre-marshalling", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** How Long Will the Solver Take to Tidy This Container Yard? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Container Pre-Marshalling Algorithm Runtimes (CPMP 2015), 2,108 rows - **For:** Logistics and operations researchers - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) - [Will This Kaggle Dataset Win a Medal?](https://ergodic.dev/use-cases/kaggle-dataset-medal.html) --- # Is This Website a Phishing Site? Page: https://ergodic.dev/use-cases/phishing-website.html From 30 features of its URL, page content and outside services, is this website trying to steal logins? A good score lets a browser warn people before they type a password. ## The table 11,055 websites with features such as URL length, use of an IP address, SSL state, domain age and page links, labelled phishing or legitimate. It's in Welt's research catalogue as Phishing Websites, 11,055 rows by 31 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.91. At 11,055 rows and 30 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 4,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="phishing websites", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 4,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(4000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A phishing probability**: For any site you can describe. **Earlier warnings**: Block the riskiest sites first. **A very strong signal**: The catalogue measures one of its highest signals. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "phishing websites", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** Is This Website a Phishing Site? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Phishing Websites, 11,055 rows - **For:** Security analysts and browser developers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) - [Will This Kaggle Dataset Win a Medal?](https://ergodic.dev/use-cases/kaggle-dataset-medal.html) --- # Is This Email Spam? Page: https://ergodic.dev/use-cases/spam-email.html From how often certain words and characters appear and how long its runs of capitals are, is this email spam? It's the table generations of spam filters were tested on. ## The table 4,601 emails with 57 word, character and capital-letter features, labelled spam or not. It's in Welt's research catalogue as Spambase, 4,601 rows by 58 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.90. At 4,601 rows and 57 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="spambase", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A spam probability**: For each email. **A threshold you choose**: Trade missed spam against lost mail using the out-of-fold scores. **A very strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "spambase", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** Is This Email Spam? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Spambase, 4,601 rows - **For:** Email providers and security teams - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) - [Will This Kaggle Dataset Win a Medal?](https://ergodic.dev/use-cases/kaggle-dataset-medal.html) --- # How Badly Does This Java Class Need Refactoring? Page: https://ergodic.dev/use-cases/code-smell-severity.html From size and complexity metrics, how severe is this class's data-class smell, a class that holds data but does little with it? Teams use the score to decide what to clean up first. ## The table Java classes from open-source projects with size, coupling and complexity metrics, and a severity score for the data-class smell. It's in Welt's research catalogue as Code Smells Data Class, 86,467 rows by 74 columns, licensed Public. The catalogue measures its signal at 0.37. At 86,467 rows and 73 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="code smells data class", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A severity per class**: Rank the codebase for refactoring. **Wide tables handled**: Seventy-three metrics go in without selection. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "code smells data class", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** How Badly Does This Java Class Need Refactoring? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Code Smells Data Class, 86,467 rows - **For:** Software engineers and engineering managers - **Licence:** Public - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [Will This Kaggle Dataset Win a Medal?](https://ergodic.dev/use-cases/kaggle-dataset-medal.html) --- # Will This Kaggle Dataset Win a Medal? Page: https://ergodic.dev/use-cases/kaggle-dataset-medal.html From its usability score, files, size, keywords, views, downloads and dates, which medal will this dataset get, if any? Publishers want to know what makes a dataset useful to others. ## The table 5,717 Kaggle datasets with usability, file count, size, keywords, views, downloads and dates, and the medal each received. It's in Welt's research catalogue as Hottest Kaggle Datasets, 5,717 rows by 15 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.44. At 5,717 rows and 14 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="hottest Kaggle datasets", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A medal prediction**: With a probability for each outcome. **What gets noticed**: Compare models to see which features matter. **Text columns handled**: Keywords and dates go in as they are. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "hottest Kaggle datasets", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** Will This Kaggle Dataset Win a Medal? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Hottest Kaggle Datasets, 5,717 rows - **For:** Data publishers and community managers - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) --- # Is This Part of the Page Text, a Picture or a Line? Page: https://ergodic.dev/use-cases/page-layout-blocks.html From the shape of a block on a scanned page and how much black ink it holds, is it text, a horizontal line, a graphic, a vertical line or a picture? Getting this right is the first step in reading a document automatically. ## The table 5,473 blocks from scanned documents with height, length, area, eccentricity and black-pixel measures, labelled by block type. It's in Welt's research catalogue as Page Blocks, 5,473 rows by 11 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.78. At 5,473 rows and 10 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="page blocks", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A type per block**: With a probability for each type. **Rare blocks checked**: Per-class scores show how pictures and lines are handled. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "page blocks", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Technology - **Question:** Is This Part of the Page Text, a Picture or a Line? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Page Blocks, 5,473 rows - **For:** Document-processing engineers - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Technology - [Which Heuristic Will Prove This Theorem Fastest?](https://ergodic.dev/use-cases/theorem-proving-heuristic.html) - [How Well Will This Optimiser Do on a New Problem?](https://ergodic.dev/use-cases/optimiser-performance.html) - [How Long Will the Solver Take to Tidy This Container Yard?](https://ergodic.dev/use-cases/container-solver-runtime.html) - [Is This Website a Phishing Site?](https://ergodic.dev/use-cases/phishing-website.html) - [Is This Email Spam?](https://ergodic.dev/use-cases/spam-email.html) - [How Badly Does This Java Class Need Refactoring?](https://ergodic.dev/use-cases/code-smell-severity.html) --- # Who Wins from This Connect Four Position? Page: https://ergodic.dev/use-cases/connect-four-outcome.html From the 42 cells of the board, does the first player win, lose or draw with perfect play? Learning game outcomes from positions alone is a hard test for any model. ## The table 67,557 Connect Four positions after eight moves, with the state of every cell and the result under perfect play. It's in Welt's research catalogue as Connect-4 Board States, 67,557 rows by 43 columns, licensed MIT (PMLB collection). The catalogue measures its signal at 0.34. At 67,557 rows and 42 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="connect-4", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **An outcome per position**: Win, loss or draw, with a probability. **A hard test**: The catalogue measures a modest signal for such a rule-bound game. **A classic benchmark**: Compare with published results. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "connect-4", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** Who Wins from This Connect Four Position? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Connect-4 Board States, 67,557 rows - **For:** Game AI researchers and puzzle fans - **Licence:** MIT (PMLB collection) - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) - [What Position Does This Footballer Play?](https://ergodic.dev/use-cases/football-player-position.html) --- # Will the Blue Team Win This League of Legends Match? Page: https://ergodic.dev/use-cases/league-of-legends-win.html From gold, minions, levels, kills and objectives at the 15-minute mark, will the blue team win? Analysts want to know how much the early game decides. ## The table 48,651 Diamond-ranked matches with each team's gold, minions, levels, kills and objectives at 15 minutes, and which side won. It's in Welt's research catalogue as League of Legends Diamond Matches: First 15 Minutes, 48,651 rows by 19 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.52. At 48,651 rows and 18 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 8,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="League of Legends diamond matches 15 minutes", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 8,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(8000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A win probability**: For any game state at 15 minutes. **How early it's decided**: The score shows how much the first 15 minutes tell you. **Calibrated odds**: Check the Brier score before quoting a percentage. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "League of Legends diamond matches 15 minutes", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** Will the Blue Team Win This League of Legends Match? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** League of Legends Diamond Matches: First 15 Minutes, 48,651 rows - **For:** Esports analysts and players - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) - [What Position Does This Footballer Play?](https://ergodic.dev/use-cases/football-player-position.html) --- # Will We Win This Overwatch Match? Page: https://ergodic.dev/use-cases/overwatch-match-result.html From the season, map, role, characters and both teams' skill ratings before the match, will this game be won? Players want to know which picks and maps suit them. ## The table 3,266 competitive matches logged by one player over seven seasons, with map, role, characters and team ratings, and the result. It's in Welt's research catalogue as Overwatch Competitive Matches (Seven Seasons), 3,266 rows by 47 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.67. At 3,266 rows and 46 features the table is larger than the model limits allow, so the walkthrough evaluates and fits on a seeded sample of 2,000 rows. TabICLv2 and Kumo Tabular Medium compete. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Overwatch competitive matches", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end. The models learn from a seeded sample of 2,000 of the rest, the most this table's width allows. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index).sample(2000, random_state=7) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A win probability**: Before the match starts. **Best maps and picks**: Compare predictions across choices. **A clear signal**: The catalogue measures a good signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Overwatch competitive matches", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** Will We Win This Overwatch Match? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** Overwatch Competitive Matches (Seven Seasons), 3,266 rows - **For:** Esports players and analysts - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) - [What Position Does This Footballer Play?](https://ergodic.dev/use-cases/football-player-position.html) --- # Which League Does This StarCraft II Player Belong In? Page: https://ergodic.dev/use-cases/starcraft-league.html From actions per minute, hotkey use, reaction cycles and hours played, which league is this player in? Researchers use it to study how expertise shows up in fast decisions. ## The table 3,395 StarCraft II players with in-game measures of speed, hotkey use and attention, plus age and hours played, and their league. It's in Welt's research catalogue as SkillCraft1 Master Table: StarCraft 2 Player Performance, 3,395 rows by 20 columns, licensed CC BY 4.0. The catalogue measures its signal at 0.31. At 3,395 rows and 19 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="SkillCraft1 StarCraft 2", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A league per player**: With a probability for each league. **What separates the best**: Compare models to see which skills matter. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "SkillCraft1 StarCraft 2", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** Which League Does This StarCraft II Player Belong In? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** SkillCraft1 Master Table: StarCraft 2 Player Performance, 3,395 rows - **For:** Esports coaches and cognitive scientists - **Licence:** CC BY 4.0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) - [What Position Does This Footballer Play?](https://ergodic.dev/use-cases/football-player-position.html) --- # Is This Pokémon Legendary? Page: https://ergodic.dev/use-cases/pokemon-legendary.html From its types, base stats, size, capture rate and egg steps, is this Pokémon legendary? It's a fun table with a real lesson: some columns give the answer away. ## The table 1,013 Pokémon with types, base stats, height, weight, capture rate, egg steps and more, labelled legendary or not. It's in Welt's research catalogue as Pokemon Dataset 2020, 1,013 rows by 40 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.81. At 1,013 rows and 39 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Pokemon 2020", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A probability per Pokémon**: Legendary or not. **A strong signal**: The catalogue measures a high signal. **A lesson in leakage**: Check whether one column does all the work. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Pokemon 2020", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** Is This Pokémon Legendary? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Pokemon Dataset 2020, 1,013 rows - **For:** Game fans and anyone new to machine learning - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) - [What Position Does This Footballer Play?](https://ergodic.dev/use-cases/football-player-position.html) --- # What Will Critics Score This 3DS Game? Page: https://ergodic.dev/use-cases/3ds-metacritic-score.html From user ratings, playtime, ownership counts, tags and genres, what Metacritic score did this Nintendo 3DS game get? With 138 games, it's a test of how far a tiny table can go. ## The table 138 Nintendo 3DS games with user ratings, playtime, owners, tags and genres, and their Metacritic score. It's in Welt's research catalogue as Nintendo 3DS Games, 138 rows by 21 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.36. At 138 rows and 20 features, TabICLv2, Kumo Tabular Medium, Mitra-v2 and TabDPT 1.3 take the table as it is. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="Nintendo 3DS games", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2", "tabdpt-1.3"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted score**: For each game. **Tiny data handled**: Every model in the collection can take 138 rows. **An honest signal**: The catalogue measures a modest signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "Nintendo 3DS games", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** What Will Critics Score This 3DS Game? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2, TabDPT 1.3 - **Data:** Nintendo 3DS Games, 138 rows - **For:** Game publishers and players - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Position Does This Footballer Play?](https://ergodic.dev/use-cases/football-player-position.html) --- # What Position Does This Footballer Play? Page: https://ergodic.dev/use-cases/football-player-position.html From age, height and per-match statistics, does this player play as a goalkeeper, defender, midfielder or forward? Scouts use the same idea to find players who could switch roles. ## The table 3,611 players with age, height and per-match performance statistics, labelled by position. It's in Welt's research catalogue as Football Player Position, 3,611 rows by 12 columns, licensed CC0. The catalogue measures its signal at 0.78. At 3,611 rows and 11 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="football player position", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. ROC AUC runs from 0.5, a coin toss, to 1, a perfect ranking, and a lower Brier score means the probabilities can be trusted more. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="classification", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "roc_auc_mean", "brier_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features), "probability": model.predict_proba(features).max(axis=1)})) ``` ## What you get **A position per player**: With a probability for each role. **Players who fit two roles**: Look for players split between positions. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "football player position", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** What Position Does This Footballer Play? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Football Player Position, 3,611 rows - **For:** Football scouts and analysts - **Licence:** CC0 - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) --- # What Will This Film Score on IMDb? Page: https://ergodic.dev/use-cases/imdb-rating.html From its year, genre, runtime, votes, box office, Metascore and director, what IMDb rating did this film get? It's a fun way to see how much critics and audiences agree. ## The table 5,834 films released from 1972 to 2019 with year, genre, runtime, votes, revenue, Metascore and director, and the IMDb rating. It's in Welt's research catalogue as IMDB Movies 1972-2019, 5,834 rows by 12 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.60. At 5,834 rows and 11 features, TabICLv2 and Kumo Tabular Medium take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="IMDB movies 1972-2019", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted rating**: For any film you can describe. **Critics and crowds**: See how much the Metascore predicts the audience. **Text columns handled**: Genres and directors go in as they are. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "IMDB movies 1972-2019", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** What Will This Film Score on IMDb? - **Model:** TabICLv2, Kumo Tabular Medium - **Data:** IMDB Movies 1972-2019, 5,834 rows - **For:** Film fans, studios and data journalists - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html) --- # How Will Viewers Rate This Anime? Page: https://ergodic.dev/use-cases/anime-rating.html From its media type, episodes, years, studio, content warnings and viewing counts, what average rating does this title get on Anime-Planet? Streaming teams use estimates like this to pick what to license. ## The table 3,767 anime titles with media type, episode count, years aired, studios, warnings and viewer counts, and the average rating. It's in Welt's research catalogue as Anime Dataset from Anime-Planet, 3,767 rows by 18 columns, licensed CC0: Public Domain. The catalogue measures its signal at 0.76. At 3,767 rows and 17 features, TabICLv2, Kumo Tabular Medium and Mitra-v2 take the table as it is. The others can't take a table this size, so the walkthrough leaves them out. ## Walkthrough 1. ### Load it from the catalogue Find the table, read its recorded target and print the column names. ``` import pandas as pd from welt import Client with Client() as client: item = client.research_datasets(q="anime-planet", limit=1)["items"][0] info = client.research_dataset(item["id"]) data = client.load_research_dataset(item["id"]) target = info["targets"][0] target = target["name"] if isinstance(target, dict) else target print([column["name"] for column in info["schema"]], target) ``` 2. ### Pick the rows Set aside 20 rows to predict at the end, and keep the rest for the models to learn from. ``` known = data.dropna(subset=[target]) new_rows = known.sample(20, random_state=1) table = known.drop(new_rows.index) ``` 3. ### Compare the models and predict The models compete on the same folds against a simple guess, then the top-ranked one is fitted on the whole table. RMSE and MAE are average errors in the target's own units, so lower is better. The last table puts each prediction next to the real answer. ``` with Client() as client: evaluation = client.evaluate(table, target, task="regression", seed=7, models=["tabicl-v2", "kumo-medium", "mitra-v2"]) model = evaluation.fit() print(evaluation.summary()[["name", "rank", "rmse_mean", "mae_mean"]]) features = new_rows.drop(columns=target) print(pd.DataFrame({"actual": new_rows[target].values, "predicted": model.predict(features)})) ``` ## What you get **A predicted rating**: For any title. **What fans value**: Compare predictions across studios and formats. **A strong signal**: The catalogue measures a high signal. ## Try it Use Open with to run the research datasets notebook in Colab, Kaggle or Jupyter and search for "anime-planet", or run the code above after `pip install "welt-client[parquet]"`. - **Type:** Use case - **Area:** Media and games - **Question:** How Will Viewers Rate This Anime? - **Model:** TabICLv2, Kumo Tabular Medium, Mitra-v2 - **Data:** Anime Dataset from Anime-Planet, 3,767 rows - **For:** Anime fans, streaming teams and data journalists - **Licence:** CC0: Public Domain - [Google Colab: Run the notebook in your browser](https://colab.research.google.com/github/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Kaggle: Import the notebook into Kaggle](https://www.kaggle.com/kernels/welcome?src=https://github.com/ergodic-ai/welt-python/blob/1ffb86d1bd5e3575a00b245d594b0f705e518689/examples/notebooks/research-datasets.ipynb) - [Jupyter: Download the .ipynb file and run it locally](https://ergodic-ai.github.io/welt-python/downloads/research-datasets.ipynb) - [Read it first: The formatted notebook in the Welt docs](https://ergodic-ai.github.io/welt-python/notebook-research-datasets.html) - [Your AI assistant: Connect Claude, ChatGPT, Cursor or VS Code to Welt](https://welt.ergodic.dev/agents/mcp.md) - [Welt console: Sign in and find the table in the research catalogue](https://welt.ergodic.dev/) ## More in Media and games - [Who Wins from This Connect Four Position?](https://ergodic.dev/use-cases/connect-four-outcome.html) - [Will the Blue Team Win This League of Legends Match?](https://ergodic.dev/use-cases/league-of-legends-win.html) - [Will We Win This Overwatch Match?](https://ergodic.dev/use-cases/overwatch-match-result.html) - [Which League Does This StarCraft II Player Belong In?](https://ergodic.dev/use-cases/starcraft-league.html) - [Is This Pokémon Legendary?](https://ergodic.dev/use-cases/pokemon-legendary.html) - [What Will Critics Score This 3DS Game?](https://ergodic.dev/use-cases/3ds-metacritic-score.html)