Chocolate Sales: EDA to ML in Two Kaggle Notebooks

Updated Feb 13, 2026

Kaggle’s Chocolate Sales dataset is a clean, well-structured dataset with 3,282 transactions across 6 countries, 18 products, and 25 sales representatives — perfect for both visual exploration and predictive modeling.

I built two notebooks on this dataset: one focused on exploratory data analysis (EDA) and another on ML & deep learning prediction. Here’s what I found, how I built it, and what you can learn from each.

The Dataset at a Glance

Column Type Example
Sales Person Categorical (25 unique) Kelci Walkden
Country Categorical (6 unique) Australia, India, UK, USA, Canada, New Zealand
Product Categorical (18 unique) 85% Dark Bars, Milk Bars, Drinking Coco
Date Datetime 01/01/2022 – 31/12/2024
Amount Currency string “$5,320.00”
Boxes Shipped Integer 42

The Amount field comes as a formatted currency string — stripping $ and , is the first cleaning step. Dates are in DD/MM/YYYY format, which catches many people off guard when using pd.to_datetime with default settings.

EDA Notebook: Visual Exploration with Plotly

View the full EDA notebook on Kaggle →

The EDA notebook covers 12 sections, all with interactive Plotly charts using a chocolate-inspired color palette (#5B3A29, #8B6914, #D2691E, #CD853F, #DEB887).

Key Findings

Revenue Distribution: The data is right-skewed — most transactions cluster in the low-to-mid range, with a long tail of high-value sales. This is typical for B2B sales data and important to know before modeling (it tells us mean ≠ median).

Country Analysis: Revenue varies significantly across markets. We looked at both total revenue (market size) and average transaction size (spending intensity) — a country can rank high in one but not the other.

The Surprising Correlation: Revenue vs. Boxes Shipped has a correlation of -0.013 — essentially zero. Higher volume does not mean higher revenue. This means pricing is highly variable across products and markets, and any ML model that relies too heavily on Boxes Shipped will miss the real signal.

Product × Country Heatmap: Cultural preferences for chocolate vary. The heatmap reveals which products sell best in which countries — useful for localized product strategies. Sunburst and treemap charts break down the top 10 sales people by their country and product mix.

Seasonality: Monthly and day-of-week patterns were analyzed. Holiday months (February, April, December) were highlighted to check for Valentine’s Day, Easter, and Christmas effects.

Enjoying this article? Get more like it delivered to your inbox. Subscribe to the newsletter

ML & Deep Learning Notebook: 4 Models Compared

View the full ML notebook on Kaggle →

The goal: predict Amount (revenue) from all other features. We built 4 models progressively, from a simple baseline to a neural network.

Feature Engineering (26 Features)

Raw data rarely works well for ML. Here’s what we built:

Feature Type Count Examples
Date decomposition 7 Year, Month, DayOfWeek, Quarter, WeekOfYear, IsWeekend
Cyclical encoding 6 sin/cos of Month, DayOfWeek, DayOfMonth
Label encoding 4 Sales Person, Country, Product, Country×Product
Target encoding 4 Mean revenue per category
Frequency encoding 3 How often each category appears
Boxes features 3 Raw, log-transformed, squared

Cyclical encoding deserves special mention: if Month is encoded as 1–12, the model thinks December (12) is far from January (1). Using sin(2π × month/12) and cos(2π × month/12) preserves the circular relationship.

Model 1: Ridge Regression (Baseline)

Linear regression with L2 regularization (alpha=1.0). Features are standardized with StandardScaler before training — this is critical for linear models where feature scales affect coefficient magnitudes.

This sets the floor: any model that can’t beat a straight line isn’t worth the complexity.

Model 2: Random Forest

An ensemble of 300 decision trees, each trained on a random subset of data and features:

n_estimators=300, max_depth=12, min_samples_leaf=5,
max_features=0.7, n_jobs=-1

max_depth=12 prevents individual trees from memorizing the training data. min_samples_leaf=5 ensures each leaf has enough data to make a reliable prediction. max_features=0.7 means each tree only sees 70% of features, forcing diversity.

Model 3: XGBoost

Gradient boosting — the state-of-the-art for tabular data:

n_estimators=1000, learning_rate=0.05, max_depth=6,
subsample=0.8, colsample_bytree=0.8,
reg_alpha=0.1, reg_lambda=1.0,
min_child_weight=10, tree_method='hist'

Unlike Random Forest (parallel trees), XGBoost builds trees sequentially — each new tree corrects the mistakes of previous ones. learning_rate=0.05 means each tree contributes modestly, requiring more trees (1000) but achieving higher precision. Early stopping prevents overfitting.

Model 4: Neural Network (Keras)

A feedforward network with 3 hidden layers:

Input(26) → Dense(256) + BatchNorm + ReLU + Dropout(0.3)
         → Dense(128) + BatchNorm + ReLU + Dropout(0.2)
         → Dense(64)  + BatchNorm + ReLU + Dropout(0.1)
         → Dense(1)

Training configuration:

  • Optimizer: Adam (lr=1e-3)
  • Loss: MSE
  • Callbacks: EarlyStopping (patience=20), ReduceLROnPlateau (factor=0.5, patience=10, min_lr=1e-6)
  • Batch size: 64, max 200 epochs

BatchNormalization normalizes each layer’s input, dramatically speeding up convergence. Dropout randomly disables neurons during training — effectively training an ensemble of sub-networks within one model.

Ensembles

Three ensemble strategies were tested:

  1. Simple average — equal weight to all 4 models
  2. Weighted average — weights proportional to inverse MAE (better model → higher weight)
  3. Top-3 blend — average of the 3 best models, dropping the weakest

Evaluation: 5-Fold Cross-Validation

All models evaluated with the same 5-fold CV split (KFold, shuffle=True, seed=42). Three metrics reported:

  • MAE — average prediction error in dollars
  • RMSE — penalizes large errors more heavily
  • R² — 1.0 = perfect, 0.0 = predicting the mean

Results Visualization

The notebook includes:

  • MAE/R² bar charts comparing all models side by side
  • Predicted vs Actual scatter plots for each model (with perfect-prediction reference line)
  • Error distribution histograms — overlaid for all 4 models to compare error shapes
  • XGBoost feature importance — top 15 features ranked by split importance

Key Takeaway

Tree-based models (XGBoost, Random Forest) outperform both linear regression and neural networks on this dataset. This is consistent with Grinsztajn et al. (NeurIPS 2022), which showed tree-based models dominate on tabular data under ~50K rows. Feature engineering — especially target encoding — provides more lift than switching model architectures.

Try It Yourself

Both notebooks are public and ready to fork:

The dataset is small enough to run entirely on CPU in under 5 minutes. No GPU needed.

FAQ

What Python libraries are needed for these notebooks?

Both notebooks use pandas, numpy, and plotly for visualization. The ML notebook additionally requires scikit-learn, xgboost, and tensorflow (Keras). All are pre-installed in the Kaggle environment — no extra setup needed.

Why does the neural network underperform XGBoost on this dataset?

With only 3,282 rows, there isn’t enough data for a neural network to learn complex patterns that tree-based models capture naturally. Neural networks typically need 50K+ rows to outperform gradient boosting on tabular data. The 2022 NeurIPS benchmark by Grinsztajn et al. confirmed this finding across 45 datasets.

Can I use these notebooks for a different sales dataset?

Yes. The feature engineering pipeline is generic — date decomposition, cyclical encoding, target encoding, and frequency encoding work on any tabular dataset with categorical and datetime columns. Just swap the CSV path and column names.

Did you find this helpful?

Your support keeps this blog running and ad-free content coming.

☕ Buy me a coffee
TODAY 617 | TOTAL 141,794