This is a Machine Learning Lab Manual built on the League of Legends High Diamond Ranked 10-Minute Dataset. Each section of the notebook is a separate hands-on lab covering a core ML concept — from data loading to advanced ensemble methods.
Dataset: high_diamond_ranked_10min.csv
Source: Kaggle — League of Legends Diamond Ranked Games
Task: Binary Classification — Predict which team wins based on the first 10 minutes of gameplay
Can we predict the winner of a League of Legends match using only the first 10 minutes of in-game data?
| Class | Label | Meaning |
|---|---|---|
| 0 | Lose | Blue team loses the match |
| 1 | Win | Blue team wins the match |
The dataset captures economic, combat, and objective stats collected at the 10-minute mark — well before the match ends. This makes it a real prediction problem, not a post-match summary.
ml-lab-manual-lol/
│
├── 📓 Copy_of_ML_Lab_Manual.ipynb ← Main notebook (all labs)
│
├── 📂 data/
│ └── high_diamond_ranked_10min.csv ← Dataset
│
├── 📄 requirements.txt ← All dependencies
├── 📄 README.md ← You are here
└── 📄 .gitignore ← Files to ignore
Dataset: League of Legends High Diamond Ranked 10min
Rows: ~10,000 matches
Features: 38 columns (19 blue team + 19 red team stats)
| Feature | Description |
|---|---|
blueWins |
TARGET — Did blue team win? (0=No, 1=Yes) |
blueGoldDiff |
Gold difference between blue and red team |
blueExperienceDiff |
Experience (XP) difference between teams |
blueKills |
Total kills by blue team in 10 min |
blueDeaths |
Total deaths by blue team |
blueAssists |
Total assists by blue team |
blueTotalGold |
Total gold earned by blue team |
blueTotalExperience |
Total XP earned by blue team |
blueDragons |
Did blue team kill the Dragon? (0/1) |
blueHeralds |
Did blue team kill the Rift Herald? (0/1) |
blueFirstBlood |
Did blue team get first kill? (0/1) |
blueWardsPlaced |
Vision wards placed by blue team |
blueAvgLevel |
Average champion level of blue team |
blueCSPerMin |
Creep score (farm) per minute |
redKills |
Total kills by red team |
redGoldDiff |
Gold difference from red team perspective |
gameId |
Unique match ID (dropped before training) |
| Feature | Formula | Meaning |
|---|---|---|
blueKDA |
(Kills + Assists) / (Deaths + 1) | Combat efficiency |
redKDA |
(Kills + Assists) / (Deaths + 1) | Red team efficiency |
blueObjectives |
Dragons + Heralds | Total objectives secured |
Concepts: Pandas, data inspection, shape, dtypes, missing values
What we do:
- Load the CSV with
pd.read_csv() - Print shape, column names, data types
- Check for missing values with heatmap
- Display first 5 rows and descriptive stats
Key code:
df = pd.read_csv('high_diamond_ranked_10min.csv')
print(df.shape) # (9879, 40)
print(df.info()) # column types
df.isnull().sum() # zero missing valuesConcepts: Outlier handling, duplicate removal, IQR capping
What we do:
- Calculate IQR for
blueGoldDiff - Cap outliers:
clip(lower=Q1-1.5*IQR, upper=Q3+1.5*IQR) - Remove duplicate rows
- Verify no missing values remain
Key code:
Q1, Q3 = df['blueGoldDiff'].quantile([0.25, 0.75])
IQR = Q3 - Q1
df['blueGoldDiff_Capped'] = df['blueGoldDiff'].clip(
lower=Q1 - 1.5*IQR, upper=Q3 + 1.5*IQR
)
df.drop_duplicates(inplace=True)Concepts: Distributions, correlations, relationships, pairplots
Visualizations created:
- Histogram of Gold Difference with KDE
- Boxplot: Experience Difference vs Win Outcome
- Correlation heatmap (5 key features)
- Scatter plot: Kills vs Total Gold (colored by result)
- Bar plot: Win probability based on Dragon kill
- Pairplot of key numeric features
Key insight from EDA:
Teams with positive Gold Difference at 10 minutes win ~65% of matches
Concepts: Creating new features from existing ones
Features engineered:
# Combat efficiency per player
df['blueKDA'] = (df['blueKills'] + df['blueAssists']) / (df['blueDeaths'] + 1)
df['redKDA'] = (df['redKills'] + df['redAssists']) / (df['redDeaths'] + 1)
# Combined objective control
df['blueObjectives'] = df['blueDragons'] + df['blueHeralds']Concepts: Label Encoding, One-Hot Encoding, StandardScaler, MinMaxScaler, RobustScaler
Scaling methods compared:
| Scaler | Formula | When to Use |
|---|---|---|
StandardScaler |
(x - mean) / std | When data is normally distributed |
MinMaxScaler |
(x - min) / (max - min) | When you need values between 0–1 |
RobustScaler |
(x - median) / IQR | When data has many outliers |
Encoding methods:
LabelEncoder— binary columns (0/1 values)pd.get_dummies()— One-Hot Encoding for multi-class
Concepts: Regression on classification data, train/test split, evaluation metrics
⚠️ Note: Linear Regression was applied here as a learning exercise. Logistic Regression or tree models are more appropriate for binary classification.
What we do:
- Split: 70% train / 30% test
- Fit
LinearRegressionon the features - Evaluate with MSE, MAE, R² Score
- Observe predictions (floating point 0–1 range)
Concepts: Probabilistic classification, Laplace smoothing, BernoulliNB
What we do:
- Apply
BernoulliNB(suited for binary features) - Compare without smoothing (alpha=0.0) vs with Laplace smoothing (alpha=1.0)
- Show why smoothing prevents zero-probability issues
Key comparison:
WITHOUT Smoothing (alpha=0.0) → Accuracy: ~72%
WITH Laplace Smoothing (alpha=1.0) → Accuracy: ~73%
✅ Laplace Smoothing performs BETTER (avoids zero probabilities)
Concepts: Density-based clustering, epsilon, min_samples, noise detection
What we do:
- Select 2 features:
blueGoldDiff,blueExperienceDiff - Apply
StandardScaler - Implement custom
euclidean_distance()function from scratch - Run sklearn
DBSCAN(eps=0.5, min_samples=5) - Tune hyperparameters: vary
epsandmin_samples - Evaluate with Silhouette Score and Davies-Bouldin Score
Hyperparameter tuning results:
| eps | Clusters | Noise Points | Silhouette |
|---|---|---|---|
| 0.1 | many | very high | low |
| 0.5 | 1–2 | moderate | best |
| 1.5 | 1 | very low | N/A |
Concepts: Entropy, Information Gain, tree depth, overfitting
What we do:
- Implement
entropy()andinformation_gain()functions from scratch - Train
DecisionTreeClassifier(criterion='entropy', max_depth=3) - Visualize the full decision tree
- Plot top 10 feature importances
- Compare
entropyvsginicriterion - Test different
max_depthvalues
Top features by Information Gain:
blueGoldDiffblueExperienceDiffblueKillsblueDragons
Depth comparison:
max_depth=1 → ~65% accuracy (underfitting)
max_depth=3 → ~73% accuracy (best balance)
max_depth=10 → ~72% accuracy (slight overfit)
max_depth=None → ~68% accuracy (overfit)
Concepts: Bagging, Random Forest, AdaBoost, Gradient Boosting
All 4 ensemble methods compared:
| Method | Type | Train Acc | Test Acc |
|---|---|---|---|
| Decision Tree (Baseline) | Single | ~100% | ~70% |
| Bagging | Bagging | ~99% | ~73% |
| Random Forest | Bagging+Random | ~99% | ~74% |
| AdaBoost | Boosting | ~75% | ~73% |
| Gradient Boosting | Boosting | ~78% | ~74% |
Random Forest tuning:
n_estimators=10 → 71.2%
n_estimators=50 → 73.6%
n_estimators=100 → 74.1% ← sweet spot
n_estimators=200 → 74.2%
n_estimators=300 → 74.1% (plateaus)
git clone https://github.com/YOUR_USERNAME/ml-lab-manual-lol.git
cd ml-lab-manual-lolpip install -r requirements.txtDownload from Kaggle: League of Legends Diamond Ranked Games (10 min)
Place it inside the data/ folder as high_diamond_ranked_10min.csv
jupyter notebook Copy_of_ML_Lab_Manual.ipynb# Step 1 — Upload dataset
from google.colab import files
uploaded = files.upload() # Upload high_diamond_ranked_10min.csv
# Step 2 — Install any missing packages
!pip install scikit-learn pandas matplotlib seaborn -q
# Step 3 — Run all cells top to bottompandas>=1.5.0
numpy>=1.23.0
matplotlib>=3.6.0
seaborn>=0.12.0
scikit-learn>=1.2.0
jupyter>=1.0.0
notebook>=6.5.0
| Lab | Algorithm | Accuracy |
|---|---|---|
| Lab 6 | Linear Regression (baseline) | ~65% |
| Lab 7 | Naïve Bayes (BernoulliNB) | ~73% |
| Lab 9 | Decision Tree (max_depth=3) | ~73% |
| Lab 10 | Bagging | ~73% |
| Lab 10 | AdaBoost | ~73% |
| Lab 10 | Random Forest | ~74% ✅ |
| Lab 10 | Gradient Boosting | ~74% ✅ |
Best Models: Random Forest & Gradient Boosting (~74% accuracy)
| Concept | Lab |
|---|---|
| Data Loading & Inspection | Lab 1 |
| Outlier Detection (IQR) | Lab 2 |
| Data Visualization | Lab 3 |
| Feature Engineering | Lab 4 |
| StandardScaler / MinMax / Robust | Lab 5 |
| Label Encoding / One-Hot Encoding | Lab 5 |
| Train-Test Split | Lab 5–10 |
| Regression Metrics (MSE, MAE, R²) | Lab 6 |
| Naïve Bayes + Laplace Smoothing | Lab 7 |
| DBSCAN Clustering | Lab 8 |
| Entropy & Information Gain | Lab 9 |
| Decision Tree Visualization | Lab 9 |
| Bagging & Boosting | Lab 10 |
| Feature Importance | Lab 9, 10 |
| Tool | Purpose |
|---|---|
| Python 3.8+ | Core language |
| Pandas / NumPy | Data manipulation |
| Matplotlib / Seaborn | Visualization |
| Scikit-learn | All ML models & preprocessing |
| Jupyter Notebook | Interactive lab environment |
CustomBot-UI
Machine Learning Lab — 2026
This project is licensed under the MIT License.
- Dataset: Kaggle — League of Legends Diamond Ranked Games
- Scikit-learn Documentation: https://scikit-learn.org