The iFood dataset creates a multi-schema decisioning environment modeled after a food delivery platform’s multi-wave direct marketing campaign. It is the most architecturally complex dataset pack, featuring 3 data tables that join on customer_id, 6 campaign offers, 4 delivery channels, custom outcome types, and a cross-schema segment.
Based on the Kaggle iFood Marketing Campaigns dataset (CC0: Public Domain).
Unlike the single-table Starbucks dataset, iFood is a multi-schema pack: 3 tables that join on customer_id. It demonstrates cross-table predictor joins, 6 custom outcome types (one per campaign wave), Epsilon-Greedy with 6 arms, and cross-schema segment definitions.
What Gets Created
| Entity Type | Count | Details |
|---|
| Schemas | 3 | ifood_customers, ifood_spending, ifood_campaigns |
| Categories | 5 | Campaign 1 through Campaign 5 & Response |
| Channels | 4 | Web, Catalog, Store, Deals |
| Offers | 6 | Campaign 1-5 Offers + Current Response Offer |
| Creatives | 24 | 6 offers x 4 channels |
| Qualification Rules | 0 | None (open targeting) |
| Outcome Types | 6 | accepted_cmp1 through accepted_cmp5 + response |
| Algorithm Models | 2 | Scorecard + Epsilon-Greedy |
| Experiments | 1 | Scorecard (70%) vs Epsilon-Greedy (30%) |
| Segments | 1 | High-Value Spenders (cross-schema join) |
| Customer Rows | 500 | IFOOD-000000 through IFOOD-000499 |
Step-by-Step Walkthrough
curl -X POST "http://localhost:3000/api/v1/seed-dataset/ifood?force=true" \
-H "Content-Type: application/json" \
-H "X-Requested-With: XMLHttpRequest"
Expected Response (201 Created)
{
"message": "iFood Campaigns loaded successfully",
"counts": {
"schemas": 3,
"categories": 5,
"subCategories": 6,
"channels": 4,
"offers": 6,
"creatives": 24,
"qualificationRules": 0,
"contactPolicies": 0,
"outcomeTypes": 6,
"models": 2,
"experiments": 1,
"decisionFlows": 1,
"segments": 1,
"ifood_customers_rows": 500,
"ifood_spending_rows": 500,
"ifood_campaigns_rows": 500,
"interactions": 500,
"interactionSummaries": 500
},
"datasetKey": "ifood"
}
Explore the Multi-Schema Architecture
The 3-table architecture is the defining feature of iFood:
curl "http://localhost:3000/api/v1/schemas" \
-H "X-Requested-With: XMLHttpRequest"
ifood_customers ifood_spending ifood_campaigns
─────────────── ────────────── ───────────────
customer_id (PK) ────> customer_id (PK) ────> customer_id (PK)
income wines accepted_cmp1
education fruits accepted_cmp2
marital_status meat accepted_cmp3
age fish accepted_cmp4
kidhome sweets accepted_cmp5
teenhome gold response
dt_customer total_spend complain
recency_days deals_purchases
web_purchases
catalog_purchases
store_purchases
web_visits
Get a Recommendation with Cross-Schema Attributes
Pass attributes from all three schemas for cross-schema scoring:
curl -X POST "http://localhost:3000/api/v1/recommend" \
-H "Content-Type: application/json" \
-H "X-Requested-With: XMLHttpRequest" \
-d '{
"customerId": "IFOOD-000042",
"channel": "web",
"limit": 3,
"context": {
"placement": "homepage_banner",
"sessionType": "returning"
},
"customerAttributes": {
"income": 72000,
"education": "PhD",
"marital_status": "Married",
"age": 45,
"kidhome": 1,
"teenhome": 0,
"recency_days": 12,
"total_spend": 1850.50,
"wines": 800.00,
"meat": 650.00,
"web_purchases": 8,
"catalog_purchases": 3,
"store_purchases": 5,
"deals_purchases": 4,
"web_visits": 12,
"accepted_cmp1": 0,
"accepted_cmp2": 1,
"accepted_cmp3": 0,
"accepted_cmp4": 0,
"accepted_cmp5": 1,
"response": 0
}
}'
Expected Response
{
"customerId": "IFOOD-000042",
"recommendations": [
{
"offerId": "...",
"offerName": "iFood: Campaign 1 Offer",
"score": 0.87,
"rank": 1,
"reason": "High income + high spend + recent activity"
},
{
"offerId": "...",
"offerName": "iFood: Campaign 2 Offer",
"score": 0.82,
"rank": 2,
"reason": "Previous campaign 2 acceptance"
},
{
"offerId": "...",
"offerName": "iFood: Current Response Offer",
"score": 0.74,
"rank": 3,
"reason": "Active response target"
}
],
"modelUsed": "ifood-scorecard",
"experimentArm": "champion"
}
Record a Campaign-Specific Outcome
Use the custom outcome types to track per-campaign acceptance:
curl -X POST "http://localhost:3000/api/v1/respond" \
-H "Content-Type: application/json" \
-H "X-Requested-With: XMLHttpRequest" \
-d '{
"customerId": "IFOOD-000042",
"offerId": "<campaign-3-offer-id>",
"creativeId": "<cmp3-web-creative-id>",
"channelId": "<web-channel-id>",
"outcomeTypeKey": "accepted_cmp3",
"interactionType": "conversion",
"direction": "inbound",
"context": {
"source": "web_checkout",
"campaignWave": 3
},
"outcome": {
"key": "accepted_cmp3",
"classification": "positive",
"value": 45.00
}
}'
Preview the Cross-Schema Segment
The High-Value Spenders segment joins
ifood_customers (income >
60k)with‘ifoodspending‘(totalspend>1000):
curl "http://localhost:3000/api/v1/segments/<segmentId>/preview?limit=5" \
-H "X-Requested-With: XMLHttpRequest"
Run a Batch Campaign via Segment
curl -X POST "http://localhost:3000/api/v1/recommend/batch" \
-H "Content-Type: application/json" \
-H "X-Requested-With: XMLHttpRequest" \
-d '{
"segmentId": "<high-value-spenders-segment-id>",
"channel": "catalog",
"limit": 1,
"context": { "campaignRun": "ifood-march-batch" }
}'
Train the Epsilon-Greedy Model
curl -X POST "http://localhost:3000/api/v1/algorithm-models/<epsilon-model-id>/train" \
-H "Content-Type: application/json" \
-H "X-Requested-With: XMLHttpRequest"
curl "http://localhost:3000/api/v1/experiments/<experimentId>/results" \
-H "X-Requested-With: XMLHttpRequest"
Offer Priority Strategy
| Offer | Priority | Strategy |
|---|
| Campaign 1 Offer | 90 | Broad acquisition — highest priority for new customers |
| Campaign 2 Offer | 80 | Refined retargeting based on Campaign 1 learnings |
| Campaign 3 Offer | 70 | Mid-tier customer focus with category promotions |
| Campaign 4 Offer | 65 | Seasonal promo with personalized bundles |
| Campaign 5 Offer | 55 | Re-engagement for lapsed customers |
| Current Response | 50 | Active response — primary Epsilon-Greedy optimization target |
Custom Outcome Types
iFood defines 6 custom outcome types, one per campaign wave:
| Outcome Key | Name | Classification |
|---|
accepted_cmp1 | Campaign 1 Accepted | positive |
accepted_cmp2 | Campaign 2 Accepted | positive |
accepted_cmp3 | Campaign 3 Accepted | positive |
accepted_cmp4 | Campaign 4 Accepted | positive |
accepted_cmp5 | Campaign 5 Accepted | positive |
response | Current Response | positive |
Each outcome type maps 1:1 to a campaign acceptance flag in the ifood_campaigns table. This allows the Epsilon-Greedy model to track which arm (campaign) has the highest conversion rate.
Epsilon-Greedy Model
The iFood Epsilon-Greedy is a 6-armed bandit — one arm per campaign offer:
| Parameter | Value | Description |
|---|
| Arms | 6 | One per campaign (Cmp1-5 + Response) |
| Epsilon | 0.15 | 15% exploration rate (initial) |
| Decay | 0.99 | Epsilon decays by 1% per training cycle |
Arm Rewards (after 500 interactions):
Arm 0: Campaign 1 pulls: 95 reward: 0.18
Arm 1: Campaign 2 pulls: 82 reward: 0.14
Arm 2: Campaign 3 pulls: 110 reward: 0.22 ← BEST
Arm 3: Campaign 4 pulls: 78 reward: 0.12
Arm 4: Campaign 5 pulls: 85 reward: 0.15
Arm 5: Response pulls: 50 reward: 0.16
Experiment: Scorecard vs Epsilon-Greedy
| Arm | Model | Traffic % | Strategy |
|---|
| Champion | iFood: Scorecard Model | 70% | Rule-based scoring (income ≥ 60k,totalspend≥1000, recency ≤ 30 days) |
| Challenger | iFood: Epsilon-Greedy Model | 30% | 6-arm bandit with epsilon=0.15, decay=0.99 |
Auto-promotion is disabled (autoPromote: false). You must manually promote the winner after reviewing results. Wait until the p-value drops below 0.05 and the uplift exceeds 2% before promoting.
What to Look For
- Multi-schema predictors: The Scorecard model uses predictors from all 3 schemas:
income from customers, total_spend from spending, and recency_days from customers.
- Cross-schema segment: The High-Value Spenders segment joins two tables via
customer_id, finding customers with income > 60kANDtotalspend>1000.
- 6 custom outcome types: Per-campaign tracking enables the Epsilon-Greedy model to learn which campaign wave performs best.
- 4 delivery channels: Web (banner), Catalog (print), Store (signage), Deals (webhook) — each with different delivery modes.
- Batch + Segment: The batch endpoint iterates over all customers in the segment, runs the decision pipeline for each, and returns ranked offers for offline campaign targeting.