Spaces:
Running
Running
Commit Β·
5b394bc
1
Parent(s): 87f43b1
update files
Browse files- ml_complete-all-topics/app.js +1709 -107
- ml_complete-all-topics/index.html +1087 -6
ml_complete-all-topics/app.js
CHANGED
|
@@ -1,3 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
// Data
|
| 2 |
const data = {
|
| 3 |
linearRegression: [
|
|
@@ -134,8 +228,18 @@ function initSections() {
|
|
| 134 |
if (section.id === 'hyperparameter-tuning') initHyperparameterTuning();
|
| 135 |
if (section.id === 'naive-bayes') initNaiveBayes();
|
| 136 |
if (section.id === 'kmeans') initKMeans();
|
|
|
|
| 137 |
if (section.id === 'decision-trees') initDecisionTrees();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
if (section.id === 'ensemble-methods') initEnsembleMethods();
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
if (section.id === 'rl-intro') { /* No viz for intro */ }
|
| 140 |
if (section.id === 'q-learning') { /* Add Q-learning viz if needed */ }
|
| 141 |
if (section.id === 'policy-gradient') { /* Add policy gradient viz if needed */ }
|
|
@@ -182,7 +286,7 @@ function initTOCLinks() {
|
|
| 182 |
});
|
| 183 |
ticking = true;
|
| 184 |
}
|
| 185 |
-
});
|
| 186 |
}
|
| 187 |
|
| 188 |
function updateActiveLink() {
|
|
@@ -263,7 +367,12 @@ function drawLinearRegression() {
|
|
| 263 |
});
|
| 264 |
mse /= data.linearRegression.length;
|
| 265 |
|
| 266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
type: 'scatter',
|
| 268 |
data: {
|
| 269 |
datasets: [
|
|
@@ -313,7 +422,7 @@ function drawLinearRegression() {
|
|
| 313 |
}
|
| 314 |
}
|
| 315 |
}
|
| 316 |
-
}, 'Linear Regression
|
| 317 |
}
|
| 318 |
|
| 319 |
// Gradient Descent Visualization
|
|
@@ -429,7 +538,12 @@ function drawGradientDescent(currentStep = -1) {
|
|
| 429 |
const ctx = canvas.getContext('2d');
|
| 430 |
const lossData = state.gdIterations.map((iter, i) => ({ x: i + 1, y: iter.loss }));
|
| 431 |
|
| 432 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
type: 'line',
|
| 434 |
data: {
|
| 435 |
datasets: [{
|
|
@@ -481,17 +595,57 @@ function safeCreateChart(ctx, config, chartName) {
|
|
| 481 |
console.warn(`Canvas context not found for ${chartName}`);
|
| 482 |
return null;
|
| 483 |
}
|
| 484 |
-
|
|
|
|
|
|
|
| 485 |
} catch (error) {
|
| 486 |
console.error(`Chart creation failed for ${chartName}:`, error);
|
| 487 |
-
// Show fallback message
|
| 488 |
-
if (ctx && ctx.canvas && ctx.canvas.parentElement) {
|
| 489 |
-
ctx.canvas.parentElement.innerHTML = `<p style="color: #ff8c6a; text-align: center; padding: 40px;">Visualization temporarily unavailable. Please refresh the page.</p>`;
|
| 490 |
-
}
|
| 491 |
return null;
|
| 492 |
}
|
| 493 |
}
|
| 494 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 495 |
// Initialize everything when DOM is ready
|
| 496 |
function init() {
|
| 497 |
initCategories();
|
|
@@ -502,6 +656,17 @@ function init() {
|
|
| 502 |
setTimeout(() => {
|
| 503 |
initLinearRegression();
|
| 504 |
}, 100);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
}
|
| 506 |
|
| 507 |
if (document.readyState === 'loading') {
|
|
@@ -557,7 +722,10 @@ function initSVMBasic() {
|
|
| 557 |
|
| 558 |
function drawSVMBasic() {
|
| 559 |
const canvas = document.getElementById('svm-basic-canvas');
|
| 560 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 561 |
|
| 562 |
const ctx = canvas.getContext('2d');
|
| 563 |
if (!ctx) {
|
|
@@ -661,6 +829,8 @@ function drawSVMBasic() {
|
|
| 661 |
ctx.font = '13px sans-serif';
|
| 662 |
ctx.textAlign = 'center';
|
| 663 |
ctx.fillText('Xβ', width / 2, height - 20);
|
|
|
|
|
|
|
| 664 |
ctx.save();
|
| 665 |
ctx.translate(20, height / 2);
|
| 666 |
ctx.rotate(-Math.PI / 2);
|
|
@@ -683,7 +853,10 @@ function initSVMMargin() {
|
|
| 683 |
|
| 684 |
function drawSVMMargin() {
|
| 685 |
const canvas = document.getElementById('svm-margin-canvas');
|
| 686 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 687 |
|
| 688 |
const ctx = canvas.getContext('2d');
|
| 689 |
if (!ctx) {
|
|
@@ -804,11 +977,9 @@ let svmCChart = null;
|
|
| 804 |
|
| 805 |
function drawSVMCParameter() {
|
| 806 |
const canvas = document.getElementById('svm-c-canvas');
|
| 807 |
-
if (!canvas)
|
| 808 |
-
|
| 809 |
-
|
| 810 |
-
if (svmCChart) {
|
| 811 |
-
svmCChart.destroy();
|
| 812 |
}
|
| 813 |
|
| 814 |
const ctx = canvas.getContext('2d');
|
|
@@ -902,6 +1073,8 @@ function drawSVMCParameter() {
|
|
| 902 |
const violEl = document.getElementById('violations-count');
|
| 903 |
if (marginEl) marginEl.textContent = marginWidth.toFixed(2);
|
| 904 |
if (violEl) violEl.textContent = violations;
|
|
|
|
|
|
|
| 905 |
}
|
| 906 |
|
| 907 |
function initSVMTraining() {
|
|
@@ -992,7 +1165,10 @@ function updateTrainingInfo(point = null, violation = null) {
|
|
| 992 |
|
| 993 |
function drawSVMTraining() {
|
| 994 |
const canvas = document.getElementById('svm-train-canvas');
|
| 995 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 996 |
|
| 997 |
const ctx = canvas.getContext('2d');
|
| 998 |
if (!ctx) {
|
|
@@ -1060,6 +1236,8 @@ function drawSVMTraining() {
|
|
| 1060 |
ctx.textAlign = 'center';
|
| 1061 |
ctx.fillText(point.label, x, y - 15);
|
| 1062 |
});
|
|
|
|
|
|
|
| 1063 |
}
|
| 1064 |
|
| 1065 |
let svmKernelChart = null;
|
|
@@ -1096,7 +1274,10 @@ function initSVMKernel() {
|
|
| 1096 |
|
| 1097 |
function drawSVMKernel() {
|
| 1098 |
const canvas = document.getElementById('svm-kernel-canvas');
|
| 1099 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1100 |
|
| 1101 |
const ctx = canvas.getContext('2d');
|
| 1102 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1180,6 +1361,8 @@ function drawSVMKernel() {
|
|
| 1180 |
ctx.fillStyle = '#7ef0d4';
|
| 1181 |
ctx.fillText('β Non-linear kernel successfully separates the data', padding + 10, padding + 50);
|
| 1182 |
}
|
|
|
|
|
|
|
| 1183 |
}
|
| 1184 |
|
| 1185 |
// Logistic Regression Visualizations
|
|
@@ -1197,7 +1380,10 @@ function initSigmoid() {
|
|
| 1197 |
|
| 1198 |
function drawSigmoid() {
|
| 1199 |
const canvas = document.getElementById('sigmoid-canvas');
|
| 1200 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1201 |
|
| 1202 |
const ctx = canvas.getContext('2d');
|
| 1203 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1281,6 +1467,8 @@ function drawSigmoid() {
|
|
| 1281 |
ctx.fillText('Ο(z) = 1/(1+eβ»αΆ»)', padding + 10, padding + 25);
|
| 1282 |
ctx.fillStyle = '#ff8c6a';
|
| 1283 |
ctx.fillText('Threshold = 0.5', padding + 10, scaleY(0.5) - 10);
|
|
|
|
|
|
|
| 1284 |
}
|
| 1285 |
|
| 1286 |
function initLogisticClassification() {
|
|
@@ -1292,7 +1480,10 @@ function initLogisticClassification() {
|
|
| 1292 |
|
| 1293 |
function drawLogisticClassification() {
|
| 1294 |
const canvas = document.getElementById('logistic-canvas');
|
| 1295 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1296 |
|
| 1297 |
const ctx = canvas.getContext('2d');
|
| 1298 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1350,6 +1541,8 @@ function drawLogisticClassification() {
|
|
| 1350 |
ctx.fillText(point.height, x, height - padding + 20);
|
| 1351 |
});
|
| 1352 |
|
|
|
|
|
|
|
| 1353 |
// Labels
|
| 1354 |
ctx.fillStyle = '#a9b4c2';
|
| 1355 |
ctx.font = '12px sans-serif';
|
|
@@ -1436,7 +1629,10 @@ function stopDragKNN() {
|
|
| 1436 |
|
| 1437 |
function drawKNN() {
|
| 1438 |
const canvas = document.getElementById('knn-canvas');
|
| 1439 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1440 |
|
| 1441 |
const ctx = canvas.getContext('2d');
|
| 1442 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1524,6 +1720,8 @@ function drawKNN() {
|
|
| 1524 |
ctx.textAlign = 'left';
|
| 1525 |
ctx.fillText(`K=${knnState.k} | Prediction: ${prediction}`, padding + 10, padding + 25);
|
| 1526 |
ctx.fillText(`Votes: Orange=${votes.orange || 0}, Yellow=${votes.yellow || 0}`, padding + 10, padding + 50);
|
|
|
|
|
|
|
| 1527 |
}
|
| 1528 |
|
| 1529 |
// Model Evaluation
|
|
@@ -1542,7 +1740,10 @@ function initConfusionMatrix() {
|
|
| 1542 |
|
| 1543 |
function drawConfusionMatrix() {
|
| 1544 |
const canvas = document.getElementById('confusion-canvas');
|
| 1545 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1546 |
|
| 1547 |
const ctx = canvas.getContext('2d');
|
| 1548 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1598,6 +1799,8 @@ function drawConfusionMatrix() {
|
|
| 1598 |
ctx.rotate(-Math.PI / 2);
|
| 1599 |
ctx.fillText('Actual Negative', 0, 0);
|
| 1600 |
ctx.restore();
|
|
|
|
|
|
|
| 1601 |
}
|
| 1602 |
|
| 1603 |
let rocState = { threshold: 0.5 };
|
|
@@ -1621,7 +1824,10 @@ function initROC() {
|
|
| 1621 |
|
| 1622 |
function drawROC() {
|
| 1623 |
const canvas = document.getElementById('roc-canvas');
|
| 1624 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1625 |
|
| 1626 |
const ctx = canvas.getContext('2d');
|
| 1627 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1718,6 +1924,8 @@ function drawROC() {
|
|
| 1718 |
ctx.textAlign = 'left';
|
| 1719 |
ctx.fillText(`TPR: ${tpr.toFixed(2)} | FPR: ${fpr.toFixed(2)}`, chartX + 10, chartY + 25);
|
| 1720 |
ctx.fillText(`TP=${tp} FP=${fp} TN=${tn} FN=${fn}`, chartX + 10, chartY + 50);
|
|
|
|
|
|
|
| 1721 |
}
|
| 1722 |
|
| 1723 |
function initR2() {
|
|
@@ -1729,7 +1937,10 @@ function initR2() {
|
|
| 1729 |
|
| 1730 |
function drawR2() {
|
| 1731 |
const canvas = document.getElementById('r2-canvas');
|
| 1732 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1733 |
|
| 1734 |
const ctx = canvas.getContext('2d');
|
| 1735 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1808,6 +2019,8 @@ function drawR2() {
|
|
| 1808 |
ctx.textAlign = 'left';
|
| 1809 |
ctx.fillText(`RΒ² = ${r2.toFixed(3)}`, padding + 10, padding + 25);
|
| 1810 |
ctx.fillText(`Model explains ${(r2 * 100).toFixed(1)}% of variance`, padding + 10, padding + 50);
|
|
|
|
|
|
|
| 1811 |
}
|
| 1812 |
|
| 1813 |
// Regularization
|
|
@@ -1832,7 +2045,10 @@ function initRegularization() {
|
|
| 1832 |
|
| 1833 |
function drawRegularization() {
|
| 1834 |
const canvas = document.getElementById('regularization-canvas');
|
| 1835 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1836 |
|
| 1837 |
const ctx = canvas.getContext('2d');
|
| 1838 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1899,6 +2115,8 @@ function drawRegularization() {
|
|
| 1899 |
ctx.fillRect(padding + 210, legendY, 15, 15);
|
| 1900 |
ctx.fillStyle = '#e8eef6';
|
| 1901 |
ctx.fillText('L2 (Ridge)', padding + 230, legendY + 12);
|
|
|
|
|
|
|
| 1902 |
}
|
| 1903 |
|
| 1904 |
// Bias-Variance
|
|
@@ -1917,7 +2135,10 @@ function initBiasVariance() {
|
|
| 1917 |
|
| 1918 |
function drawBiasVariance() {
|
| 1919 |
const canvas = document.getElementById('bias-variance-canvas');
|
| 1920 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 1921 |
|
| 1922 |
const ctx = canvas.getContext('2d');
|
| 1923 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -1993,11 +2214,16 @@ function drawBiasVariance() {
|
|
| 1993 |
ctx.fillText(line, offsetX + sectionWidth / 2, 20 + i * 18);
|
| 1994 |
});
|
| 1995 |
});
|
|
|
|
|
|
|
| 1996 |
}
|
| 1997 |
|
| 1998 |
function drawComplexityCurve() {
|
| 1999 |
const canvas = document.getElementById('complexity-canvas');
|
| 2000 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2001 |
|
| 2002 |
const ctx = canvas.getContext('2d');
|
| 2003 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2050,6 +2276,8 @@ function drawComplexityCurve() {
|
|
| 2050 |
ctx.fillStyle = '#7ef0d4';
|
| 2051 |
ctx.fillText('β Sweet Spot', padding + 10, padding + 60);
|
| 2052 |
|
|
|
|
|
|
|
| 2053 |
// Labels
|
| 2054 |
ctx.fillStyle = '#a9b4c2';
|
| 2055 |
ctx.textAlign = 'center';
|
|
@@ -2071,7 +2299,10 @@ function initCrossValidation() {
|
|
| 2071 |
|
| 2072 |
function drawCrossValidation() {
|
| 2073 |
const canvas = document.getElementById('cv-canvas');
|
| 2074 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2075 |
|
| 2076 |
const ctx = canvas.getContext('2d');
|
| 2077 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2142,6 +2373,8 @@ function drawCrossValidation() {
|
|
| 2142 |
ctx.font = 'bold 16px sans-serif';
|
| 2143 |
ctx.textAlign = 'center';
|
| 2144 |
ctx.fillText(`Final Score: ${mean.toFixed(2)} Β± ${std.toFixed(3)}`, width / 2, height - 20);
|
|
|
|
|
|
|
| 2145 |
}
|
| 2146 |
|
| 2147 |
// Preprocessing
|
|
@@ -2161,7 +2394,10 @@ function initPreprocessing() {
|
|
| 2161 |
|
| 2162 |
function drawScaling() {
|
| 2163 |
const canvas = document.getElementById('scaling-canvas');
|
| 2164 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2165 |
|
| 2166 |
const ctx = canvas.getContext('2d');
|
| 2167 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2213,11 +2449,16 @@ function drawScaling() {
|
|
| 2213 |
centerX += 35;
|
| 2214 |
});
|
| 2215 |
});
|
|
|
|
|
|
|
| 2216 |
}
|
| 2217 |
|
| 2218 |
function drawPipeline() {
|
| 2219 |
const canvas = document.getElementById('pipeline-canvas');
|
| 2220 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2221 |
|
| 2222 |
const ctx = canvas.getContext('2d');
|
| 2223 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2268,6 +2509,8 @@ function drawPipeline() {
|
|
| 2268 |
ctx.fill();
|
| 2269 |
}
|
| 2270 |
});
|
|
|
|
|
|
|
| 2271 |
}
|
| 2272 |
|
| 2273 |
// Loss Functions
|
|
@@ -2287,7 +2530,10 @@ function initLossFunctions() {
|
|
| 2287 |
|
| 2288 |
function drawLossComparison() {
|
| 2289 |
const canvas = document.getElementById('loss-comparison-canvas');
|
| 2290 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2291 |
|
| 2292 |
const ctx = canvas.getContext('2d');
|
| 2293 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2350,11 +2596,16 @@ function drawLossComparison() {
|
|
| 2350 |
ctx.font = 'bold 16px sans-serif';
|
| 2351 |
ctx.textAlign = 'center';
|
| 2352 |
ctx.fillText('Regression Loss Comparison', width / 2, 50);
|
|
|
|
|
|
|
| 2353 |
}
|
| 2354 |
|
| 2355 |
function drawLossCurves() {
|
| 2356 |
const canvas = document.getElementById('loss-curves-canvas');
|
| 2357 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2358 |
|
| 2359 |
const ctx = canvas.getContext('2d');
|
| 2360 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2410,6 +2661,8 @@ function drawLossCurves() {
|
|
| 2410 |
ctx.rotate(-Math.PI / 2);
|
| 2411 |
ctx.fillText('Loss', 0, 0);
|
| 2412 |
ctx.restore();
|
|
|
|
|
|
|
| 2413 |
}
|
| 2414 |
|
| 2415 |
// Topic 13: Finding Optimal K in KNN
|
|
@@ -2469,7 +2722,12 @@ function drawElbowCurve() {
|
|
| 2469 |
}
|
| 2470 |
|
| 2471 |
// Use Chart.js
|
| 2472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2473 |
type: 'line',
|
| 2474 |
data: {
|
| 2475 |
labels: kValues,
|
|
@@ -2528,12 +2786,15 @@ function drawElbowCurve() {
|
|
| 2528 |
}
|
| 2529 |
}
|
| 2530 |
}
|
| 2531 |
-
}, 'Elbow
|
| 2532 |
}
|
| 2533 |
|
| 2534 |
function drawCVKHeatmap() {
|
| 2535 |
const canvas = document.getElementById('cv-k-canvas');
|
| 2536 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2537 |
|
| 2538 |
const ctx = canvas.getContext('2d');
|
| 2539 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2612,6 +2873,8 @@ function drawCVKHeatmap() {
|
|
| 2612 |
const maxMean = Math.max(...meanAccs);
|
| 2613 |
const optIdx = meanAccs.indexOf(maxMean);
|
| 2614 |
ctx.fillText(`Best K = ${kValues[optIdx]} (Mean Acc: ${maxMean.toFixed(3)})`, padding, height - 20);
|
|
|
|
|
|
|
| 2615 |
}
|
| 2616 |
|
| 2617 |
// Topic 14: Hyperparameter Tuning
|
|
@@ -2640,11 +2903,9 @@ function initHyperparameterTuning() {
|
|
| 2640 |
|
| 2641 |
function drawGridSearchHeatmap() {
|
| 2642 |
const canvas = document.getElementById('gridsearch-heatmap');
|
| 2643 |
-
if (!canvas)
|
| 2644 |
-
|
| 2645 |
-
|
| 2646 |
-
if (gridSearchChart) {
|
| 2647 |
-
gridSearchChart.destroy();
|
| 2648 |
}
|
| 2649 |
|
| 2650 |
const ctx = canvas.getContext('2d');
|
|
@@ -2763,11 +3024,16 @@ function drawGridSearchHeatmap() {
|
|
| 2763 |
ctx.font = 'bold 14px sans-serif';
|
| 2764 |
ctx.textAlign = 'left';
|
| 2765 |
ctx.fillText(`Best: C=${cValues[bestJ]}, Ξ³=${gammaValues[bestI]} β Acc=${bestAcc.toFixed(2)}`, padding, height - 30);
|
|
|
|
|
|
|
| 2766 |
}
|
| 2767 |
|
| 2768 |
function drawParamSurface() {
|
| 2769 |
const canvas = document.getElementById('param-surface');
|
| 2770 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2771 |
|
| 2772 |
const ctx = canvas.getContext('2d');
|
| 2773 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2826,6 +3092,8 @@ function drawParamSurface() {
|
|
| 2826 |
ctx.font = 'bold 16px sans-serif';
|
| 2827 |
ctx.textAlign = 'center';
|
| 2828 |
ctx.fillText('Performance Surface (3D Contour View)', width / 2, 30);
|
|
|
|
|
|
|
| 2829 |
}
|
| 2830 |
|
| 2831 |
// Topic 15: Naive Bayes
|
|
@@ -2861,7 +3129,10 @@ function initNaiveBayes() {
|
|
| 2861 |
|
| 2862 |
function drawBayesTheorem() {
|
| 2863 |
const canvas = document.getElementById('bayes-theorem-viz');
|
| 2864 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2865 |
|
| 2866 |
const ctx = canvas.getContext('2d');
|
| 2867 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -2923,7 +3194,11 @@ function drawCategoricalNB() {
|
|
| 2923 |
|
| 2924 |
const ctx = canvas.getContext('2d');
|
| 2925 |
|
| 2926 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2927 |
type: 'bar',
|
| 2928 |
data: {
|
| 2929 |
labels: ['P(Yes|Rainy,Hot)', 'P(No|Rainy,Hot)'],
|
|
@@ -2975,12 +3250,15 @@ function drawCategoricalNB() {
|
|
| 2975 |
}
|
| 2976 |
}
|
| 2977 |
}
|
| 2978 |
-
}, '
|
| 2979 |
}
|
| 2980 |
|
| 2981 |
function drawGaussianNB() {
|
| 2982 |
const canvas = document.getElementById('gaussian-nb-canvas');
|
| 2983 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 2984 |
|
| 2985 |
const ctx = canvas.getContext('2d');
|
| 2986 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -3088,6 +3366,8 @@ function drawGaussianNB() {
|
|
| 3088 |
|
| 3089 |
ctx.fillStyle = '#6aa9ff';
|
| 3090 |
ctx.fillText('| Decision Boundary', padding + 210, 35);
|
|
|
|
|
|
|
| 3091 |
}
|
| 3092 |
|
| 3093 |
function drawSpamClassification() {
|
|
@@ -3157,7 +3437,11 @@ function drawSpamClassification() {
|
|
| 3157 |
compCanvas.style.marginTop = '20px';
|
| 3158 |
canvas.parentElement.appendChild(compCanvas);
|
| 3159 |
|
| 3160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3161 |
type: 'bar',
|
| 3162 |
data: {
|
| 3163 |
labels: ['Spam Probability', 'Not-Spam Probability'],
|
|
@@ -3193,9 +3477,11 @@ function drawSpamClassification() {
|
|
| 3193 |
}
|
| 3194 |
}
|
| 3195 |
}
|
| 3196 |
-
}, 'Bayes
|
| 3197 |
if (bayesComparisonChart) compCanvas.style.height = '150px';
|
| 3198 |
}
|
|
|
|
|
|
|
| 3199 |
}
|
| 3200 |
|
| 3201 |
// Topic 16: Decision Trees
|
|
@@ -3227,7 +3513,10 @@ function initDecisionTrees() {
|
|
| 3227 |
|
| 3228 |
function drawDecisionTree() {
|
| 3229 |
const canvas = document.getElementById('decision-tree-viz');
|
| 3230 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 3231 |
|
| 3232 |
const ctx = canvas.getContext('2d');
|
| 3233 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -3311,6 +3600,8 @@ function drawDecisionTree() {
|
|
| 3311 |
ctx.font = '12px sans-serif';
|
| 3312 |
ctx.textAlign = 'left';
|
| 3313 |
ctx.fillText('Example: Email with "free" + link β SPAM', 40, height - 20);
|
|
|
|
|
|
|
| 3314 |
}
|
| 3315 |
|
| 3316 |
function drawSplitComparison() {
|
|
@@ -3368,6 +3659,8 @@ function drawSplitComparison() {
|
|
| 3368 |
ctx.textAlign = 'center';
|
| 3369 |
ctx.fillText('β Best split: Highest Information Gain!', width / 2, height - 30);
|
| 3370 |
|
|
|
|
|
|
|
| 3371 |
// Title
|
| 3372 |
ctx.fillStyle = '#7ef0d4';
|
| 3373 |
ctx.font = 'bold 16px sans-serif';
|
|
@@ -3376,7 +3669,10 @@ function drawSplitComparison() {
|
|
| 3376 |
|
| 3377 |
function drawEntropyViz() {
|
| 3378 |
const canvas = document.getElementById('entropy-viz');
|
| 3379 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 3380 |
|
| 3381 |
const ctx = canvas.getContext('2d');
|
| 3382 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -3454,6 +3750,8 @@ function drawEntropyViz() {
|
|
| 3454 |
ctx.font = 'bold 16px sans-serif';
|
| 3455 |
ctx.textAlign = 'center';
|
| 3456 |
ctx.fillText('Entropy: Measuring Disorder', width / 2, 30);
|
|
|
|
|
|
|
| 3457 |
}
|
| 3458 |
|
| 3459 |
function drawSplitComparison() {
|
|
@@ -3601,7 +3899,10 @@ function drawEntropyViz() {
|
|
| 3601 |
|
| 3602 |
function drawTreeBoundary() {
|
| 3603 |
const canvas = document.getElementById('tree-boundary');
|
| 3604 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 3605 |
|
| 3606 |
const ctx = canvas.getContext('2d');
|
| 3607 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -3686,80 +3987,1255 @@ function drawTreeBoundary() {
|
|
| 3686 |
ctx.font = 'bold 16px sans-serif';
|
| 3687 |
ctx.textAlign = 'center';
|
| 3688 |
ctx.fillText('Decision Tree Creates Rectangular Regions', width / 2, 30);
|
|
|
|
|
|
|
| 3689 |
}
|
| 3690 |
|
| 3691 |
-
// Topic
|
| 3692 |
-
function
|
| 3693 |
-
const canvas1 = document.getElementById('
|
| 3694 |
if (canvas1 && !canvas1.dataset.initialized) {
|
| 3695 |
canvas1.dataset.initialized = 'true';
|
| 3696 |
-
|
| 3697 |
}
|
| 3698 |
|
| 3699 |
-
const canvas2 = document.getElementById('
|
| 3700 |
if (canvas2 && !canvas2.dataset.initialized) {
|
| 3701 |
canvas2.dataset.initialized = 'true';
|
| 3702 |
-
|
| 3703 |
-
}
|
| 3704 |
-
|
| 3705 |
-
const canvas3 = document.getElementById('random-forest-viz');
|
| 3706 |
-
if (canvas3 && !canvas3.dataset.initialized) {
|
| 3707 |
-
canvas3.dataset.initialized = 'true';
|
| 3708 |
-
drawRandomForestViz();
|
| 3709 |
}
|
| 3710 |
}
|
| 3711 |
|
| 3712 |
-
function
|
| 3713 |
-
const canvas = document.getElementById('
|
| 3714 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 3715 |
|
| 3716 |
const ctx = canvas.getContext('2d');
|
| 3717 |
const width = canvas.width = canvas.offsetWidth;
|
| 3718 |
-
const height = canvas.height =
|
| 3719 |
|
| 3720 |
ctx.clearRect(0, 0, width, height);
|
| 3721 |
ctx.fillStyle = '#1a2332';
|
| 3722 |
ctx.fillRect(0, 0, width, height);
|
| 3723 |
|
| 3724 |
-
const
|
| 3725 |
-
const
|
| 3726 |
-
const
|
| 3727 |
-
const spacing = (width - 3 * boxWidth) / 4;
|
| 3728 |
|
| 3729 |
-
|
| 3730 |
-
|
| 3731 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3732 |
ctx.strokeStyle = '#6aa9ff';
|
| 3733 |
-
ctx.lineWidth =
|
| 3734 |
-
ctx.
|
| 3735 |
-
ctx.
|
| 3736 |
-
ctx.
|
| 3737 |
-
ctx.
|
| 3738 |
-
ctx.
|
| 3739 |
|
| 3740 |
-
|
| 3741 |
-
|
| 3742 |
-
|
| 3743 |
-
|
| 3744 |
-
|
| 3745 |
-
|
| 3746 |
-
|
| 3747 |
-
|
| 3748 |
-
|
| 3749 |
-
|
| 3750 |
-
|
| 3751 |
-
|
| 3752 |
-
|
| 3753 |
-
|
| 3754 |
-
|
| 3755 |
-
|
| 3756 |
-
|
| 3757 |
-
|
| 3758 |
-
|
| 3759 |
-
|
| 3760 |
-
|
| 3761 |
-
|
| 3762 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3763 |
ctx.fillStyle = '#a9b4c2';
|
| 3764 |
ctx.fillText('(random sample)', x + boxWidth / 2, sampleY + boxHeight / 2 + 10);
|
| 3765 |
|
|
@@ -3910,6 +5386,40 @@ function drawBoostingViz() {
|
|
| 3910 |
ctx.fillStyle = '#ff8c6a';
|
| 3911 |
ctx.font = 'bold 14px sans-serif';
|
| 3912 |
ctx.fillText('Final Prediction = Weighted Combination of All Models', width / 2, height - 20);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3913 |
}
|
| 3914 |
|
| 3915 |
function drawRandomForestViz() {
|
|
@@ -4018,6 +5528,8 @@ function drawRandomForestViz() {
|
|
| 4018 |
ctx.fillStyle = '#7ef0d4';
|
| 4019 |
ctx.font = 'bold 16px sans-serif';
|
| 4020 |
ctx.fillText('Random Forest: Ensemble of Decision Trees', width / 2, 25);
|
|
|
|
|
|
|
| 4021 |
}
|
| 4022 |
|
| 4023 |
// Topic 16: K-means Clustering
|
|
@@ -4040,7 +5552,10 @@ function initKMeans() {
|
|
| 4040 |
|
| 4041 |
function drawKMeansVisualization() {
|
| 4042 |
const canvas = document.getElementById('kmeans-viz-canvas');
|
| 4043 |
-
if (!canvas)
|
|
|
|
|
|
|
|
|
|
| 4044 |
|
| 4045 |
const ctx = canvas.getContext('2d');
|
| 4046 |
const width = canvas.width = canvas.offsetWidth;
|
|
@@ -4160,6 +5675,8 @@ function drawKMeansVisualization() {
|
|
| 4160 |
ctx.font = '14px sans-serif';
|
| 4161 |
ctx.textAlign = 'left';
|
| 4162 |
ctx.fillText('WCSS = 15.984', padding, height - padding + 30);
|
|
|
|
|
|
|
| 4163 |
}
|
| 4164 |
|
| 4165 |
function drawKMeansElbow() {
|
|
@@ -4175,7 +5692,7 @@ function drawKMeansElbow() {
|
|
| 4175 |
const kValues = [1, 2, 3, 4, 5];
|
| 4176 |
const wcssValues = [50, 18, 10, 8, 7];
|
| 4177 |
|
| 4178 |
-
kmeansElbowChart =
|
| 4179 |
type: 'line',
|
| 4180 |
data: {
|
| 4181 |
labels: kValues,
|
|
@@ -4238,7 +5755,7 @@ function drawKMeansElbow() {
|
|
| 4238 |
}
|
| 4239 |
}
|
| 4240 |
}
|
| 4241 |
-
}, 'K-means Elbow
|
| 4242 |
}
|
| 4243 |
|
| 4244 |
// Topic 18: Algorithm Comparison
|
|
@@ -4474,6 +5991,8 @@ function renderComparisonTable() {
|
|
| 4474 |
|
| 4475 |
html += '</tbody>';
|
| 4476 |
table.innerHTML = html;
|
|
|
|
|
|
|
| 4477 |
}
|
| 4478 |
|
| 4479 |
let radarComparisonChart = null;
|
|
@@ -4505,7 +6024,12 @@ function renderRadarChart() {
|
|
| 4505 |
};
|
| 4506 |
});
|
| 4507 |
|
| 4508 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4509 |
type: 'radar',
|
| 4510 |
data: {
|
| 4511 |
labels: ['Speed', 'Accuracy', 'Data Efficiency', 'Interpretability', 'Scalability'],
|
|
@@ -4530,7 +6054,7 @@ function renderRadarChart() {
|
|
| 4530 |
}
|
| 4531 |
}
|
| 4532 |
}
|
| 4533 |
-
}, '
|
| 4534 |
}
|
| 4535 |
|
| 4536 |
function renderHeatmap() {
|
|
@@ -4586,6 +6110,8 @@ function renderHeatmap() {
|
|
| 4586 |
html += '</table>';
|
| 4587 |
html += '</div>';
|
| 4588 |
|
|
|
|
|
|
|
| 4589 |
// Legend
|
| 4590 |
html += '<div style="text-align: center; margin-top: 24px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">';
|
| 4591 |
html += '<strong style="color: #e8eef6;">Legend:</strong> ';
|
|
@@ -4634,6 +6160,8 @@ function renderUseCaseMatrix() {
|
|
| 4634 |
|
| 4635 |
html += '</tbody>';
|
| 4636 |
table.innerHTML = html;
|
|
|
|
|
|
|
| 4637 |
}
|
| 4638 |
|
| 4639 |
function renderDetailedCards() {
|
|
@@ -4673,6 +6201,8 @@ function renderDetailedCards() {
|
|
| 4673 |
|
| 4674 |
html += '</div>';
|
| 4675 |
container.innerHTML = html;
|
|
|
|
|
|
|
| 4676 |
}
|
| 4677 |
|
| 4678 |
function initQuiz() {
|
|
@@ -4836,6 +6366,75 @@ function drawDecisionFlowchart() {
|
|
| 4836 |
ctx.fillText('Algorithm Selection Flowchart', width/2, 25);
|
| 4837 |
}
|
| 4838 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4839 |
// Handle window resize
|
| 4840 |
let resizeTimer;
|
| 4841 |
window.addEventListener('resize', () => {
|
|
@@ -4883,3 +6482,6 @@ window.addEventListener('resize', () => {
|
|
| 4883 |
if (document.getElementById('decision-flowchart')) drawDecisionFlowchart();
|
| 4884 |
}, 250);
|
| 4885 |
});
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// ========== VISUALIZATION VERIFICATION SYSTEM ==========
|
| 2 |
+
const vizLog = {
|
| 3 |
+
success: [],
|
| 4 |
+
failed: [],
|
| 5 |
+
warnings: []
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
function logViz(module, name, status, error = null) {
|
| 9 |
+
const log = {
|
| 10 |
+
module: module,
|
| 11 |
+
name: name,
|
| 12 |
+
status: status,
|
| 13 |
+
timestamp: new Date().toLocaleTimeString(),
|
| 14 |
+
error: error
|
| 15 |
+
};
|
| 16 |
+
|
| 17 |
+
if (status === 'success') {
|
| 18 |
+
vizLog.success.push(log);
|
| 19 |
+
console.log(`β ${module} - ${name}`);
|
| 20 |
+
} else if (status === 'failed') {
|
| 21 |
+
vizLog.failed.push(log);
|
| 22 |
+
console.error(`β ${module} - ${name}: ${error}`);
|
| 23 |
+
} else {
|
| 24 |
+
vizLog.warnings.push(log);
|
| 25 |
+
console.warn(`β ${module} - ${name}: ${error}`);
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
function createVerifiedVisualization(canvasId, chartConfig, moduleName, vizName) {
|
| 30 |
+
try {
|
| 31 |
+
const canvas = document.getElementById(canvasId);
|
| 32 |
+
if (!canvas) {
|
| 33 |
+
logViz(moduleName, vizName, 'failed', 'Canvas not found');
|
| 34 |
+
showFallback(canvasId, 'error');
|
| 35 |
+
return null;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
const ctx = canvas.getContext('2d');
|
| 39 |
+
if (!ctx) {
|
| 40 |
+
logViz(moduleName, vizName, 'failed', 'Cannot get context');
|
| 41 |
+
showFallback(canvasId, 'error');
|
| 42 |
+
return null;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
if (typeof Chart === 'undefined') {
|
| 46 |
+
logViz(moduleName, vizName, 'failed', 'Chart.js not loaded');
|
| 47 |
+
showFallback(canvasId, 'error');
|
| 48 |
+
return null;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
const chart = new Chart(ctx, chartConfig);
|
| 52 |
+
logViz(moduleName, vizName, 'success');
|
| 53 |
+
return chart;
|
| 54 |
+
|
| 55 |
+
} catch (error) {
|
| 56 |
+
logViz(moduleName, vizName, 'failed', error.message);
|
| 57 |
+
showFallback(canvasId, 'error');
|
| 58 |
+
return null;
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
function showFallback(elementId, type) {
|
| 63 |
+
const element = document.getElementById(elementId);
|
| 64 |
+
if (!element) return;
|
| 65 |
+
|
| 66 |
+
const container = element.parentElement;
|
| 67 |
+
if (!container) return;
|
| 68 |
+
|
| 69 |
+
if (type === 'error') {
|
| 70 |
+
container.innerHTML = '<div style="padding: 40px; text-align: center; color: #ff8c6a; background: rgba(255, 140, 106, 0.1); border-radius: 8px; border: 2px solid #ff8c6a;">β οΈ Visualization temporarily unavailable<br><small style="color: #a9b4c2; margin-top: 8px; display: block;">Data is still accessible via diagnostic tools</small></div>';
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
// Show report on load
|
| 75 |
+
window.addEventListener('load', () => {
|
| 76 |
+
setTimeout(() => {
|
| 77 |
+
console.log('\n=== VISUALIZATION VERIFICATION REPORT ===');
|
| 78 |
+
console.log(`β Success: ${vizLog.success.length}`);
|
| 79 |
+
console.log(`β Failed: ${vizLog.failed.length}`);
|
| 80 |
+
console.log(`β Warnings: ${vizLog.warnings.length}`);
|
| 81 |
+
|
| 82 |
+
if (vizLog.failed.length > 0) {
|
| 83 |
+
console.error('Failed visualizations:', vizLog.failed);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
if (vizLog.success.length > 0) {
|
| 87 |
+
console.log('\nSuccessful visualizations:');
|
| 88 |
+
vizLog.success.forEach(v => console.log(` β ${v.module} - ${v.name}`));
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
console.log('\n=========================================');
|
| 92 |
+
}, 2000);
|
| 93 |
+
});
|
| 94 |
+
|
| 95 |
// Data
|
| 96 |
const data = {
|
| 97 |
linearRegression: [
|
|
|
|
| 228 |
if (section.id === 'hyperparameter-tuning') initHyperparameterTuning();
|
| 229 |
if (section.id === 'naive-bayes') initNaiveBayes();
|
| 230 |
if (section.id === 'kmeans') initKMeans();
|
| 231 |
+
if (section.id === 'decision-tree-regression') initDecisionTreeRegression();
|
| 232 |
if (section.id === 'decision-trees') initDecisionTrees();
|
| 233 |
+
if (section.id === 'gradient-boosting') initGradientBoosting();
|
| 234 |
+
if (section.id === 'xgboost') initXGBoost();
|
| 235 |
+
if (section.id === 'bagging') initBagging();
|
| 236 |
+
if (section.id === 'boosting-adaboost') initBoostingAdaBoost();
|
| 237 |
+
if (section.id === 'random-forest') initRandomForest();
|
| 238 |
if (section.id === 'ensemble-methods') initEnsembleMethods();
|
| 239 |
+
if (section.id === 'diagnostics') {
|
| 240 |
+
// Wait for all visualizations to initialize
|
| 241 |
+
setTimeout(showDiagnostics, 500);
|
| 242 |
+
}
|
| 243 |
if (section.id === 'rl-intro') { /* No viz for intro */ }
|
| 244 |
if (section.id === 'q-learning') { /* Add Q-learning viz if needed */ }
|
| 245 |
if (section.id === 'policy-gradient') { /* Add policy gradient viz if needed */ }
|
|
|
|
| 286 |
});
|
| 287 |
ticking = true;
|
| 288 |
}
|
| 289 |
+
}, 'Gradient Descent', 'Loss Curve');
|
| 290 |
}
|
| 291 |
|
| 292 |
function updateActiveLink() {
|
|
|
|
| 367 |
});
|
| 368 |
mse /= data.linearRegression.length;
|
| 369 |
|
| 370 |
+
// Destroy existing chart
|
| 371 |
+
if (lrChart) {
|
| 372 |
+
lrChart.destroy();
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
lrChart = createVerifiedVisualization('lr-canvas', {
|
| 376 |
type: 'scatter',
|
| 377 |
data: {
|
| 378 |
datasets: [
|
|
|
|
| 422 |
}
|
| 423 |
}
|
| 424 |
}
|
| 425 |
+
}, 'Linear Regression', 'Scatter + Line');
|
| 426 |
}
|
| 427 |
|
| 428 |
// Gradient Descent Visualization
|
|
|
|
| 538 |
const ctx = canvas.getContext('2d');
|
| 539 |
const lossData = state.gdIterations.map((iter, i) => ({ x: i + 1, y: iter.loss }));
|
| 540 |
|
| 541 |
+
// Destroy existing chart
|
| 542 |
+
if (gdChart) {
|
| 543 |
+
gdChart.destroy();
|
| 544 |
+
}
|
| 545 |
+
|
| 546 |
+
gdChart = createVerifiedVisualization('gd-canvas', {
|
| 547 |
type: 'line',
|
| 548 |
data: {
|
| 549 |
datasets: [{
|
|
|
|
| 595 |
console.warn(`Canvas context not found for ${chartName}`);
|
| 596 |
return null;
|
| 597 |
}
|
| 598 |
+
const chart = new Chart(ctx, config);
|
| 599 |
+
console.log(`β Chart created: ${chartName}`);
|
| 600 |
+
return chart;
|
| 601 |
} catch (error) {
|
| 602 |
console.error(`Chart creation failed for ${chartName}:`, error);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 603 |
return null;
|
| 604 |
}
|
| 605 |
}
|
| 606 |
|
| 607 |
+
// Link Verification System
|
| 608 |
+
function verifyAllLinks() {
|
| 609 |
+
const links = document.querySelectorAll('a[href^="#"]');
|
| 610 |
+
const broken = [];
|
| 611 |
+
let working = 0;
|
| 612 |
+
|
| 613 |
+
links.forEach(link => {
|
| 614 |
+
const targetId = link.getAttribute('href').substring(1);
|
| 615 |
+
const target = document.getElementById(targetId);
|
| 616 |
+
|
| 617 |
+
if (!target) {
|
| 618 |
+
broken.push({
|
| 619 |
+
text: link.textContent,
|
| 620 |
+
href: link.getAttribute('href')
|
| 621 |
+
});
|
| 622 |
+
link.style.color = 'red';
|
| 623 |
+
link.title = 'Broken link';
|
| 624 |
+
} else {
|
| 625 |
+
working++;
|
| 626 |
+
link.addEventListener('click', (e) => {
|
| 627 |
+
e.preventDefault();
|
| 628 |
+
target.scrollIntoView({ behavior: 'smooth' });
|
| 629 |
+
|
| 630 |
+
// Highlight section
|
| 631 |
+
const originalBg = target.style.backgroundColor;
|
| 632 |
+
target.style.backgroundColor = 'rgba(106, 169, 255, 0.2)';
|
| 633 |
+
setTimeout(() => {
|
| 634 |
+
target.style.backgroundColor = originalBg;
|
| 635 |
+
}, 1000);
|
| 636 |
+
});
|
| 637 |
+
}
|
| 638 |
+
});
|
| 639 |
+
|
| 640 |
+
console.log(`\n=== LINK VERIFICATION ===`);
|
| 641 |
+
console.log(`β Working: ${working}/${links.length}`);
|
| 642 |
+
console.log(`β Broken: ${broken.length}`);
|
| 643 |
+
if (broken.length > 0) {
|
| 644 |
+
console.error('Broken links:', broken);
|
| 645 |
+
}
|
| 646 |
+
console.log('==========================\n');
|
| 647 |
+
}
|
| 648 |
+
|
| 649 |
// Initialize everything when DOM is ready
|
| 650 |
function init() {
|
| 651 |
initCategories();
|
|
|
|
| 656 |
setTimeout(() => {
|
| 657 |
initLinearRegression();
|
| 658 |
}, 100);
|
| 659 |
+
|
| 660 |
+
// Verify all links on load
|
| 661 |
+
setTimeout(verifyAllLinks, 1000);
|
| 662 |
+
|
| 663 |
+
// Initialize diagnostics refresh
|
| 664 |
+
setInterval(() => {
|
| 665 |
+
const diagSection = document.getElementById('diagnostics');
|
| 666 |
+
if (diagSection && diagSection.querySelector('.section-body').classList.contains('expanded')) {
|
| 667 |
+
showDiagnostics();
|
| 668 |
+
}
|
| 669 |
+
}, 3000);
|
| 670 |
}
|
| 671 |
|
| 672 |
if (document.readyState === 'loading') {
|
|
|
|
| 722 |
|
| 723 |
function drawSVMBasic() {
|
| 724 |
const canvas = document.getElementById('svm-basic-canvas');
|
| 725 |
+
if (!canvas) {
|
| 726 |
+
logViz('SVM', 'Basic Decision Boundary', 'failed', 'Canvas not found');
|
| 727 |
+
return;
|
| 728 |
+
}
|
| 729 |
|
| 730 |
const ctx = canvas.getContext('2d');
|
| 731 |
if (!ctx) {
|
|
|
|
| 829 |
ctx.font = '13px sans-serif';
|
| 830 |
ctx.textAlign = 'center';
|
| 831 |
ctx.fillText('Xβ', width / 2, height - 20);
|
| 832 |
+
|
| 833 |
+
logViz('SVM', 'Basic Decision Boundary', 'success');
|
| 834 |
ctx.save();
|
| 835 |
ctx.translate(20, height / 2);
|
| 836 |
ctx.rotate(-Math.PI / 2);
|
|
|
|
| 853 |
|
| 854 |
function drawSVMMargin() {
|
| 855 |
const canvas = document.getElementById('svm-margin-canvas');
|
| 856 |
+
if (!canvas) {
|
| 857 |
+
logViz('SVM', 'Margin Visualization', 'failed', 'Canvas not found');
|
| 858 |
+
return;
|
| 859 |
+
}
|
| 860 |
|
| 861 |
const ctx = canvas.getContext('2d');
|
| 862 |
if (!ctx) {
|
|
|
|
| 977 |
|
| 978 |
function drawSVMCParameter() {
|
| 979 |
const canvas = document.getElementById('svm-c-canvas');
|
| 980 |
+
if (!canvas) {
|
| 981 |
+
logViz('SVM', 'C Parameter Effect', 'failed', 'Canvas not found');
|
| 982 |
+
return;
|
|
|
|
|
|
|
| 983 |
}
|
| 984 |
|
| 985 |
const ctx = canvas.getContext('2d');
|
|
|
|
| 1073 |
const violEl = document.getElementById('violations-count');
|
| 1074 |
if (marginEl) marginEl.textContent = marginWidth.toFixed(2);
|
| 1075 |
if (violEl) violEl.textContent = violations;
|
| 1076 |
+
|
| 1077 |
+
logViz('SVM', 'Margin Visualization', 'success');
|
| 1078 |
}
|
| 1079 |
|
| 1080 |
function initSVMTraining() {
|
|
|
|
| 1165 |
|
| 1166 |
function drawSVMTraining() {
|
| 1167 |
const canvas = document.getElementById('svm-train-canvas');
|
| 1168 |
+
if (!canvas) {
|
| 1169 |
+
logViz('SVM', 'Training Animation', 'failed', 'Canvas not found');
|
| 1170 |
+
return;
|
| 1171 |
+
}
|
| 1172 |
|
| 1173 |
const ctx = canvas.getContext('2d');
|
| 1174 |
if (!ctx) {
|
|
|
|
| 1236 |
ctx.textAlign = 'center';
|
| 1237 |
ctx.fillText(point.label, x, y - 15);
|
| 1238 |
});
|
| 1239 |
+
|
| 1240 |
+
logViz('SVM', 'Training Animation', 'success');
|
| 1241 |
}
|
| 1242 |
|
| 1243 |
let svmKernelChart = null;
|
|
|
|
| 1274 |
|
| 1275 |
function drawSVMKernel() {
|
| 1276 |
const canvas = document.getElementById('svm-kernel-canvas');
|
| 1277 |
+
if (!canvas) {
|
| 1278 |
+
logViz('SVM', 'Kernel Comparison', 'failed', 'Canvas not found');
|
| 1279 |
+
return;
|
| 1280 |
+
}
|
| 1281 |
|
| 1282 |
const ctx = canvas.getContext('2d');
|
| 1283 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 1361 |
ctx.fillStyle = '#7ef0d4';
|
| 1362 |
ctx.fillText('β Non-linear kernel successfully separates the data', padding + 10, padding + 50);
|
| 1363 |
}
|
| 1364 |
+
|
| 1365 |
+
logViz('SVM', 'Kernel Comparison', 'success');
|
| 1366 |
}
|
| 1367 |
|
| 1368 |
// Logistic Regression Visualizations
|
|
|
|
| 1380 |
|
| 1381 |
function drawSigmoid() {
|
| 1382 |
const canvas = document.getElementById('sigmoid-canvas');
|
| 1383 |
+
if (!canvas) {
|
| 1384 |
+
logViz('Logistic Regression', 'Sigmoid Curve', 'failed', 'Canvas not found');
|
| 1385 |
+
return;
|
| 1386 |
+
}
|
| 1387 |
|
| 1388 |
const ctx = canvas.getContext('2d');
|
| 1389 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 1467 |
ctx.fillText('Ο(z) = 1/(1+eβ»αΆ»)', padding + 10, padding + 25);
|
| 1468 |
ctx.fillStyle = '#ff8c6a';
|
| 1469 |
ctx.fillText('Threshold = 0.5', padding + 10, scaleY(0.5) - 10);
|
| 1470 |
+
|
| 1471 |
+
logViz('Logistic Regression', 'Sigmoid Curve', 'success');
|
| 1472 |
}
|
| 1473 |
|
| 1474 |
function initLogisticClassification() {
|
|
|
|
| 1480 |
|
| 1481 |
function drawLogisticClassification() {
|
| 1482 |
const canvas = document.getElementById('logistic-canvas');
|
| 1483 |
+
if (!canvas) {
|
| 1484 |
+
logViz('Logistic Regression', 'Classification Boundary', 'failed', 'Canvas not found');
|
| 1485 |
+
return;
|
| 1486 |
+
}
|
| 1487 |
|
| 1488 |
const ctx = canvas.getContext('2d');
|
| 1489 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 1541 |
ctx.fillText(point.height, x, height - padding + 20);
|
| 1542 |
});
|
| 1543 |
|
| 1544 |
+
logViz('Logistic Regression', 'Classification Boundary', 'success');
|
| 1545 |
+
|
| 1546 |
// Labels
|
| 1547 |
ctx.fillStyle = '#a9b4c2';
|
| 1548 |
ctx.font = '12px sans-serif';
|
|
|
|
| 1629 |
|
| 1630 |
function drawKNN() {
|
| 1631 |
const canvas = document.getElementById('knn-canvas');
|
| 1632 |
+
if (!canvas) {
|
| 1633 |
+
logViz('KNN', 'Draggable Point', 'failed', 'Canvas not found');
|
| 1634 |
+
return;
|
| 1635 |
+
}
|
| 1636 |
|
| 1637 |
const ctx = canvas.getContext('2d');
|
| 1638 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 1720 |
ctx.textAlign = 'left';
|
| 1721 |
ctx.fillText(`K=${knnState.k} | Prediction: ${prediction}`, padding + 10, padding + 25);
|
| 1722 |
ctx.fillText(`Votes: Orange=${votes.orange || 0}, Yellow=${votes.yellow || 0}`, padding + 10, padding + 50);
|
| 1723 |
+
|
| 1724 |
+
logViz('KNN', 'Draggable Point', 'success');
|
| 1725 |
}
|
| 1726 |
|
| 1727 |
// Model Evaluation
|
|
|
|
| 1740 |
|
| 1741 |
function drawConfusionMatrix() {
|
| 1742 |
const canvas = document.getElementById('confusion-canvas');
|
| 1743 |
+
if (!canvas) {
|
| 1744 |
+
logViz('Model Evaluation', 'Confusion Matrix', 'failed', 'Canvas not found');
|
| 1745 |
+
return;
|
| 1746 |
+
}
|
| 1747 |
|
| 1748 |
const ctx = canvas.getContext('2d');
|
| 1749 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 1799 |
ctx.rotate(-Math.PI / 2);
|
| 1800 |
ctx.fillText('Actual Negative', 0, 0);
|
| 1801 |
ctx.restore();
|
| 1802 |
+
|
| 1803 |
+
logViz('Model Evaluation', 'Confusion Matrix', 'success');
|
| 1804 |
}
|
| 1805 |
|
| 1806 |
let rocState = { threshold: 0.5 };
|
|
|
|
| 1824 |
|
| 1825 |
function drawROC() {
|
| 1826 |
const canvas = document.getElementById('roc-canvas');
|
| 1827 |
+
if (!canvas) {
|
| 1828 |
+
logViz('Model Evaluation', 'ROC Curve', 'failed', 'Canvas not found');
|
| 1829 |
+
return;
|
| 1830 |
+
}
|
| 1831 |
|
| 1832 |
const ctx = canvas.getContext('2d');
|
| 1833 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 1924 |
ctx.textAlign = 'left';
|
| 1925 |
ctx.fillText(`TPR: ${tpr.toFixed(2)} | FPR: ${fpr.toFixed(2)}`, chartX + 10, chartY + 25);
|
| 1926 |
ctx.fillText(`TP=${tp} FP=${fp} TN=${tn} FN=${fn}`, chartX + 10, chartY + 50);
|
| 1927 |
+
|
| 1928 |
+
logViz('Model Evaluation', 'ROC Curve', 'success');
|
| 1929 |
}
|
| 1930 |
|
| 1931 |
function initR2() {
|
|
|
|
| 1937 |
|
| 1938 |
function drawR2() {
|
| 1939 |
const canvas = document.getElementById('r2-canvas');
|
| 1940 |
+
if (!canvas) {
|
| 1941 |
+
logViz('Model Evaluation', 'RΒ² Score', 'failed', 'Canvas not found');
|
| 1942 |
+
return;
|
| 1943 |
+
}
|
| 1944 |
|
| 1945 |
const ctx = canvas.getContext('2d');
|
| 1946 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2019 |
ctx.textAlign = 'left';
|
| 2020 |
ctx.fillText(`RΒ² = ${r2.toFixed(3)}`, padding + 10, padding + 25);
|
| 2021 |
ctx.fillText(`Model explains ${(r2 * 100).toFixed(1)}% of variance`, padding + 10, padding + 50);
|
| 2022 |
+
|
| 2023 |
+
logViz('Model Evaluation', 'RΒ² Score', 'success');
|
| 2024 |
}
|
| 2025 |
|
| 2026 |
// Regularization
|
|
|
|
| 2045 |
|
| 2046 |
function drawRegularization() {
|
| 2047 |
const canvas = document.getElementById('regularization-canvas');
|
| 2048 |
+
if (!canvas) {
|
| 2049 |
+
logViz('Regularization', 'L1 vs L2 Comparison', 'failed', 'Canvas not found');
|
| 2050 |
+
return;
|
| 2051 |
+
}
|
| 2052 |
|
| 2053 |
const ctx = canvas.getContext('2d');
|
| 2054 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2115 |
ctx.fillRect(padding + 210, legendY, 15, 15);
|
| 2116 |
ctx.fillStyle = '#e8eef6';
|
| 2117 |
ctx.fillText('L2 (Ridge)', padding + 230, legendY + 12);
|
| 2118 |
+
|
| 2119 |
+
logViz('Regularization', 'L1 vs L2 Comparison', 'success');
|
| 2120 |
}
|
| 2121 |
|
| 2122 |
// Bias-Variance
|
|
|
|
| 2135 |
|
| 2136 |
function drawBiasVariance() {
|
| 2137 |
const canvas = document.getElementById('bias-variance-canvas');
|
| 2138 |
+
if (!canvas) {
|
| 2139 |
+
logViz('Bias-Variance', 'Three Models', 'failed', 'Canvas not found');
|
| 2140 |
+
return;
|
| 2141 |
+
}
|
| 2142 |
|
| 2143 |
const ctx = canvas.getContext('2d');
|
| 2144 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2214 |
ctx.fillText(line, offsetX + sectionWidth / 2, 20 + i * 18);
|
| 2215 |
});
|
| 2216 |
});
|
| 2217 |
+
|
| 2218 |
+
logViz('Bias-Variance', 'Three Models', 'success');
|
| 2219 |
}
|
| 2220 |
|
| 2221 |
function drawComplexityCurve() {
|
| 2222 |
const canvas = document.getElementById('complexity-canvas');
|
| 2223 |
+
if (!canvas) {
|
| 2224 |
+
logViz('Bias-Variance', 'Complexity Curve', 'failed', 'Canvas not found');
|
| 2225 |
+
return;
|
| 2226 |
+
}
|
| 2227 |
|
| 2228 |
const ctx = canvas.getContext('2d');
|
| 2229 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2276 |
ctx.fillStyle = '#7ef0d4';
|
| 2277 |
ctx.fillText('β Sweet Spot', padding + 10, padding + 60);
|
| 2278 |
|
| 2279 |
+
logViz('Bias-Variance', 'Complexity Curve', 'success');
|
| 2280 |
+
|
| 2281 |
// Labels
|
| 2282 |
ctx.fillStyle = '#a9b4c2';
|
| 2283 |
ctx.textAlign = 'center';
|
|
|
|
| 2299 |
|
| 2300 |
function drawCrossValidation() {
|
| 2301 |
const canvas = document.getElementById('cv-canvas');
|
| 2302 |
+
if (!canvas) {
|
| 2303 |
+
logViz('Cross-Validation', 'K-Fold Visualization', 'failed', 'Canvas not found');
|
| 2304 |
+
return;
|
| 2305 |
+
}
|
| 2306 |
|
| 2307 |
const ctx = canvas.getContext('2d');
|
| 2308 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2373 |
ctx.font = 'bold 16px sans-serif';
|
| 2374 |
ctx.textAlign = 'center';
|
| 2375 |
ctx.fillText(`Final Score: ${mean.toFixed(2)} Β± ${std.toFixed(3)}`, width / 2, height - 20);
|
| 2376 |
+
|
| 2377 |
+
logViz('Cross-Validation', 'K-Fold Visualization', 'success');
|
| 2378 |
}
|
| 2379 |
|
| 2380 |
// Preprocessing
|
|
|
|
| 2394 |
|
| 2395 |
function drawScaling() {
|
| 2396 |
const canvas = document.getElementById('scaling-canvas');
|
| 2397 |
+
if (!canvas) {
|
| 2398 |
+
logViz('Preprocessing', 'Feature Scaling', 'failed', 'Canvas not found');
|
| 2399 |
+
return;
|
| 2400 |
+
}
|
| 2401 |
|
| 2402 |
const ctx = canvas.getContext('2d');
|
| 2403 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2449 |
centerX += 35;
|
| 2450 |
});
|
| 2451 |
});
|
| 2452 |
+
|
| 2453 |
+
logViz('Preprocessing', 'Feature Scaling', 'success');
|
| 2454 |
}
|
| 2455 |
|
| 2456 |
function drawPipeline() {
|
| 2457 |
const canvas = document.getElementById('pipeline-canvas');
|
| 2458 |
+
if (!canvas) {
|
| 2459 |
+
logViz('Preprocessing', 'Pipeline Flow', 'failed', 'Canvas not found');
|
| 2460 |
+
return;
|
| 2461 |
+
}
|
| 2462 |
|
| 2463 |
const ctx = canvas.getContext('2d');
|
| 2464 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2509 |
ctx.fill();
|
| 2510 |
}
|
| 2511 |
});
|
| 2512 |
+
|
| 2513 |
+
logViz('Preprocessing', 'Pipeline Flow', 'success');
|
| 2514 |
}
|
| 2515 |
|
| 2516 |
// Loss Functions
|
|
|
|
| 2530 |
|
| 2531 |
function drawLossComparison() {
|
| 2532 |
const canvas = document.getElementById('loss-comparison-canvas');
|
| 2533 |
+
if (!canvas) {
|
| 2534 |
+
logViz('Loss Functions', 'Loss Comparison', 'failed', 'Canvas not found');
|
| 2535 |
+
return;
|
| 2536 |
+
}
|
| 2537 |
|
| 2538 |
const ctx = canvas.getContext('2d');
|
| 2539 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2596 |
ctx.font = 'bold 16px sans-serif';
|
| 2597 |
ctx.textAlign = 'center';
|
| 2598 |
ctx.fillText('Regression Loss Comparison', width / 2, 50);
|
| 2599 |
+
|
| 2600 |
+
logViz('Loss Functions', 'Loss Comparison', 'success');
|
| 2601 |
}
|
| 2602 |
|
| 2603 |
function drawLossCurves() {
|
| 2604 |
const canvas = document.getElementById('loss-curves-canvas');
|
| 2605 |
+
if (!canvas) {
|
| 2606 |
+
logViz('Loss Functions', 'Loss Curves', 'failed', 'Canvas not found');
|
| 2607 |
+
return;
|
| 2608 |
+
}
|
| 2609 |
|
| 2610 |
const ctx = canvas.getContext('2d');
|
| 2611 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2661 |
ctx.rotate(-Math.PI / 2);
|
| 2662 |
ctx.fillText('Loss', 0, 0);
|
| 2663 |
ctx.restore();
|
| 2664 |
+
|
| 2665 |
+
logViz('Loss Functions', 'Loss Curves', 'success');
|
| 2666 |
}
|
| 2667 |
|
| 2668 |
// Topic 13: Finding Optimal K in KNN
|
|
|
|
| 2722 |
}
|
| 2723 |
|
| 2724 |
// Use Chart.js
|
| 2725 |
+
// Destroy existing chart
|
| 2726 |
+
if (elbowChart) {
|
| 2727 |
+
elbowChart.destroy();
|
| 2728 |
+
}
|
| 2729 |
+
|
| 2730 |
+
elbowChart = createVerifiedVisualization('elbow-canvas', {
|
| 2731 |
type: 'line',
|
| 2732 |
data: {
|
| 2733 |
labels: kValues,
|
|
|
|
| 2786 |
}
|
| 2787 |
}
|
| 2788 |
}
|
| 2789 |
+
}, 'KNN', 'Elbow Method');
|
| 2790 |
}
|
| 2791 |
|
| 2792 |
function drawCVKHeatmap() {
|
| 2793 |
const canvas = document.getElementById('cv-k-canvas');
|
| 2794 |
+
if (!canvas) {
|
| 2795 |
+
logViz('Optimal K', 'CV Heatmap', 'failed', 'Canvas not found');
|
| 2796 |
+
return;
|
| 2797 |
+
}
|
| 2798 |
|
| 2799 |
const ctx = canvas.getContext('2d');
|
| 2800 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 2873 |
const maxMean = Math.max(...meanAccs);
|
| 2874 |
const optIdx = meanAccs.indexOf(maxMean);
|
| 2875 |
ctx.fillText(`Best K = ${kValues[optIdx]} (Mean Acc: ${maxMean.toFixed(3)})`, padding, height - 20);
|
| 2876 |
+
|
| 2877 |
+
logViz('Optimal K', 'CV Heatmap', 'success');
|
| 2878 |
}
|
| 2879 |
|
| 2880 |
// Topic 14: Hyperparameter Tuning
|
|
|
|
| 2903 |
|
| 2904 |
function drawGridSearchHeatmap() {
|
| 2905 |
const canvas = document.getElementById('gridsearch-heatmap');
|
| 2906 |
+
if (!canvas) {
|
| 2907 |
+
logViz('Hyperparameter Tuning', 'GridSearch Heatmap', 'failed', 'Canvas not found');
|
| 2908 |
+
return;
|
|
|
|
|
|
|
| 2909 |
}
|
| 2910 |
|
| 2911 |
const ctx = canvas.getContext('2d');
|
|
|
|
| 3024 |
ctx.font = 'bold 14px sans-serif';
|
| 3025 |
ctx.textAlign = 'left';
|
| 3026 |
ctx.fillText(`Best: C=${cValues[bestJ]}, Ξ³=${gammaValues[bestI]} β Acc=${bestAcc.toFixed(2)}`, padding, height - 30);
|
| 3027 |
+
|
| 3028 |
+
logViz('Hyperparameter Tuning', 'GridSearch Heatmap', 'success');
|
| 3029 |
}
|
| 3030 |
|
| 3031 |
function drawParamSurface() {
|
| 3032 |
const canvas = document.getElementById('param-surface');
|
| 3033 |
+
if (!canvas) {
|
| 3034 |
+
logViz('Hyperparameter Tuning', 'Parameter Surface', 'failed', 'Canvas not found');
|
| 3035 |
+
return;
|
| 3036 |
+
}
|
| 3037 |
|
| 3038 |
const ctx = canvas.getContext('2d');
|
| 3039 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 3092 |
ctx.font = 'bold 16px sans-serif';
|
| 3093 |
ctx.textAlign = 'center';
|
| 3094 |
ctx.fillText('Performance Surface (3D Contour View)', width / 2, 30);
|
| 3095 |
+
|
| 3096 |
+
logViz('Hyperparameter Tuning', 'Parameter Surface', 'success');
|
| 3097 |
}
|
| 3098 |
|
| 3099 |
// Topic 15: Naive Bayes
|
|
|
|
| 3129 |
|
| 3130 |
function drawBayesTheorem() {
|
| 3131 |
const canvas = document.getElementById('bayes-theorem-viz');
|
| 3132 |
+
if (!canvas) {
|
| 3133 |
+
logViz('Naive Bayes', 'Bayes Theorem Flow', 'failed', 'Canvas not found');
|
| 3134 |
+
return;
|
| 3135 |
+
}
|
| 3136 |
|
| 3137 |
const ctx = canvas.getContext('2d');
|
| 3138 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 3194 |
|
| 3195 |
const ctx = canvas.getContext('2d');
|
| 3196 |
|
| 3197 |
+
if (categoricalNBChart) {
|
| 3198 |
+
categoricalNBChart.destroy();
|
| 3199 |
+
}
|
| 3200 |
+
|
| 3201 |
+
categoricalNBChart = createVerifiedVisualization('categorical-nb-canvas', {
|
| 3202 |
type: 'bar',
|
| 3203 |
data: {
|
| 3204 |
labels: ['P(Yes|Rainy,Hot)', 'P(No|Rainy,Hot)'],
|
|
|
|
| 3250 |
}
|
| 3251 |
}
|
| 3252 |
}
|
| 3253 |
+
}, 'Naive Bayes', 'Categorical Calculation');
|
| 3254 |
}
|
| 3255 |
|
| 3256 |
function drawGaussianNB() {
|
| 3257 |
const canvas = document.getElementById('gaussian-nb-canvas');
|
| 3258 |
+
if (!canvas) {
|
| 3259 |
+
logViz('Naive Bayes', 'Gaussian NB Boundary', 'failed', 'Canvas not found');
|
| 3260 |
+
return;
|
| 3261 |
+
}
|
| 3262 |
|
| 3263 |
const ctx = canvas.getContext('2d');
|
| 3264 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 3366 |
|
| 3367 |
ctx.fillStyle = '#6aa9ff';
|
| 3368 |
ctx.fillText('| Decision Boundary', padding + 210, 35);
|
| 3369 |
+
|
| 3370 |
+
logViz('Naive Bayes', 'Gaussian NB Boundary', 'success');
|
| 3371 |
}
|
| 3372 |
|
| 3373 |
function drawSpamClassification() {
|
|
|
|
| 3437 |
compCanvas.style.marginTop = '20px';
|
| 3438 |
canvas.parentElement.appendChild(compCanvas);
|
| 3439 |
|
| 3440 |
+
if (bayesComparisonChart) {
|
| 3441 |
+
bayesComparisonChart.destroy();
|
| 3442 |
+
}
|
| 3443 |
+
|
| 3444 |
+
bayesComparisonChart = createVerifiedVisualization('bayes-comparison-chart', {
|
| 3445 |
type: 'bar',
|
| 3446 |
data: {
|
| 3447 |
labels: ['Spam Probability', 'Not-Spam Probability'],
|
|
|
|
| 3477 |
}
|
| 3478 |
}
|
| 3479 |
}
|
| 3480 |
+
}, 'Naive Bayes', 'Spam Classification');
|
| 3481 |
if (bayesComparisonChart) compCanvas.style.height = '150px';
|
| 3482 |
}
|
| 3483 |
+
|
| 3484 |
+
logViz('Naive Bayes', 'Bayes Theorem Flow', 'success');
|
| 3485 |
}
|
| 3486 |
|
| 3487 |
// Topic 16: Decision Trees
|
|
|
|
| 3513 |
|
| 3514 |
function drawDecisionTree() {
|
| 3515 |
const canvas = document.getElementById('decision-tree-viz');
|
| 3516 |
+
if (!canvas) {
|
| 3517 |
+
logViz('Decision Trees', 'Tree Structure', 'failed', 'Canvas not found');
|
| 3518 |
+
return;
|
| 3519 |
+
}
|
| 3520 |
|
| 3521 |
const ctx = canvas.getContext('2d');
|
| 3522 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 3600 |
ctx.font = '12px sans-serif';
|
| 3601 |
ctx.textAlign = 'left';
|
| 3602 |
ctx.fillText('Example: Email with "free" + link β SPAM', 40, height - 20);
|
| 3603 |
+
|
| 3604 |
+
logViz('Decision Trees', 'Tree Structure', 'success');
|
| 3605 |
}
|
| 3606 |
|
| 3607 |
function drawSplitComparison() {
|
|
|
|
| 3659 |
ctx.textAlign = 'center';
|
| 3660 |
ctx.fillText('β Best split: Highest Information Gain!', width / 2, height - 30);
|
| 3661 |
|
| 3662 |
+
logViz('Decision Trees', 'Information Gain', 'success');
|
| 3663 |
+
|
| 3664 |
// Title
|
| 3665 |
ctx.fillStyle = '#7ef0d4';
|
| 3666 |
ctx.font = 'bold 16px sans-serif';
|
|
|
|
| 3669 |
|
| 3670 |
function drawEntropyViz() {
|
| 3671 |
const canvas = document.getElementById('entropy-viz');
|
| 3672 |
+
if (!canvas) {
|
| 3673 |
+
logViz('Decision Trees', 'Entropy Visualization', 'failed', 'Canvas not found');
|
| 3674 |
+
return;
|
| 3675 |
+
}
|
| 3676 |
|
| 3677 |
const ctx = canvas.getContext('2d');
|
| 3678 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 3750 |
ctx.font = 'bold 16px sans-serif';
|
| 3751 |
ctx.textAlign = 'center';
|
| 3752 |
ctx.fillText('Entropy: Measuring Disorder', width / 2, 30);
|
| 3753 |
+
|
| 3754 |
+
logViz('Decision Trees', 'Entropy Visualization', 'success');
|
| 3755 |
}
|
| 3756 |
|
| 3757 |
function drawSplitComparison() {
|
|
|
|
| 3899 |
|
| 3900 |
function drawTreeBoundary() {
|
| 3901 |
const canvas = document.getElementById('tree-boundary');
|
| 3902 |
+
if (!canvas) {
|
| 3903 |
+
logViz('Decision Trees', 'Decision Regions', 'failed', 'Canvas not found');
|
| 3904 |
+
return;
|
| 3905 |
+
}
|
| 3906 |
|
| 3907 |
const ctx = canvas.getContext('2d');
|
| 3908 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 3987 |
ctx.font = 'bold 16px sans-serif';
|
| 3988 |
ctx.textAlign = 'center';
|
| 3989 |
ctx.fillText('Decision Tree Creates Rectangular Regions', width / 2, 30);
|
| 3990 |
+
|
| 3991 |
+
logViz('Decision Trees', 'Decision Regions', 'success');
|
| 3992 |
}
|
| 3993 |
|
| 3994 |
+
// Topic 16b: Decision Tree Regression Visualization
|
| 3995 |
+
function initDecisionTreeRegression() {
|
| 3996 |
+
const canvas1 = document.getElementById('dt-regression-canvas');
|
| 3997 |
if (canvas1 && !canvas1.dataset.initialized) {
|
| 3998 |
canvas1.dataset.initialized = 'true';
|
| 3999 |
+
drawDTRegression();
|
| 4000 |
}
|
| 4001 |
|
| 4002 |
+
const canvas2 = document.getElementById('dt-splits-canvas');
|
| 4003 |
if (canvas2 && !canvas2.dataset.initialized) {
|
| 4004 |
canvas2.dataset.initialized = 'true';
|
| 4005 |
+
drawDTSplits();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4006 |
}
|
| 4007 |
}
|
| 4008 |
|
| 4009 |
+
function drawDTRegression() {
|
| 4010 |
+
const canvas = document.getElementById('dt-regression-canvas');
|
| 4011 |
+
if (!canvas) {
|
| 4012 |
+
logViz('Decision Tree Regression', 'Splits & Predictions', 'failed', 'Canvas not found');
|
| 4013 |
+
return;
|
| 4014 |
+
}
|
| 4015 |
|
| 4016 |
const ctx = canvas.getContext('2d');
|
| 4017 |
const width = canvas.width = canvas.offsetWidth;
|
| 4018 |
+
const height = canvas.height = 450;
|
| 4019 |
|
| 4020 |
ctx.clearRect(0, 0, width, height);
|
| 4021 |
ctx.fillStyle = '#1a2332';
|
| 4022 |
ctx.fillRect(0, 0, width, height);
|
| 4023 |
|
| 4024 |
+
const padding = 60;
|
| 4025 |
+
const chartWidth = width - 2 * padding;
|
| 4026 |
+
const chartHeight = height - 2 * padding;
|
|
|
|
| 4027 |
|
| 4028 |
+
const xMin = 700, xMax = 1800;
|
| 4029 |
+
const yMin = 40, yMax = 110;
|
| 4030 |
+
const scaleX = (x) => padding + ((x - xMin) / (xMax - xMin)) * chartWidth;
|
| 4031 |
+
const scaleY = (y) => height - padding - ((y - yMin) / (yMax - yMin)) * chartHeight;
|
| 4032 |
+
|
| 4033 |
+
// Data points
|
| 4034 |
+
const data = [
|
| 4035 |
+
{x: 800, y: 50}, {x: 850, y: 52}, {x: 900, y: 54},
|
| 4036 |
+
{x: 1500, y: 90}, {x: 1600, y: 95}, {x: 1700, y: 100}
|
| 4037 |
+
];
|
| 4038 |
+
|
| 4039 |
+
// Draw decision boundaries
|
| 4040 |
ctx.strokeStyle = '#6aa9ff';
|
| 4041 |
+
ctx.lineWidth = 3;
|
| 4042 |
+
ctx.setLineDash([5, 5]);
|
| 4043 |
+
ctx.beginPath();
|
| 4044 |
+
ctx.moveTo(scaleX(1200), padding);
|
| 4045 |
+
ctx.lineTo(scaleX(1200), height - padding);
|
| 4046 |
+
ctx.stroke();
|
| 4047 |
|
| 4048 |
+
ctx.beginPath();
|
| 4049 |
+
ctx.moveTo(scaleX(1550), padding);
|
| 4050 |
+
ctx.lineTo(scaleX(1550), height - padding);
|
| 4051 |
+
ctx.stroke();
|
| 4052 |
+
ctx.setLineDash([]);
|
| 4053 |
+
|
| 4054 |
+
// Draw regions with predictions
|
| 4055 |
+
ctx.fillStyle = 'rgba(126, 240, 212, 0.1)';
|
| 4056 |
+
ctx.fillRect(scaleX(700), scaleY(52), scaleX(1200) - scaleX(700), height - padding - scaleY(52));
|
| 4057 |
+
ctx.fillStyle = 'rgba(255, 140, 106, 0.1)';
|
| 4058 |
+
ctx.fillRect(scaleX(1200), scaleY(90), scaleX(1550) - scaleX(1200), height - padding - scaleY(90));
|
| 4059 |
+
ctx.fillStyle = 'rgba(106, 169, 255, 0.1)';
|
| 4060 |
+
ctx.fillRect(scaleX(1550), scaleY(97.5), scaleX(1800) - scaleX(1550), height - padding - scaleY(97.5));
|
| 4061 |
+
|
| 4062 |
+
// Draw prediction lines
|
| 4063 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 4064 |
+
ctx.lineWidth = 4;
|
| 4065 |
+
ctx.beginPath();
|
| 4066 |
+
ctx.moveTo(scaleX(700), scaleY(52));
|
| 4067 |
+
ctx.lineTo(scaleX(1200), scaleY(52));
|
| 4068 |
+
ctx.stroke();
|
| 4069 |
+
|
| 4070 |
+
ctx.strokeStyle = '#ff8c6a';
|
| 4071 |
+
ctx.beginPath();
|
| 4072 |
+
ctx.moveTo(scaleX(1200), scaleY(90));
|
| 4073 |
+
ctx.lineTo(scaleX(1550), scaleY(90));
|
| 4074 |
+
ctx.stroke();
|
| 4075 |
+
|
| 4076 |
+
ctx.strokeStyle = '#6aa9ff';
|
| 4077 |
+
ctx.beginPath();
|
| 4078 |
+
ctx.moveTo(scaleX(1550), scaleY(97.5));
|
| 4079 |
+
ctx.lineTo(scaleX(1800), scaleY(97.5));
|
| 4080 |
+
ctx.stroke();
|
| 4081 |
+
|
| 4082 |
+
// Draw data points
|
| 4083 |
+
data.forEach(point => {
|
| 4084 |
+
ctx.fillStyle = '#e8eef6';
|
| 4085 |
+
ctx.beginPath();
|
| 4086 |
+
ctx.arc(scaleX(point.x), scaleY(point.y), 6, 0, 2 * Math.PI);
|
| 4087 |
+
ctx.fill();
|
| 4088 |
+
ctx.strokeStyle = '#1a2332';
|
| 4089 |
+
ctx.lineWidth = 2;
|
| 4090 |
+
ctx.stroke();
|
| 4091 |
+
});
|
| 4092 |
+
|
| 4093 |
+
// Labels
|
| 4094 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4095 |
+
ctx.font = 'bold 13px sans-serif';
|
| 4096 |
+
ctx.textAlign = 'center';
|
| 4097 |
+
ctx.fillText('Predict: βΉ52L', scaleX(950), scaleY(52) - 10);
|
| 4098 |
+
ctx.fillStyle = '#ff8c6a';
|
| 4099 |
+
ctx.fillText('Predict: βΉ90L', scaleX(1375), scaleY(90) - 10);
|
| 4100 |
+
ctx.fillStyle = '#6aa9ff';
|
| 4101 |
+
ctx.fillText('Predict: βΉ97.5L', scaleX(1650), scaleY(97.5) - 10);
|
| 4102 |
+
|
| 4103 |
+
// Axes
|
| 4104 |
+
ctx.fillStyle = '#a9b4c2';
|
| 4105 |
+
ctx.font = '12px sans-serif';
|
| 4106 |
+
ctx.textAlign = 'center';
|
| 4107 |
+
ctx.fillText('Square Feet', width / 2, height - 20);
|
| 4108 |
+
ctx.save();
|
| 4109 |
+
ctx.translate(20, height / 2);
|
| 4110 |
+
ctx.rotate(-Math.PI / 2);
|
| 4111 |
+
ctx.fillText('Price (Lakhs)', 0, 0);
|
| 4112 |
+
ctx.restore();
|
| 4113 |
+
|
| 4114 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4115 |
+
ctx.font = 'bold 14px sans-serif';
|
| 4116 |
+
ctx.fillText('Split at 1200', scaleX(1200), 30);
|
| 4117 |
+
ctx.fillText('Split at 1550', scaleX(1550), 30);
|
| 4118 |
+
|
| 4119 |
+
logViz('Decision Tree Regression', 'Splits & Predictions', 'success');
|
| 4120 |
+
}
|
| 4121 |
+
|
| 4122 |
+
function drawDTSplits() {
|
| 4123 |
+
const canvas = document.getElementById('dt-splits-canvas');
|
| 4124 |
+
if (!canvas) {
|
| 4125 |
+
logViz('Decision Tree Regression', 'Split Comparison', 'failed', 'Canvas not found');
|
| 4126 |
+
return;
|
| 4127 |
+
}
|
| 4128 |
+
|
| 4129 |
+
const ctx = canvas.getContext('2d');
|
| 4130 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 4131 |
+
const height = canvas.height = 400;
|
| 4132 |
+
|
| 4133 |
+
ctx.clearRect(0, 0, width, height);
|
| 4134 |
+
ctx.fillStyle = '#1a2332';
|
| 4135 |
+
ctx.fillRect(0, 0, width, height);
|
| 4136 |
+
|
| 4137 |
+
const splits = [
|
| 4138 |
+
{value: 825, varReduction: 120, color: '#ff8c6a'},
|
| 4139 |
+
{value: 875, varReduction: 180, color: '#ffb490'},
|
| 4140 |
+
{value: 1200, varReduction: 462.25, color: '#7ef0d4'},
|
| 4141 |
+
{value: 1550, varReduction: 95, color: '#ffb490'},
|
| 4142 |
+
{value: 1650, varReduction: 65, color: '#ff8c6a'}
|
| 4143 |
+
];
|
| 4144 |
+
|
| 4145 |
+
const padding = 60;
|
| 4146 |
+
const barHeight = 50;
|
| 4147 |
+
const maxWidth = width - 2 * padding - 200;
|
| 4148 |
+
const maxVR = Math.max(...splits.map(s => s.varReduction));
|
| 4149 |
+
|
| 4150 |
+
splits.forEach((split, i) => {
|
| 4151 |
+
const y = 60 + i * (barHeight + 25);
|
| 4152 |
+
const barWidth = (split.varReduction / maxVR) * maxWidth;
|
| 4153 |
+
|
| 4154 |
+
ctx.fillStyle = split.color;
|
| 4155 |
+
ctx.fillRect(padding, y, barWidth, barHeight);
|
| 4156 |
+
ctx.strokeStyle = split.color;
|
| 4157 |
+
ctx.lineWidth = 2;
|
| 4158 |
+
ctx.strokeRect(padding, y, barWidth, barHeight);
|
| 4159 |
+
|
| 4160 |
+
ctx.fillStyle = '#e8eef6';
|
| 4161 |
+
ctx.font = 'bold 12px sans-serif';
|
| 4162 |
+
ctx.textAlign = 'left';
|
| 4163 |
+
ctx.fillText(`Split at ${split.value}`, padding, y - 8);
|
| 4164 |
+
|
| 4165 |
+
ctx.fillStyle = '#1a2332';
|
| 4166 |
+
ctx.font = 'bold 14px sans-serif';
|
| 4167 |
+
ctx.textAlign = 'center';
|
| 4168 |
+
ctx.fillText(`VR = ${split.varReduction.toFixed(1)}`, padding + barWidth / 2, y + barHeight / 2 + 5);
|
| 4169 |
+
});
|
| 4170 |
+
|
| 4171 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4172 |
+
ctx.font = 'bold 16px sans-serif';
|
| 4173 |
+
ctx.textAlign = 'center';
|
| 4174 |
+
ctx.fillText('β Split at 1200: Maximum Variance Reduction!', width / 2, height - 20);
|
| 4175 |
+
|
| 4176 |
+
logViz('Decision Tree Regression', 'Split Comparison', 'success');
|
| 4177 |
+
}
|
| 4178 |
+
|
| 4179 |
+
// Topic 17a: Gradient Boosting (NEW)
|
| 4180 |
+
function initGradientBoosting() {
|
| 4181 |
+
const canvases = [
|
| 4182 |
+
{ id: 'gb-sequential-canvas', fn: drawGBSequential },
|
| 4183 |
+
{ id: 'gb-residuals-canvas', fn: drawGBResiduals },
|
| 4184 |
+
{ id: 'gb-learning-rate-canvas', fn: drawGBLearningRate },
|
| 4185 |
+
{ id: 'gb-stumps-canvas', fn: drawGBStumps },
|
| 4186 |
+
{ id: 'gb-predictions-canvas', fn: drawGBPredictions }
|
| 4187 |
+
];
|
| 4188 |
+
|
| 4189 |
+
canvases.forEach(c => {
|
| 4190 |
+
const canvas = document.getElementById(c.id);
|
| 4191 |
+
if (canvas && !canvas.dataset.initialized) {
|
| 4192 |
+
canvas.dataset.initialized = 'true';
|
| 4193 |
+
c.fn();
|
| 4194 |
+
}
|
| 4195 |
+
});
|
| 4196 |
+
}
|
| 4197 |
+
|
| 4198 |
+
function drawGBSequential() {
|
| 4199 |
+
const canvas = document.getElementById('gb-sequential-canvas');
|
| 4200 |
+
if (!canvas) return;
|
| 4201 |
+
|
| 4202 |
+
const gbData = [
|
| 4203 |
+
{ iteration: 0, f: 154, residual: 29.6 },
|
| 4204 |
+
{ iteration: 1, f: 151.93, residual: 26.8 },
|
| 4205 |
+
{ iteration: 2, f: 149.5, residual: 24.1 },
|
| 4206 |
+
{ iteration: 3, f: 147.2, residual: 21.5 },
|
| 4207 |
+
{ iteration: 4, f: 145.1, residual: 19.2 },
|
| 4208 |
+
{ iteration: 5, f: 143.2, residual: 17.1 },
|
| 4209 |
+
{ iteration: 6, f: 141.5, residual: 15.3 },
|
| 4210 |
+
{ iteration: 7, f: 140.0, residual: 13.7 },
|
| 4211 |
+
{ iteration: 8, f: 138.6, residual: 12.2 },
|
| 4212 |
+
{ iteration: 9, f: 137.4, residual: 10.9 },
|
| 4213 |
+
{ iteration: 10, f: 136.3, residual: 9.8 }
|
| 4214 |
+
];
|
| 4215 |
+
|
| 4216 |
+
createVerifiedVisualization('gb-sequential-canvas', {
|
| 4217 |
+
type: 'line',
|
| 4218 |
+
data: {
|
| 4219 |
+
datasets: [
|
| 4220 |
+
{
|
| 4221 |
+
label: 'Mean Prediction F(t)',
|
| 4222 |
+
data: gbData.map(d => ({ x: d.iteration, y: d.f })),
|
| 4223 |
+
borderColor: '#6aa9ff',
|
| 4224 |
+
backgroundColor: 'rgba(106, 169, 255, 0.1)',
|
| 4225 |
+
borderWidth: 3,
|
| 4226 |
+
fill: true,
|
| 4227 |
+
yAxisID: 'y'
|
| 4228 |
+
},
|
| 4229 |
+
{
|
| 4230 |
+
label: 'Mean Absolute Residual',
|
| 4231 |
+
data: gbData.map(d => ({ x: d.iteration, y: d.residual })),
|
| 4232 |
+
borderColor: '#ff8c6a',
|
| 4233 |
+
backgroundColor: 'rgba(255, 140, 106, 0.1)',
|
| 4234 |
+
borderWidth: 3,
|
| 4235 |
+
fill: true,
|
| 4236 |
+
yAxisID: 'y1'
|
| 4237 |
+
}
|
| 4238 |
+
]
|
| 4239 |
+
},
|
| 4240 |
+
options: {
|
| 4241 |
+
responsive: true,
|
| 4242 |
+
maintainAspectRatio: false,
|
| 4243 |
+
plugins: {
|
| 4244 |
+
title: {
|
| 4245 |
+
display: true,
|
| 4246 |
+
text: 'Gradient Boosting: Sequential Learning',
|
| 4247 |
+
color: '#e8eef6',
|
| 4248 |
+
font: { size: 16 }
|
| 4249 |
+
},
|
| 4250 |
+
legend: { labels: { color: '#a9b4c2' } }
|
| 4251 |
+
},
|
| 4252 |
+
scales: {
|
| 4253 |
+
x: {
|
| 4254 |
+
title: { display: true, text: 'Iteration', color: '#a9b4c2' },
|
| 4255 |
+
grid: { color: '#2a3544' },
|
| 4256 |
+
ticks: { color: '#a9b4c2' }
|
| 4257 |
+
},
|
| 4258 |
+
y: {
|
| 4259 |
+
type: 'linear',
|
| 4260 |
+
position: 'left',
|
| 4261 |
+
title: { display: true, text: 'Prediction F(t)', color: '#6aa9ff' },
|
| 4262 |
+
grid: { color: '#2a3544' },
|
| 4263 |
+
ticks: { color: '#a9b4c2' }
|
| 4264 |
+
},
|
| 4265 |
+
y1: {
|
| 4266 |
+
type: 'linear',
|
| 4267 |
+
position: 'right',
|
| 4268 |
+
title: { display: true, text: 'Residual', color: '#ff8c6a' },
|
| 4269 |
+
grid: { display: false },
|
| 4270 |
+
ticks: { color: '#a9b4c2' }
|
| 4271 |
+
}
|
| 4272 |
+
}
|
| 4273 |
+
}
|
| 4274 |
+
}, 'Gradient Boosting', 'Sequential Trees');
|
| 4275 |
+
}
|
| 4276 |
+
|
| 4277 |
+
function drawGBResiduals() {
|
| 4278 |
+
const canvas = document.getElementById('gb-residuals-canvas');
|
| 4279 |
+
if (!canvas) return;
|
| 4280 |
+
|
| 4281 |
+
const residuals = [
|
| 4282 |
+
{ id: 1, iter0: -34, iter1: -31.93, iter5: -12, iter10: -3 },
|
| 4283 |
+
{ id: 2, iter0: -24, iter1: -21.93, iter5: -8, iter10: -2 },
|
| 4284 |
+
{ id: 3, iter0: -4, iter1: -1.93, iter5: -1, iter10: 0 },
|
| 4285 |
+
{ id: 4, iter0: 16, iter1: 12.90, iter5: 5, iter10: 1 },
|
| 4286 |
+
{ id: 5, iter0: 46, iter1: 42.90, iter5: 18, iter10: 4 }
|
| 4287 |
+
];
|
| 4288 |
+
|
| 4289 |
+
createVerifiedVisualization('gb-residuals-canvas', {
|
| 4290 |
+
type: 'bar',
|
| 4291 |
+
data: {
|
| 4292 |
+
labels: ['ID 1', 'ID 2', 'ID 3', 'ID 4', 'ID 5'],
|
| 4293 |
+
datasets: [
|
| 4294 |
+
{
|
| 4295 |
+
label: 'Iteration 0',
|
| 4296 |
+
data: residuals.map(r => r.iter0),
|
| 4297 |
+
backgroundColor: '#ff8c6a'
|
| 4298 |
+
},
|
| 4299 |
+
{
|
| 4300 |
+
label: 'Iteration 1',
|
| 4301 |
+
data: residuals.map(r => r.iter1),
|
| 4302 |
+
backgroundColor: '#ffb490'
|
| 4303 |
+
},
|
| 4304 |
+
{
|
| 4305 |
+
label: 'Iteration 5',
|
| 4306 |
+
data: residuals.map(r => r.iter5),
|
| 4307 |
+
backgroundColor: '#6aa9ff'
|
| 4308 |
+
},
|
| 4309 |
+
{
|
| 4310 |
+
label: 'Iteration 10',
|
| 4311 |
+
data: residuals.map(r => r.iter10),
|
| 4312 |
+
backgroundColor: '#7ef0d4'
|
| 4313 |
+
}
|
| 4314 |
+
]
|
| 4315 |
+
},
|
| 4316 |
+
options: {
|
| 4317 |
+
responsive: true,
|
| 4318 |
+
maintainAspectRatio: false,
|
| 4319 |
+
plugins: {
|
| 4320 |
+
title: {
|
| 4321 |
+
display: true,
|
| 4322 |
+
text: 'Residual Reduction Over Iterations',
|
| 4323 |
+
color: '#e8eef6',
|
| 4324 |
+
font: { size: 16 }
|
| 4325 |
+
},
|
| 4326 |
+
legend: { labels: { color: '#a9b4c2' } }
|
| 4327 |
+
},
|
| 4328 |
+
scales: {
|
| 4329 |
+
x: {
|
| 4330 |
+
grid: { color: '#2a3544' },
|
| 4331 |
+
ticks: { color: '#a9b4c2' }
|
| 4332 |
+
},
|
| 4333 |
+
y: {
|
| 4334 |
+
title: { display: true, text: 'Residual Value', color: '#a9b4c2' },
|
| 4335 |
+
grid: { color: '#2a3544' },
|
| 4336 |
+
ticks: { color: '#a9b4c2' }
|
| 4337 |
+
}
|
| 4338 |
+
}
|
| 4339 |
+
}
|
| 4340 |
+
}, 'Gradient Boosting', 'Residual Reduction');
|
| 4341 |
+
}
|
| 4342 |
+
|
| 4343 |
+
function drawGBLearningRate() {
|
| 4344 |
+
const canvas = document.getElementById('gb-learning-rate-canvas');
|
| 4345 |
+
if (!canvas) return;
|
| 4346 |
+
|
| 4347 |
+
const iterations = Array.from({length: 21}, (_, i) => i);
|
| 4348 |
+
|
| 4349 |
+
const lr01 = iterations.map(i => 154 - 18 * (1 - Math.exp(-i * 0.01)));
|
| 4350 |
+
const lr10 = iterations.map(i => 154 - 18 * (1 - Math.exp(-i * 0.1)));
|
| 4351 |
+
const lr100 = iterations.map(i => {
|
| 4352 |
+
if (i === 0) return 154;
|
| 4353 |
+
if (i < 5) return 154 - 18 * (1 - Math.exp(-i * 1.0));
|
| 4354 |
+
return 136 + Math.sin(i) * 2;
|
| 4355 |
+
});
|
| 4356 |
+
|
| 4357 |
+
createVerifiedVisualization('gb-learning-rate-canvas', {
|
| 4358 |
+
type: 'line',
|
| 4359 |
+
data: {
|
| 4360 |
+
labels: iterations,
|
| 4361 |
+
datasets: [
|
| 4362 |
+
{
|
| 4363 |
+
label: 'lr = 0.01 (slow)',
|
| 4364 |
+
data: lr01,
|
| 4365 |
+
borderColor: '#ff8c6a',
|
| 4366 |
+
borderWidth: 3,
|
| 4367 |
+
pointRadius: 2
|
| 4368 |
+
},
|
| 4369 |
+
{
|
| 4370 |
+
label: 'lr = 0.1 (good)',
|
| 4371 |
+
data: lr10,
|
| 4372 |
+
borderColor: '#7ef0d4',
|
| 4373 |
+
borderWidth: 3,
|
| 4374 |
+
pointRadius: 2
|
| 4375 |
+
},
|
| 4376 |
+
{
|
| 4377 |
+
label: 'lr = 1.0 (too fast)',
|
| 4378 |
+
data: lr100,
|
| 4379 |
+
borderColor: '#6aa9ff',
|
| 4380 |
+
borderWidth: 3,
|
| 4381 |
+
pointRadius: 2
|
| 4382 |
+
}
|
| 4383 |
+
]
|
| 4384 |
+
},
|
| 4385 |
+
options: {
|
| 4386 |
+
responsive: true,
|
| 4387 |
+
maintainAspectRatio: false,
|
| 4388 |
+
plugins: {
|
| 4389 |
+
title: {
|
| 4390 |
+
display: true,
|
| 4391 |
+
text: 'Learning Rate Effect on Convergence',
|
| 4392 |
+
color: '#e8eef6',
|
| 4393 |
+
font: { size: 16 }
|
| 4394 |
+
},
|
| 4395 |
+
legend: { labels: { color: '#a9b4c2' } }
|
| 4396 |
+
},
|
| 4397 |
+
scales: {
|
| 4398 |
+
x: {
|
| 4399 |
+
title: { display: true, text: 'Iteration', color: '#a9b4c2' },
|
| 4400 |
+
grid: { color: '#2a3544' },
|
| 4401 |
+
ticks: { color: '#a9b4c2' }
|
| 4402 |
+
},
|
| 4403 |
+
y: {
|
| 4404 |
+
title: { display: true, text: 'Mean Prediction', color: '#a9b4c2' },
|
| 4405 |
+
grid: { color: '#2a3544' },
|
| 4406 |
+
ticks: { color: '#a9b4c2' }
|
| 4407 |
+
}
|
| 4408 |
+
}
|
| 4409 |
+
}
|
| 4410 |
+
}, 'Gradient Boosting', 'Learning Rate Effect');
|
| 4411 |
+
}
|
| 4412 |
+
|
| 4413 |
+
function drawGBStumps() {
|
| 4414 |
+
const canvas = document.getElementById('gb-stumps-canvas');
|
| 4415 |
+
if (!canvas) return;
|
| 4416 |
+
|
| 4417 |
+
const ctx = canvas.getContext('2d');
|
| 4418 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 4419 |
+
const height = canvas.height = 400;
|
| 4420 |
+
|
| 4421 |
+
ctx.clearRect(0, 0, width, height);
|
| 4422 |
+
ctx.fillStyle = '#1a2332';
|
| 4423 |
+
ctx.fillRect(0, 0, width, height);
|
| 4424 |
+
|
| 4425 |
+
const stumps = [
|
| 4426 |
+
{ name: 'h1', split: 1050, left: -20.66, right: 31.0, color: '#6aa9ff' },
|
| 4427 |
+
{ name: 'h2', split: 950, left: -15.2, right: 22.5, color: '#7ef0d4' },
|
| 4428 |
+
{ name: 'h3', split: 1150, left: -8.5, right: 14.8, color: '#ffb490' }
|
| 4429 |
+
];
|
| 4430 |
+
|
| 4431 |
+
const stumpWidth = width / 3;
|
| 4432 |
+
|
| 4433 |
+
stumps.forEach((stump, idx) => {
|
| 4434 |
+
const offsetX = idx * stumpWidth;
|
| 4435 |
+
const centerX = offsetX + stumpWidth / 2;
|
| 4436 |
+
|
| 4437 |
+
// Title
|
| 4438 |
+
ctx.fillStyle = stump.color;
|
| 4439 |
+
ctx.font = 'bold 14px sans-serif';
|
| 4440 |
+
ctx.textAlign = 'center';
|
| 4441 |
+
ctx.fillText(stump.name, centerX, 30);
|
| 4442 |
+
|
| 4443 |
+
// Root node
|
| 4444 |
+
ctx.fillStyle = stump.color + '33';
|
| 4445 |
+
ctx.fillRect(centerX - 40, 60, 80, 50);
|
| 4446 |
+
ctx.strokeStyle = stump.color;
|
| 4447 |
+
ctx.lineWidth = 2;
|
| 4448 |
+
ctx.strokeRect(centerX - 40, 60, 80, 50);
|
| 4449 |
+
|
| 4450 |
+
ctx.fillStyle = '#e8eef6';
|
| 4451 |
+
ctx.font = '12px sans-serif';
|
| 4452 |
+
ctx.fillText('Size <', centerX, 80);
|
| 4453 |
+
ctx.fillText(stump.split, centerX, 95);
|
| 4454 |
+
|
| 4455 |
+
// Left child
|
| 4456 |
+
ctx.strokeStyle = stump.color;
|
| 4457 |
+
ctx.beginPath();
|
| 4458 |
+
ctx.moveTo(centerX, 110);
|
| 4459 |
+
ctx.lineTo(centerX - 50, 180);
|
| 4460 |
+
ctx.stroke();
|
| 4461 |
+
|
| 4462 |
+
ctx.fillStyle = '#7ef0d4' + '33';
|
| 4463 |
+
ctx.fillRect(centerX - 85, 180, 70, 50);
|
| 4464 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 4465 |
+
ctx.strokeRect(centerX - 85, 180, 70, 50);
|
| 4466 |
+
|
| 4467 |
+
ctx.fillStyle = '#e8eef6';
|
| 4468 |
+
ctx.font = 'bold 13px sans-serif';
|
| 4469 |
+
ctx.fillText(stump.left.toFixed(2), centerX - 50, 210);
|
| 4470 |
+
|
| 4471 |
+
// Right child
|
| 4472 |
+
ctx.strokeStyle = stump.color;
|
| 4473 |
+
ctx.beginPath();
|
| 4474 |
+
ctx.moveTo(centerX, 110);
|
| 4475 |
+
ctx.lineTo(centerX + 50, 180);
|
| 4476 |
+
ctx.stroke();
|
| 4477 |
+
|
| 4478 |
+
ctx.fillStyle = '#ff8c6a' + '33';
|
| 4479 |
+
ctx.fillRect(centerX + 15, 180, 70, 50);
|
| 4480 |
+
ctx.strokeStyle = '#ff8c6a';
|
| 4481 |
+
ctx.strokeRect(centerX + 15, 180, 70, 50);
|
| 4482 |
+
|
| 4483 |
+
ctx.fillStyle = '#e8eef6';
|
| 4484 |
+
ctx.font = 'bold 13px sans-serif';
|
| 4485 |
+
ctx.fillText(stump.right.toFixed(2), centerX + 50, 210);
|
| 4486 |
+
|
| 4487 |
+
// Labels
|
| 4488 |
+
ctx.fillStyle = '#a9b4c2';
|
| 4489 |
+
ctx.font = '10px sans-serif';
|
| 4490 |
+
ctx.fillText('β€', centerX - 50, 150);
|
| 4491 |
+
ctx.fillText('>', centerX + 50, 150);
|
| 4492 |
+
});
|
| 4493 |
+
|
| 4494 |
+
// Title
|
| 4495 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4496 |
+
ctx.font = 'bold 16px sans-serif';
|
| 4497 |
+
ctx.textAlign = 'center';
|
| 4498 |
+
ctx.fillText('Weak Learner Stumps (Depth = 1)', width / 2, height - 20);
|
| 4499 |
+
|
| 4500 |
+
logViz('Gradient Boosting', 'Weak Learner Stumps', 'success');
|
| 4501 |
+
}
|
| 4502 |
+
|
| 4503 |
+
function drawGBPredictions() {
|
| 4504 |
+
const canvas = document.getElementById('gb-predictions-canvas');
|
| 4505 |
+
if (!canvas) return;
|
| 4506 |
+
|
| 4507 |
+
const actual = [120, 130, 150, 170, 200];
|
| 4508 |
+
const iter0 = [154, 154, 154, 154, 154];
|
| 4509 |
+
const iter5 = [125, 135, 148, 165, 195];
|
| 4510 |
+
const iter10 = [121, 131, 149, 169, 199];
|
| 4511 |
+
|
| 4512 |
+
createVerifiedVisualization('gb-predictions-canvas', {
|
| 4513 |
+
type: 'scatter',
|
| 4514 |
+
data: {
|
| 4515 |
+
datasets: [
|
| 4516 |
+
{
|
| 4517 |
+
label: 'Actual',
|
| 4518 |
+
data: actual.map((y, i) => ({ x: i + 1, y: y })),
|
| 4519 |
+
backgroundColor: '#7ef0d4',
|
| 4520 |
+
pointRadius: 8
|
| 4521 |
+
},
|
| 4522 |
+
{
|
| 4523 |
+
label: 'Iteration 0',
|
| 4524 |
+
data: iter0.map((y, i) => ({ x: i + 1, y: y })),
|
| 4525 |
+
backgroundColor: '#ff8c6a',
|
| 4526 |
+
pointRadius: 6
|
| 4527 |
+
},
|
| 4528 |
+
{
|
| 4529 |
+
label: 'Iteration 5',
|
| 4530 |
+
data: iter5.map((y, i) => ({ x: i + 1, y: y })),
|
| 4531 |
+
backgroundColor: '#ffb490',
|
| 4532 |
+
pointRadius: 6
|
| 4533 |
+
},
|
| 4534 |
+
{
|
| 4535 |
+
label: 'Iteration 10',
|
| 4536 |
+
data: iter10.map((y, i) => ({ x: i + 1, y: y })),
|
| 4537 |
+
backgroundColor: '#6aa9ff',
|
| 4538 |
+
pointRadius: 6
|
| 4539 |
+
}
|
| 4540 |
+
]
|
| 4541 |
+
},
|
| 4542 |
+
options: {
|
| 4543 |
+
responsive: true,
|
| 4544 |
+
maintainAspectRatio: false,
|
| 4545 |
+
plugins: {
|
| 4546 |
+
title: {
|
| 4547 |
+
display: true,
|
| 4548 |
+
text: 'Predictions Approaching Actual Values',
|
| 4549 |
+
color: '#e8eef6',
|
| 4550 |
+
font: { size: 16 }
|
| 4551 |
+
},
|
| 4552 |
+
legend: { labels: { color: '#a9b4c2' } }
|
| 4553 |
+
},
|
| 4554 |
+
scales: {
|
| 4555 |
+
x: {
|
| 4556 |
+
title: { display: true, text: 'Sample ID', color: '#a9b4c2' },
|
| 4557 |
+
grid: { color: '#2a3544' },
|
| 4558 |
+
ticks: { color: '#a9b4c2', stepSize: 1 }
|
| 4559 |
+
},
|
| 4560 |
+
y: {
|
| 4561 |
+
title: { display: true, text: 'Price (βΉ Lakhs)', color: '#a9b4c2' },
|
| 4562 |
+
grid: { color: '#2a3544' },
|
| 4563 |
+
ticks: { color: '#a9b4c2' }
|
| 4564 |
+
}
|
| 4565 |
+
}
|
| 4566 |
+
}
|
| 4567 |
+
}, 'Gradient Boosting', 'Predictions vs Actual');
|
| 4568 |
+
}
|
| 4569 |
+
|
| 4570 |
+
// Topic 17b: XGBoost (NEW)
|
| 4571 |
+
function initXGBoost() {
|
| 4572 |
+
const canvases = [
|
| 4573 |
+
{ id: 'xgb-gain-canvas', fn: drawXGBGain },
|
| 4574 |
+
{ id: 'xgb-regularization-canvas', fn: drawXGBRegularization },
|
| 4575 |
+
{ id: 'xgb-hessian-canvas', fn: drawXGBHessian },
|
| 4576 |
+
{ id: 'xgb-leaf-weights-canvas', fn: drawXGBLeafWeights },
|
| 4577 |
+
{ id: 'xgb-comparison-canvas', fn: drawXGBComparison }
|
| 4578 |
+
];
|
| 4579 |
+
|
| 4580 |
+
canvases.forEach(c => {
|
| 4581 |
+
const canvas = document.getElementById(c.id);
|
| 4582 |
+
if (canvas && !canvas.dataset.initialized) {
|
| 4583 |
+
canvas.dataset.initialized = 'true';
|
| 4584 |
+
c.fn();
|
| 4585 |
+
}
|
| 4586 |
+
});
|
| 4587 |
+
}
|
| 4588 |
+
|
| 4589 |
+
function drawXGBGain() {
|
| 4590 |
+
const canvas = document.getElementById('xgb-gain-canvas');
|
| 4591 |
+
if (!canvas) return;
|
| 4592 |
+
|
| 4593 |
+
const splits = [
|
| 4594 |
+
{ threshold: 850, gl: -58, gr: 0, hl: 2, hr: 3, gain: 1121 },
|
| 4595 |
+
{ threshold: 950, gl: -58, gr: 58, hl: 2, hr: 3, gain: 1962 },
|
| 4596 |
+
{ threshold: 1050, gl: -62, gr: 62, hl: 3, hr: 2, gain: 1842 },
|
| 4597 |
+
{ threshold: 1150, gl: -4, gr: 4, hl: 4, hr: 1, gain: 892 }
|
| 4598 |
+
];
|
| 4599 |
+
|
| 4600 |
+
createVerifiedVisualization('xgb-gain-canvas', {
|
| 4601 |
+
type: 'bar',
|
| 4602 |
+
data: {
|
| 4603 |
+
labels: splits.map(s => `Split ${s.threshold}`),
|
| 4604 |
+
datasets: [
|
| 4605 |
+
{
|
| 4606 |
+
label: 'GL (Left Gradient)',
|
| 4607 |
+
data: splits.map(s => s.gl),
|
| 4608 |
+
backgroundColor: '#ff8c6a',
|
| 4609 |
+
stack: 'gradient'
|
| 4610 |
+
},
|
| 4611 |
+
{
|
| 4612 |
+
label: 'GR (Right Gradient)',
|
| 4613 |
+
data: splits.map(s => s.gr),
|
| 4614 |
+
backgroundColor: '#6aa9ff',
|
| 4615 |
+
stack: 'gradient'
|
| 4616 |
+
},
|
| 4617 |
+
{
|
| 4618 |
+
label: 'Gain Score',
|
| 4619 |
+
data: splits.map(s => s.gain),
|
| 4620 |
+
backgroundColor: '#7ef0d4',
|
| 4621 |
+
yAxisID: 'y1'
|
| 4622 |
+
}
|
| 4623 |
+
]
|
| 4624 |
+
},
|
| 4625 |
+
options: {
|
| 4626 |
+
responsive: true,
|
| 4627 |
+
maintainAspectRatio: false,
|
| 4628 |
+
plugins: {
|
| 4629 |
+
title: {
|
| 4630 |
+
display: true,
|
| 4631 |
+
text: 'XGBoost Gain Calculation for Different Splits',
|
| 4632 |
+
color: '#e8eef6',
|
| 4633 |
+
font: { size: 16 }
|
| 4634 |
+
},
|
| 4635 |
+
legend: { labels: { color: '#a9b4c2' } }
|
| 4636 |
+
},
|
| 4637 |
+
scales: {
|
| 4638 |
+
x: {
|
| 4639 |
+
grid: { color: '#2a3544' },
|
| 4640 |
+
ticks: { color: '#a9b4c2' }
|
| 4641 |
+
},
|
| 4642 |
+
y: {
|
| 4643 |
+
title: { display: true, text: 'Gradient Sum', color: '#a9b4c2' },
|
| 4644 |
+
grid: { color: '#2a3544' },
|
| 4645 |
+
ticks: { color: '#a9b4c2' }
|
| 4646 |
+
},
|
| 4647 |
+
y1: {
|
| 4648 |
+
type: 'linear',
|
| 4649 |
+
position: 'right',
|
| 4650 |
+
title: { display: true, text: 'Gain', color: '#7ef0d4' },
|
| 4651 |
+
grid: { display: false },
|
| 4652 |
+
ticks: { color: '#a9b4c2' }
|
| 4653 |
+
}
|
| 4654 |
+
}
|
| 4655 |
+
}
|
| 4656 |
+
}, 'XGBoost', 'Gain Calculation');
|
| 4657 |
+
}
|
| 4658 |
+
|
| 4659 |
+
function drawXGBRegularization() {
|
| 4660 |
+
const canvas = document.getElementById('xgb-regularization-canvas');
|
| 4661 |
+
if (!canvas) return;
|
| 4662 |
+
|
| 4663 |
+
const lambdas = ['Ξ»=0', 'Ξ»=1', 'Ξ»=10'];
|
| 4664 |
+
const trainAcc = [0.99, 0.95, 0.88];
|
| 4665 |
+
const testAcc = [0.82, 0.93, 0.91];
|
| 4666 |
+
|
| 4667 |
+
createVerifiedVisualization('xgb-regularization-canvas', {
|
| 4668 |
+
type: 'bar',
|
| 4669 |
+
data: {
|
| 4670 |
+
labels: lambdas,
|
| 4671 |
+
datasets: [
|
| 4672 |
+
{
|
| 4673 |
+
label: 'Training Accuracy',
|
| 4674 |
+
data: trainAcc,
|
| 4675 |
+
backgroundColor: '#6aa9ff'
|
| 4676 |
+
},
|
| 4677 |
+
{
|
| 4678 |
+
label: 'Test Accuracy',
|
| 4679 |
+
data: testAcc,
|
| 4680 |
+
backgroundColor: '#7ef0d4'
|
| 4681 |
+
}
|
| 4682 |
+
]
|
| 4683 |
+
},
|
| 4684 |
+
options: {
|
| 4685 |
+
responsive: true,
|
| 4686 |
+
maintainAspectRatio: false,
|
| 4687 |
+
plugins: {
|
| 4688 |
+
title: {
|
| 4689 |
+
display: true,
|
| 4690 |
+
text: 'Regularization Effect: Ξ» Controls Overfitting',
|
| 4691 |
+
color: '#e8eef6',
|
| 4692 |
+
font: { size: 16 }
|
| 4693 |
+
},
|
| 4694 |
+
legend: { labels: { color: '#a9b4c2' } }
|
| 4695 |
+
},
|
| 4696 |
+
scales: {
|
| 4697 |
+
x: {
|
| 4698 |
+
grid: { color: '#2a3544' },
|
| 4699 |
+
ticks: { color: '#a9b4c2' }
|
| 4700 |
+
},
|
| 4701 |
+
y: {
|
| 4702 |
+
title: { display: true, text: 'Accuracy', color: '#a9b4c2' },
|
| 4703 |
+
grid: { color: '#2a3544' },
|
| 4704 |
+
ticks: { color: '#a9b4c2' },
|
| 4705 |
+
min: 0.7,
|
| 4706 |
+
max: 1.0
|
| 4707 |
+
}
|
| 4708 |
+
}
|
| 4709 |
+
}
|
| 4710 |
+
}, 'XGBoost', 'Regularization Effect');
|
| 4711 |
+
}
|
| 4712 |
+
|
| 4713 |
+
function drawXGBHessian() {
|
| 4714 |
+
const canvas = document.getElementById('xgb-hessian-canvas');
|
| 4715 |
+
if (!canvas) return;
|
| 4716 |
+
|
| 4717 |
+
const ctx = canvas.getContext('2d');
|
| 4718 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 4719 |
+
const height = canvas.height = 400;
|
| 4720 |
+
|
| 4721 |
+
ctx.clearRect(0, 0, width, height);
|
| 4722 |
+
ctx.fillStyle = '#1a2332';
|
| 4723 |
+
ctx.fillRect(0, 0, width, height);
|
| 4724 |
+
|
| 4725 |
+
const padding = 60;
|
| 4726 |
+
const chartWidth = width - 2 * padding;
|
| 4727 |
+
const chartHeight = height - 2 * padding;
|
| 4728 |
+
|
| 4729 |
+
// Draw surface comparison
|
| 4730 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4731 |
+
ctx.font = 'bold 16px sans-serif';
|
| 4732 |
+
ctx.textAlign = 'center';
|
| 4733 |
+
ctx.fillText('Hessian Provides Curvature Information', width / 2, 30);
|
| 4734 |
+
|
| 4735 |
+
// Draw gradient only curve
|
| 4736 |
+
ctx.strokeStyle = '#ff8c6a';
|
| 4737 |
+
ctx.lineWidth = 3;
|
| 4738 |
+
ctx.beginPath();
|
| 4739 |
+
for (let x = 0; x <= 10; x += 0.2) {
|
| 4740 |
+
const y = 200 - 100 * Math.exp(-Math.pow(x - 5, 2) / 8);
|
| 4741 |
+
if (x === 0) ctx.moveTo(padding + x * chartWidth / 10, y);
|
| 4742 |
+
else ctx.lineTo(padding + x * chartWidth / 10, y);
|
| 4743 |
+
}
|
| 4744 |
+
ctx.stroke();
|
| 4745 |
+
|
| 4746 |
+
// Draw gradient + hessian curve
|
| 4747 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 4748 |
+
ctx.lineWidth = 3;
|
| 4749 |
+
ctx.beginPath();
|
| 4750 |
+
for (let x = 0; x <= 10; x += 0.2) {
|
| 4751 |
+
const y = 200 - 120 * Math.exp(-Math.pow(x - 5, 2) / 5);
|
| 4752 |
+
if (x === 0) ctx.moveTo(padding + x * chartWidth / 10, y);
|
| 4753 |
+
else ctx.lineTo(padding + x * chartWidth / 10, y);
|
| 4754 |
+
}
|
| 4755 |
+
ctx.stroke();
|
| 4756 |
+
|
| 4757 |
+
// Optimum point
|
| 4758 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4759 |
+
ctx.beginPath();
|
| 4760 |
+
ctx.arc(padding + 5 * chartWidth / 10, 80, 8, 0, 2 * Math.PI);
|
| 4761 |
+
ctx.fill();
|
| 4762 |
+
|
| 4763 |
+
// Legend
|
| 4764 |
+
ctx.fillStyle = '#ff8c6a';
|
| 4765 |
+
ctx.fillRect(padding + 10, height - 80, 20, 3);
|
| 4766 |
+
ctx.fillStyle = '#e8eef6';
|
| 4767 |
+
ctx.font = '12px sans-serif';
|
| 4768 |
+
ctx.textAlign = 'left';
|
| 4769 |
+
ctx.fillText('1st order only (slower)', padding + 40, height - 75);
|
| 4770 |
+
|
| 4771 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4772 |
+
ctx.fillRect(padding + 10, height - 55, 20, 3);
|
| 4773 |
+
ctx.fillStyle = '#e8eef6';
|
| 4774 |
+
ctx.fillText('1st + 2nd order (faster)', padding + 40, height - 50);
|
| 4775 |
+
|
| 4776 |
+
logViz('XGBoost', 'Hessian Contribution', 'success');
|
| 4777 |
+
}
|
| 4778 |
+
|
| 4779 |
+
function drawXGBLeafWeights() {
|
| 4780 |
+
const canvas = document.getElementById('xgb-leaf-weights-canvas');
|
| 4781 |
+
if (!canvas) return;
|
| 4782 |
+
|
| 4783 |
+
const ctx = canvas.getContext('2d');
|
| 4784 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 4785 |
+
const height = canvas.height = 350;
|
| 4786 |
+
|
| 4787 |
+
ctx.clearRect(0, 0, width, height);
|
| 4788 |
+
ctx.fillStyle = '#1a2332';
|
| 4789 |
+
ctx.fillRect(0, 0, width, height);
|
| 4790 |
+
|
| 4791 |
+
const padding = 40;
|
| 4792 |
+
const boxWidth = 300;
|
| 4793 |
+
const boxHeight = 120;
|
| 4794 |
+
|
| 4795 |
+
// Left leaf
|
| 4796 |
+
const leftX = width / 4 - boxWidth / 2;
|
| 4797 |
+
ctx.fillStyle = '#7ef0d4' + '22';
|
| 4798 |
+
ctx.fillRect(leftX, 80, boxWidth, boxHeight);
|
| 4799 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 4800 |
+
ctx.lineWidth = 3;
|
| 4801 |
+
ctx.strokeRect(leftX, 80, boxWidth, boxHeight);
|
| 4802 |
+
|
| 4803 |
+
ctx.fillStyle = '#e8eef6';
|
| 4804 |
+
ctx.font = 'bold 14px sans-serif';
|
| 4805 |
+
ctx.textAlign = 'left';
|
| 4806 |
+
ctx.fillText('Left Leaf (Size β€ 950):', leftX + 10, 105);
|
| 4807 |
+
ctx.font = '12px monospace';
|
| 4808 |
+
ctx.fillText('w = -G / (H + Ξ»)', leftX + 10, 130);
|
| 4809 |
+
ctx.fillText(' = -(-58) / (2 + 1)', leftX + 10, 150);
|
| 4810 |
+
ctx.fillText(' = 58 / 3', leftX + 10, 170);
|
| 4811 |
+
ctx.font = 'bold 16px monospace';
|
| 4812 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4813 |
+
ctx.fillText(' = 19.33', leftX + 10, 190);
|
| 4814 |
+
|
| 4815 |
+
// Right leaf
|
| 4816 |
+
const rightX = 3 * width / 4 - boxWidth / 2;
|
| 4817 |
+
ctx.fillStyle = '#ff8c6a' + '22';
|
| 4818 |
+
ctx.fillRect(rightX, 80, boxWidth, boxHeight);
|
| 4819 |
+
ctx.strokeStyle = '#ff8c6a';
|
| 4820 |
+
ctx.lineWidth = 3;
|
| 4821 |
+
ctx.strokeRect(rightX, 80, boxWidth, boxHeight);
|
| 4822 |
+
|
| 4823 |
+
ctx.fillStyle = '#e8eef6';
|
| 4824 |
+
ctx.font = 'bold 14px sans-serif';
|
| 4825 |
+
ctx.textAlign = 'left';
|
| 4826 |
+
ctx.fillText('Right Leaf (Size > 950):', rightX + 10, 105);
|
| 4827 |
+
ctx.font = '12px monospace';
|
| 4828 |
+
ctx.fillText('w = -G / (H + Ξ»)', rightX + 10, 130);
|
| 4829 |
+
ctx.fillText(' = -(58) / (3 + 1)', rightX + 10, 150);
|
| 4830 |
+
ctx.fillText(' = -58 / 4', rightX + 10, 170);
|
| 4831 |
+
ctx.font = 'bold 16px monospace';
|
| 4832 |
+
ctx.fillStyle = '#ff8c6a';
|
| 4833 |
+
ctx.fillText(' = -14.5', rightX + 10, 190);
|
| 4834 |
+
|
| 4835 |
+
// Title
|
| 4836 |
+
ctx.fillStyle = '#7ef0d4';
|
| 4837 |
+
ctx.font = 'bold 16px sans-serif';
|
| 4838 |
+
ctx.textAlign = 'center';
|
| 4839 |
+
ctx.fillText('Leaf Weight Calculation (Ξ» = 1)', width / 2, 40);
|
| 4840 |
+
|
| 4841 |
+
// Formula reminder
|
| 4842 |
+
ctx.fillStyle = '#a9b4c2';
|
| 4843 |
+
ctx.font = '13px sans-serif';
|
| 4844 |
+
ctx.fillText('Negative gradient divided by (Hessian + regularization)', width / 2, height - 20);
|
| 4845 |
+
|
| 4846 |
+
logViz('XGBoost', 'Leaf Weight Calculation', 'success');
|
| 4847 |
+
}
|
| 4848 |
+
|
| 4849 |
+
function drawXGBComparison() {
|
| 4850 |
+
const canvas = document.getElementById('xgb-comparison-canvas');
|
| 4851 |
+
if (!canvas) return;
|
| 4852 |
+
|
| 4853 |
+
createVerifiedVisualization('xgb-comparison-canvas', {
|
| 4854 |
+
type: 'radar',
|
| 4855 |
+
data: {
|
| 4856 |
+
labels: ['Accuracy', 'Speed', 'Robustness', 'Ease of Use', 'Scalability', 'Interpretability'],
|
| 4857 |
+
datasets: [
|
| 4858 |
+
{
|
| 4859 |
+
label: 'Gradient Boosting',
|
| 4860 |
+
data: [4.5, 3, 3.5, 4, 3, 3],
|
| 4861 |
+
borderColor: '#ff8c6a',
|
| 4862 |
+
backgroundColor: 'rgba(255, 140, 106, 0.2)',
|
| 4863 |
+
borderWidth: 2
|
| 4864 |
+
},
|
| 4865 |
+
{
|
| 4866 |
+
label: 'XGBoost',
|
| 4867 |
+
data: [5, 4.5, 5, 4, 5, 3],
|
| 4868 |
+
borderColor: '#7ef0d4',
|
| 4869 |
+
backgroundColor: 'rgba(126, 240, 212, 0.2)',
|
| 4870 |
+
borderWidth: 2
|
| 4871 |
+
}
|
| 4872 |
+
]
|
| 4873 |
+
},
|
| 4874 |
+
options: {
|
| 4875 |
+
responsive: true,
|
| 4876 |
+
maintainAspectRatio: false,
|
| 4877 |
+
plugins: {
|
| 4878 |
+
title: {
|
| 4879 |
+
display: true,
|
| 4880 |
+
text: 'Gradient Boosting vs XGBoost: Comprehensive Comparison',
|
| 4881 |
+
color: '#e8eef6',
|
| 4882 |
+
font: { size: 16 }
|
| 4883 |
+
},
|
| 4884 |
+
legend: {
|
| 4885 |
+
position: 'top',
|
| 4886 |
+
labels: { color: '#a9b4c2', padding: 15 }
|
| 4887 |
+
}
|
| 4888 |
+
},
|
| 4889 |
+
scales: {
|
| 4890 |
+
r: {
|
| 4891 |
+
beginAtZero: true,
|
| 4892 |
+
max: 5,
|
| 4893 |
+
ticks: { color: '#a9b4c2', backdropColor: 'transparent' },
|
| 4894 |
+
grid: { color: '#2a3544' },
|
| 4895 |
+
pointLabels: { color: '#e8eef6', font: { size: 12 } }
|
| 4896 |
+
}
|
| 4897 |
+
}
|
| 4898 |
+
}
|
| 4899 |
+
}, 'XGBoost', 'GB vs XGB Comparison');
|
| 4900 |
+
}
|
| 4901 |
+
|
| 4902 |
+
function initBagging() {
|
| 4903 |
+
const canvas = document.getElementById('bagging-complete-canvas');
|
| 4904 |
+
if (canvas && !canvas.dataset.initialized) {
|
| 4905 |
+
canvas.dataset.initialized = 'true';
|
| 4906 |
+
drawBaggingCompleteViz();
|
| 4907 |
+
}
|
| 4908 |
+
}
|
| 4909 |
+
|
| 4910 |
+
function initBoostingAdaBoost() {
|
| 4911 |
+
const canvas = document.getElementById('boosting-complete-canvas');
|
| 4912 |
+
if (canvas && !canvas.dataset.initialized) {
|
| 4913 |
+
canvas.dataset.initialized = 'true';
|
| 4914 |
+
drawBoostingCompleteViz();
|
| 4915 |
+
}
|
| 4916 |
+
}
|
| 4917 |
+
|
| 4918 |
+
function initRandomForest() {
|
| 4919 |
+
const canvas = document.getElementById('rf-complete-canvas');
|
| 4920 |
+
if (canvas && !canvas.dataset.initialized) {
|
| 4921 |
+
canvas.dataset.initialized = 'true';
|
| 4922 |
+
drawRandomForestCompleteViz();
|
| 4923 |
+
}
|
| 4924 |
+
}
|
| 4925 |
+
|
| 4926 |
+
// Topic 17: Ensemble Methods
|
| 4927 |
+
function initEnsembleMethods() {
|
| 4928 |
+
const canvasNew1 = document.getElementById('bagging-complete-canvas');
|
| 4929 |
+
if (canvasNew1 && !canvasNew1.dataset.initialized) {
|
| 4930 |
+
canvasNew1.dataset.initialized = 'true';
|
| 4931 |
+
drawBaggingCompleteViz();
|
| 4932 |
+
}
|
| 4933 |
+
|
| 4934 |
+
const canvasNew2 = document.getElementById('boosting-complete-canvas');
|
| 4935 |
+
if (canvasNew2 && !canvasNew2.dataset.initialized) {
|
| 4936 |
+
canvasNew2.dataset.initialized = 'true';
|
| 4937 |
+
drawBoostingCompleteViz();
|
| 4938 |
+
}
|
| 4939 |
+
|
| 4940 |
+
const canvasNew3 = document.getElementById('rf-complete-canvas');
|
| 4941 |
+
if (canvasNew3 && !canvasNew3.dataset.initialized) {
|
| 4942 |
+
canvasNew3.dataset.initialized = 'true';
|
| 4943 |
+
drawRandomForestCompleteViz();
|
| 4944 |
+
}
|
| 4945 |
+
|
| 4946 |
+
const canvas1 = document.getElementById('bagging-viz');
|
| 4947 |
+
if (canvas1 && !canvas1.dataset.initialized) {
|
| 4948 |
+
canvas1.dataset.initialized = 'true';
|
| 4949 |
+
drawBaggingViz();
|
| 4950 |
+
}
|
| 4951 |
+
|
| 4952 |
+
const canvas2 = document.getElementById('boosting-viz');
|
| 4953 |
+
if (canvas2 && !canvas2.dataset.initialized) {
|
| 4954 |
+
canvas2.dataset.initialized = 'true';
|
| 4955 |
+
drawBoostingViz();
|
| 4956 |
+
}
|
| 4957 |
+
|
| 4958 |
+
const canvas3 = document.getElementById('random-forest-viz');
|
| 4959 |
+
if (canvas3 && !canvas3.dataset.initialized) {
|
| 4960 |
+
canvas3.dataset.initialized = 'true';
|
| 4961 |
+
drawRandomForestViz();
|
| 4962 |
+
}
|
| 4963 |
+
}
|
| 4964 |
+
|
| 4965 |
+
function drawBaggingCompleteViz() {
|
| 4966 |
+
const canvas = document.getElementById('bagging-complete-canvas');
|
| 4967 |
+
if (!canvas) {
|
| 4968 |
+
logViz('Ensemble Methods', 'Bagging Complete', 'failed', 'Canvas not found');
|
| 4969 |
+
return;
|
| 4970 |
+
}
|
| 4971 |
+
|
| 4972 |
+
const ctx = canvas.getContext('2d');
|
| 4973 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 4974 |
+
const height = canvas.height = 400;
|
| 4975 |
+
|
| 4976 |
+
ctx.clearRect(0, 0, width, height);
|
| 4977 |
+
ctx.fillStyle = '#1a2332';
|
| 4978 |
+
ctx.fillRect(0, 0, width, height);
|
| 4979 |
+
|
| 4980 |
+
const treeY = 100;
|
| 4981 |
+
const predY = 280;
|
| 4982 |
+
const finalY = 350;
|
| 4983 |
+
|
| 4984 |
+
// Three trees
|
| 4985 |
+
for (let i = 0; i < 3; i++) {
|
| 4986 |
+
const x = 150 + i * 250;
|
| 4987 |
+
const preds = [75, 72, 78];
|
| 4988 |
+
|
| 4989 |
+
// Tree box
|
| 4990 |
+
ctx.fillStyle = '#7ef0d433';
|
| 4991 |
+
ctx.fillRect(x - 50, treeY, 100, 60);
|
| 4992 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 4993 |
+
ctx.lineWidth = 2;
|
| 4994 |
+
ctx.strokeRect(x - 50, treeY, 100, 60);
|
| 4995 |
+
|
| 4996 |
+
ctx.fillStyle = '#e8eef6';
|
| 4997 |
+
ctx.font = 'bold 14px sans-serif';
|
| 4998 |
+
ctx.textAlign = 'center';
|
| 4999 |
+
ctx.fillText(`Tree ${i + 1}`, x, treeY + 35);
|
| 5000 |
+
|
| 5001 |
+
// Prediction
|
| 5002 |
+
ctx.fillStyle = '#6aa9ff33';
|
| 5003 |
+
ctx.fillRect(x - 40, predY, 80, 50);
|
| 5004 |
+
ctx.strokeStyle = '#6aa9ff';
|
| 5005 |
+
ctx.strokeRect(x - 40, predY, 80, 50);
|
| 5006 |
+
|
| 5007 |
+
ctx.fillStyle = '#e8eef6';
|
| 5008 |
+
ctx.font = 'bold 16px sans-serif';
|
| 5009 |
+
ctx.fillText(`βΉ${preds[i]}L`, x, predY + 32);
|
| 5010 |
+
|
| 5011 |
+
// Arrow to final
|
| 5012 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 5013 |
+
ctx.lineWidth = 2;
|
| 5014 |
+
ctx.beginPath();
|
| 5015 |
+
ctx.moveTo(x, predY + 50);
|
| 5016 |
+
ctx.lineTo(width / 2, finalY - 10);
|
| 5017 |
+
ctx.stroke();
|
| 5018 |
+
}
|
| 5019 |
+
|
| 5020 |
+
// Final average
|
| 5021 |
+
ctx.fillStyle = '#ff8c6a33';
|
| 5022 |
+
ctx.fillRect(width / 2 - 80, finalY, 160, 50);
|
| 5023 |
+
ctx.strokeStyle = '#ff8c6a';
|
| 5024 |
+
ctx.lineWidth = 3;
|
| 5025 |
+
ctx.strokeRect(width / 2 - 80, finalY, 160, 50);
|
| 5026 |
+
|
| 5027 |
+
ctx.fillStyle = '#e8eef6';
|
| 5028 |
+
ctx.font = 'bold 18px sans-serif';
|
| 5029 |
+
ctx.textAlign = 'center';
|
| 5030 |
+
ctx.fillText('Avg = βΉ75L β', width / 2, finalY + 32);
|
| 5031 |
+
|
| 5032 |
+
// Title
|
| 5033 |
+
ctx.fillStyle = '#7ef0d4';
|
| 5034 |
+
ctx.font = 'bold 16px sans-serif';
|
| 5035 |
+
ctx.fillText('Bagging: Average of 3 Trees', width / 2, 30);
|
| 5036 |
+
|
| 5037 |
+
logViz('Ensemble Methods', 'Bagging Complete', 'success');
|
| 5038 |
+
}
|
| 5039 |
+
|
| 5040 |
+
function drawBoostingCompleteViz() {
|
| 5041 |
+
const canvas = document.getElementById('boosting-complete-canvas');
|
| 5042 |
+
if (!canvas) {
|
| 5043 |
+
logViz('Ensemble Methods', 'Boosting Complete', 'failed', 'Canvas not found');
|
| 5044 |
+
return;
|
| 5045 |
+
}
|
| 5046 |
+
|
| 5047 |
+
const ctx = canvas.getContext('2d');
|
| 5048 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 5049 |
+
const height = canvas.height = 450;
|
| 5050 |
+
|
| 5051 |
+
ctx.clearRect(0, 0, width, height);
|
| 5052 |
+
ctx.fillStyle = '#1a2332';
|
| 5053 |
+
ctx.fillRect(0, 0, width, height);
|
| 5054 |
+
|
| 5055 |
+
const rounds = [
|
| 5056 |
+
{label: 'Round 1', weights: [1, 1, 1, 1, 1, 1], errors: [20, 20, 21, 2, 3, 2]},
|
| 5057 |
+
{label: 'Round 2', weights: [1, 1, 1, 2.5, 3, 2.5], errors: [21, 21, 20, 0, 1, 0]},
|
| 5058 |
+
{label: 'Round 3', weights: [2, 2, 2, 1, 1, 1], errors: [20, 20, 21, 1, 2, 1]}
|
| 5059 |
+
];
|
| 5060 |
+
|
| 5061 |
+
const startX = 60;
|
| 5062 |
+
const barWidth = 30;
|
| 5063 |
+
const gap = 10;
|
| 5064 |
+
|
| 5065 |
+
rounds.forEach((round, r) => {
|
| 5066 |
+
const y = 80 + r * 120;
|
| 5067 |
+
|
| 5068 |
+
ctx.fillStyle = '#7ef0d4';
|
| 5069 |
+
ctx.font = 'bold 14px sans-serif';
|
| 5070 |
+
ctx.textAlign = 'left';
|
| 5071 |
+
ctx.fillText(round.label, 10, y + 20);
|
| 5072 |
+
|
| 5073 |
+
// Weight bars
|
| 5074 |
+
round.weights.forEach((w, i) => {
|
| 5075 |
+
const x = startX + i * (barWidth + gap);
|
| 5076 |
+
const h = w * 20;
|
| 5077 |
+
|
| 5078 |
+
ctx.fillStyle = w > 1.5 ? '#ff8c6a' : '#6aa9ff';
|
| 5079 |
+
ctx.fillRect(x, y + 40 - h, barWidth, h);
|
| 5080 |
+
|
| 5081 |
+
// Error text
|
| 5082 |
+
ctx.fillStyle = '#a9b4c2';
|
| 5083 |
+
ctx.font = '9px sans-serif';
|
| 5084 |
+
ctx.textAlign = 'center';
|
| 5085 |
+
ctx.fillText(`e=${round.errors[i]}`, x + barWidth / 2, y + 55);
|
| 5086 |
+
});
|
| 5087 |
+
});
|
| 5088 |
+
|
| 5089 |
+
ctx.fillStyle = '#7ef0d4';
|
| 5090 |
+
ctx.font = 'bold 16px sans-serif';
|
| 5091 |
+
ctx.textAlign = 'center';
|
| 5092 |
+
ctx.fillText('Boosting: Sequential Weight Updates', width / 2, 30);
|
| 5093 |
+
ctx.fillText('Final: Ξ±βΓMβ + Ξ±βΓMβ + Ξ±βΓMβ = βΉ74.7L', width / 2, height - 20);
|
| 5094 |
+
}
|
| 5095 |
+
|
| 5096 |
+
function drawRandomForestCompleteViz() {
|
| 5097 |
+
const canvas = document.getElementById('rf-complete-canvas');
|
| 5098 |
+
if (!canvas) {
|
| 5099 |
+
logViz('Ensemble Methods', 'Random Forest Complete', 'failed', 'Canvas not found');
|
| 5100 |
+
return;
|
| 5101 |
+
}
|
| 5102 |
+
|
| 5103 |
+
const ctx = canvas.getContext('2d');
|
| 5104 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 5105 |
+
const height = canvas.height = 500;
|
| 5106 |
+
|
| 5107 |
+
ctx.clearRect(0, 0, width, height);
|
| 5108 |
+
ctx.fillStyle = '#1a2332';
|
| 5109 |
+
ctx.fillRect(0, 0, width, height);
|
| 5110 |
+
|
| 5111 |
+
// Show 3 trees with feature randomness
|
| 5112 |
+
const trees = [
|
| 5113 |
+
{features: ['Sq Ft', 'Age'], pred: 74},
|
| 5114 |
+
{features: ['Sq Ft', 'Beds'], pred: 76},
|
| 5115 |
+
{features: ['Beds', 'Age'], pred: 75}
|
| 5116 |
+
];
|
| 5117 |
+
|
| 5118 |
+
trees.forEach((tree, i) => {
|
| 5119 |
+
const x = 120 + i * 260;
|
| 5120 |
+
const y = 100;
|
| 5121 |
+
|
| 5122 |
+
// Bootstrap
|
| 5123 |
+
ctx.fillStyle = '#6aa9ff33';
|
| 5124 |
+
ctx.fillRect(x - 60, y, 120, 50);
|
| 5125 |
+
ctx.strokeStyle = '#6aa9ff';
|
| 5126 |
+
ctx.lineWidth = 2;
|
| 5127 |
+
ctx.strokeRect(x - 60, y, 120, 50);
|
| 5128 |
+
ctx.fillStyle = '#e8eef6';
|
| 5129 |
+
ctx.font = '12px sans-serif';
|
| 5130 |
+
ctx.textAlign = 'center';
|
| 5131 |
+
ctx.fillText('Bootstrap', x, y + 25);
|
| 5132 |
+
ctx.fillText(`Sample ${i + 1}`, x, y + 40);
|
| 5133 |
+
|
| 5134 |
+
// Tree with random features
|
| 5135 |
+
ctx.fillStyle = '#7ef0d433';
|
| 5136 |
+
ctx.fillRect(x - 60, y + 80, 120, 70);
|
| 5137 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 5138 |
+
ctx.strokeRect(x - 60, y + 80, 120, 70);
|
| 5139 |
+
ctx.fillStyle = '#e8eef6';
|
| 5140 |
+
ctx.font = 'bold 13px sans-serif';
|
| 5141 |
+
ctx.fillText(`Tree ${i + 1}`, x, y + 105);
|
| 5142 |
+
ctx.font = '10px sans-serif';
|
| 5143 |
+
ctx.fillStyle = '#ffb490';
|
| 5144 |
+
ctx.fillText('Random:', x, y + 123);
|
| 5145 |
+
ctx.fillText(tree.features.join(', '), x, y + 138);
|
| 5146 |
+
|
| 5147 |
+
// Prediction
|
| 5148 |
+
ctx.fillStyle = '#ff8c6a33';
|
| 5149 |
+
ctx.fillRect(x - 50, y + 180, 100, 50);
|
| 5150 |
+
ctx.strokeStyle = '#ff8c6a';
|
| 5151 |
+
ctx.strokeRect(x - 50, y + 180, 100, 50);
|
| 5152 |
+
ctx.fillStyle = '#e8eef6';
|
| 5153 |
+
ctx.font = 'bold 16px sans-serif';
|
| 5154 |
+
ctx.fillText(`βΉ${tree.pred}L`, x, y + 210);
|
| 5155 |
+
|
| 5156 |
+
// Arrow to final
|
| 5157 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 5158 |
+
ctx.lineWidth = 2;
|
| 5159 |
+
ctx.beginPath();
|
| 5160 |
+
ctx.moveTo(x, y + 230);
|
| 5161 |
+
ctx.lineTo(width / 2, y + 300);
|
| 5162 |
+
ctx.stroke();
|
| 5163 |
+
});
|
| 5164 |
+
|
| 5165 |
+
// Final average
|
| 5166 |
+
ctx.fillStyle = '#7ef0d433';
|
| 5167 |
+
ctx.fillRect(width / 2 - 100, 400, 200, 70);
|
| 5168 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 5169 |
+
ctx.lineWidth = 3;
|
| 5170 |
+
ctx.strokeRect(width / 2 - 100, 400, 200, 70);
|
| 5171 |
+
ctx.fillStyle = '#e8eef6';
|
| 5172 |
+
ctx.font = 'bold 18px sans-serif';
|
| 5173 |
+
ctx.textAlign = 'center';
|
| 5174 |
+
ctx.fillText('Average of 100 Trees', width / 2, 425);
|
| 5175 |
+
ctx.fillText('= βΉ75.2L Β± βΉ2.3L β', width / 2, 450);
|
| 5176 |
+
|
| 5177 |
+
// Title
|
| 5178 |
+
ctx.fillStyle = '#7ef0d4';
|
| 5179 |
+
ctx.font = 'bold 16px sans-serif';
|
| 5180 |
+
ctx.fillText('Random Forest: Bootstrap + Feature Randomness', width / 2, 30);
|
| 5181 |
+
|
| 5182 |
+
logViz('Ensemble Methods', 'Random Forest Complete', 'success');
|
| 5183 |
+
}
|
| 5184 |
+
|
| 5185 |
+
function drawBaggingViz() {
|
| 5186 |
+
const canvas = document.getElementById('bagging-viz');
|
| 5187 |
+
if (!canvas) {
|
| 5188 |
+
logViz('Ensemble Methods', 'Bagging Viz', 'failed', 'Canvas not found');
|
| 5189 |
+
return;
|
| 5190 |
+
}
|
| 5191 |
+
|
| 5192 |
+
const ctx = canvas.getContext('2d');
|
| 5193 |
+
const width = canvas.width = canvas.offsetWidth;
|
| 5194 |
+
const height = canvas.height = 400;
|
| 5195 |
+
|
| 5196 |
+
ctx.clearRect(0, 0, width, height);
|
| 5197 |
+
ctx.fillStyle = '#1a2332';
|
| 5198 |
+
ctx.fillRect(0, 0, width, height);
|
| 5199 |
+
|
| 5200 |
+
const boxWidth = 150;
|
| 5201 |
+
const boxHeight = 60;
|
| 5202 |
+
const startY = 60;
|
| 5203 |
+
const spacing = (width - 3 * boxWidth) / 4;
|
| 5204 |
+
|
| 5205 |
+
// Original data
|
| 5206 |
+
ctx.fillStyle = '#6aa9ff33';
|
| 5207 |
+
ctx.fillRect(width / 2 - 100, startY, 200, boxHeight);
|
| 5208 |
+
ctx.strokeStyle = '#6aa9ff';
|
| 5209 |
+
ctx.lineWidth = 2;
|
| 5210 |
+
ctx.strokeRect(width / 2 - 100, startY, 200, boxHeight);
|
| 5211 |
+
ctx.fillStyle = '#e8eef6';
|
| 5212 |
+
ctx.font = 'bold 14px sans-serif';
|
| 5213 |
+
ctx.textAlign = 'center';
|
| 5214 |
+
ctx.fillText('Original Dataset', width / 2, startY + boxHeight / 2 + 5);
|
| 5215 |
+
|
| 5216 |
+
// Bootstrap samples
|
| 5217 |
+
const sampleY = startY + boxHeight + 60;
|
| 5218 |
+
for (let i = 0; i < 3; i++) {
|
| 5219 |
+
const x = spacing + i * (boxWidth + spacing);
|
| 5220 |
+
|
| 5221 |
+
// Arrow
|
| 5222 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 5223 |
+
ctx.lineWidth = 2;
|
| 5224 |
+
ctx.beginPath();
|
| 5225 |
+
ctx.moveTo(width / 2, startY + boxHeight);
|
| 5226 |
+
ctx.lineTo(x + boxWidth / 2, sampleY);
|
| 5227 |
+
ctx.stroke();
|
| 5228 |
+
|
| 5229 |
+
// Sample box
|
| 5230 |
+
ctx.fillStyle = '#7ef0d433';
|
| 5231 |
+
ctx.fillRect(x, sampleY, boxWidth, boxHeight);
|
| 5232 |
+
ctx.strokeStyle = '#7ef0d4';
|
| 5233 |
+
ctx.strokeRect(x, sampleY, boxWidth, boxHeight);
|
| 5234 |
+
|
| 5235 |
+
ctx.fillStyle = '#e8eef6';
|
| 5236 |
+
ctx.font = 'bold 12px sans-serif';
|
| 5237 |
+
ctx.fillText(`Bootstrap ${i + 1}`, x + boxWidth / 2, sampleY + boxHeight / 2 - 5);
|
| 5238 |
+
ctx.font = '10px sans-serif';
|
| 5239 |
ctx.fillStyle = '#a9b4c2';
|
| 5240 |
ctx.fillText('(random sample)', x + boxWidth / 2, sampleY + boxHeight / 2 + 10);
|
| 5241 |
|
|
|
|
| 5386 |
ctx.fillStyle = '#ff8c6a';
|
| 5387 |
ctx.font = 'bold 14px sans-serif';
|
| 5388 |
ctx.fillText('Final Prediction = Weighted Combination of All Models', width / 2, height - 20);
|
| 5389 |
+
|
| 5390 |
+
logViz('Ensemble Methods', 'Boosting Complete', 'success');
|
| 5391 |
+
}
|
| 5392 |
+
|
| 5393 |
+
function drawGBLearningRate() {
|
| 5394 |
+
// Implementation moved to Gradient Boosting section
|
| 5395 |
+
}
|
| 5396 |
+
|
| 5397 |
+
function drawGBStumps() {
|
| 5398 |
+
// Implementation moved to Gradient Boosting section
|
| 5399 |
+
}
|
| 5400 |
+
|
| 5401 |
+
function drawGBPredictions() {
|
| 5402 |
+
// Implementation moved to Gradient Boosting section
|
| 5403 |
+
}
|
| 5404 |
+
|
| 5405 |
+
function drawXGBGain() {
|
| 5406 |
+
// Implementation moved to XGBoost section
|
| 5407 |
+
}
|
| 5408 |
+
|
| 5409 |
+
function drawXGBRegularization() {
|
| 5410 |
+
// Implementation moved to XGBoost section
|
| 5411 |
+
}
|
| 5412 |
+
|
| 5413 |
+
function drawXGBHessian() {
|
| 5414 |
+
// Implementation moved to XGBoost section
|
| 5415 |
+
}
|
| 5416 |
+
|
| 5417 |
+
function drawXGBLeafWeights() {
|
| 5418 |
+
// Implementation moved to XGBoost section
|
| 5419 |
+
}
|
| 5420 |
+
|
| 5421 |
+
function drawXGBComparison() {
|
| 5422 |
+
// Implementation moved to XGBoost section
|
| 5423 |
}
|
| 5424 |
|
| 5425 |
function drawRandomForestViz() {
|
|
|
|
| 5528 |
ctx.fillStyle = '#7ef0d4';
|
| 5529 |
ctx.font = 'bold 16px sans-serif';
|
| 5530 |
ctx.fillText('Random Forest: Ensemble of Decision Trees', width / 2, 25);
|
| 5531 |
+
|
| 5532 |
+
logViz('Ensemble Methods', 'Bagging Viz', 'success');
|
| 5533 |
}
|
| 5534 |
|
| 5535 |
// Topic 16: K-means Clustering
|
|
|
|
| 5552 |
|
| 5553 |
function drawKMeansVisualization() {
|
| 5554 |
const canvas = document.getElementById('kmeans-viz-canvas');
|
| 5555 |
+
if (!canvas) {
|
| 5556 |
+
logViz('K-means', 'Scatter + Centroids', 'failed', 'Canvas not found');
|
| 5557 |
+
return;
|
| 5558 |
+
}
|
| 5559 |
|
| 5560 |
const ctx = canvas.getContext('2d');
|
| 5561 |
const width = canvas.width = canvas.offsetWidth;
|
|
|
|
| 5675 |
ctx.font = '14px sans-serif';
|
| 5676 |
ctx.textAlign = 'left';
|
| 5677 |
ctx.fillText('WCSS = 15.984', padding, height - padding + 30);
|
| 5678 |
+
|
| 5679 |
+
logViz('K-means', 'Scatter + Centroids', 'success');
|
| 5680 |
}
|
| 5681 |
|
| 5682 |
function drawKMeansElbow() {
|
|
|
|
| 5692 |
const kValues = [1, 2, 3, 4, 5];
|
| 5693 |
const wcssValues = [50, 18, 10, 8, 7];
|
| 5694 |
|
| 5695 |
+
kmeansElbowChart = createVerifiedVisualization('kmeans-elbow-canvas', {
|
| 5696 |
type: 'line',
|
| 5697 |
data: {
|
| 5698 |
labels: kValues,
|
|
|
|
| 5755 |
}
|
| 5756 |
}
|
| 5757 |
}
|
| 5758 |
+
}, 'K-means', 'Elbow Method');
|
| 5759 |
}
|
| 5760 |
|
| 5761 |
// Topic 18: Algorithm Comparison
|
|
|
|
| 5991 |
|
| 5992 |
html += '</tbody>';
|
| 5993 |
table.innerHTML = html;
|
| 5994 |
+
|
| 5995 |
+
logViz('Algorithm Comparison', 'Comparison Table', 'success');
|
| 5996 |
}
|
| 5997 |
|
| 5998 |
let radarComparisonChart = null;
|
|
|
|
| 6024 |
};
|
| 6025 |
});
|
| 6026 |
|
| 6027 |
+
if (radarComparisonChart) {
|
| 6028 |
+
radarComparisonChart.destroy();
|
| 6029 |
+
radarComparisonChart = null;
|
| 6030 |
+
}
|
| 6031 |
+
|
| 6032 |
+
radarComparisonChart = createVerifiedVisualization('radar-comparison-canvas', {
|
| 6033 |
type: 'radar',
|
| 6034 |
data: {
|
| 6035 |
labels: ['Speed', 'Accuracy', 'Data Efficiency', 'Interpretability', 'Scalability'],
|
|
|
|
| 6054 |
}
|
| 6055 |
}
|
| 6056 |
}
|
| 6057 |
+
}, 'Algorithm Comparison', 'Radar Chart');
|
| 6058 |
}
|
| 6059 |
|
| 6060 |
function renderHeatmap() {
|
|
|
|
| 6110 |
html += '</table>';
|
| 6111 |
html += '</div>';
|
| 6112 |
|
| 6113 |
+
logViz('Algorithm Comparison', 'Heatmap', 'success');
|
| 6114 |
+
|
| 6115 |
// Legend
|
| 6116 |
html += '<div style="text-align: center; margin-top: 24px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">';
|
| 6117 |
html += '<strong style="color: #e8eef6;">Legend:</strong> ';
|
|
|
|
| 6160 |
|
| 6161 |
html += '</tbody>';
|
| 6162 |
table.innerHTML = html;
|
| 6163 |
+
|
| 6164 |
+
logViz('Algorithm Comparison', 'Use Case Matrix', 'success');
|
| 6165 |
}
|
| 6166 |
|
| 6167 |
function renderDetailedCards() {
|
|
|
|
| 6201 |
|
| 6202 |
html += '</div>';
|
| 6203 |
container.innerHTML = html;
|
| 6204 |
+
|
| 6205 |
+
logViz('Algorithm Comparison', 'Detailed Cards', 'success');
|
| 6206 |
}
|
| 6207 |
|
| 6208 |
function initQuiz() {
|
|
|
|
| 6366 |
ctx.fillText('Algorithm Selection Flowchart', width/2, 25);
|
| 6367 |
}
|
| 6368 |
|
| 6369 |
+
// Diagnostic Functions
|
| 6370 |
+
function showDiagnostics() {
|
| 6371 |
+
const browserDetails = document.getElementById('browser-details');
|
| 6372 |
+
if (browserDetails) {
|
| 6373 |
+
browserDetails.innerHTML = `
|
| 6374 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Browser: ${navigator.userAgent.split(' ').slice(-2).join(' ')}</li>
|
| 6375 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Platform: ${navigator.platform}</li>
|
| 6376 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Language: ${navigator.language}</li>
|
| 6377 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Online: ${navigator.onLine ? 'β Yes' : 'β No'}</li>
|
| 6378 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Cookies Enabled: ${navigator.cookieEnabled ? 'β Yes' : 'β No'}</li>
|
| 6379 |
+
`;
|
| 6380 |
+
}
|
| 6381 |
+
|
| 6382 |
+
const libraryDetails = document.getElementById('library-details');
|
| 6383 |
+
if (libraryDetails) {
|
| 6384 |
+
const chartJsLoaded = typeof Chart !== 'undefined';
|
| 6385 |
+
const canvasSupport = !!document.createElement('canvas').getContext('2d');
|
| 6386 |
+
|
| 6387 |
+
libraryDetails.innerHTML = `
|
| 6388 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Chart.js: ${chartJsLoaded ? 'β Loaded (v' + (Chart.version || '4.x') + ')' : 'β Missing'}</li>
|
| 6389 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Canvas Support: ${canvasSupport ? 'β Yes' : 'β No'}</li>
|
| 6390 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Device Pixel Ratio: ${window.devicePixelRatio || 1}</li>
|
| 6391 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Screen Resolution: ${window.screen.width}x${window.screen.height}</li>
|
| 6392 |
+
`;
|
| 6393 |
+
}
|
| 6394 |
+
|
| 6395 |
+
const successCount = document.getElementById('diag-success-count');
|
| 6396 |
+
const failedCount = document.getElementById('diag-failed-count');
|
| 6397 |
+
const warningCount = document.getElementById('diag-warning-count');
|
| 6398 |
+
|
| 6399 |
+
if (successCount) successCount.textContent = vizLog.success.length;
|
| 6400 |
+
if (failedCount) failedCount.textContent = vizLog.failed.length;
|
| 6401 |
+
if (warningCount) warningCount.textContent = vizLog.warnings.length;
|
| 6402 |
+
}
|
| 6403 |
+
|
| 6404 |
+
function showDiagnosticDetails(filter) {
|
| 6405 |
+
const container = document.getElementById('viz-details');
|
| 6406 |
+
if (!container) return;
|
| 6407 |
+
|
| 6408 |
+
let items = [];
|
| 6409 |
+
if (filter === 'success') items = vizLog.success;
|
| 6410 |
+
else if (filter === 'failed') items = vizLog.failed;
|
| 6411 |
+
else items = [...vizLog.success, ...vizLog.failed, ...vizLog.warnings];
|
| 6412 |
+
|
| 6413 |
+
if (items.length === 0) {
|
| 6414 |
+
container.innerHTML = '<p style="color: var(--color-text-secondary); text-align: center; padding: 20px;">No items to display</p>';
|
| 6415 |
+
return;
|
| 6416 |
+
}
|
| 6417 |
+
|
| 6418 |
+
let html = '<table class="data-table" style="font-size: 12px;">';
|
| 6419 |
+
html += '<thead><tr><th>Module</th><th>Visualization</th><th>Status</th><th>Time</th></tr></thead>';
|
| 6420 |
+
html += '<tbody>';
|
| 6421 |
+
|
| 6422 |
+
items.forEach(item => {
|
| 6423 |
+
const statusIcon = item.status === 'success' ? 'β' : (item.status === 'failed' ? 'β' : 'β ');
|
| 6424 |
+
const statusColor = item.status === 'success' ? 'var(--color-success)' : (item.status === 'failed' ? 'var(--color-error)' : 'var(--color-warning)');
|
| 6425 |
+
|
| 6426 |
+
html += `<tr>`;
|
| 6427 |
+
html += `<td>${item.module}</td>`;
|
| 6428 |
+
html += `<td>${item.name}</td>`;
|
| 6429 |
+
html += `<td style="color: ${statusColor}; font-weight: bold;">${statusIcon} ${item.status.toUpperCase()}</td>`;
|
| 6430 |
+
html += `<td>${item.timestamp}</td>`;
|
| 6431 |
+
html += `</tr>`;
|
| 6432 |
+
});
|
| 6433 |
+
|
| 6434 |
+
html += '</tbody></table>';
|
| 6435 |
+
container.innerHTML = html;
|
| 6436 |
+
}
|
| 6437 |
+
|
| 6438 |
// Handle window resize
|
| 6439 |
let resizeTimer;
|
| 6440 |
window.addEventListener('resize', () => {
|
|
|
|
| 6482 |
if (document.getElementById('decision-flowchart')) drawDecisionFlowchart();
|
| 6483 |
}, 250);
|
| 6484 |
});
|
| 6485 |
+
|
| 6486 |
+
// Add global function for diagnostic details (needed by onclick)
|
| 6487 |
+
window.showDiagnosticDetails = showDiagnosticDetails;
|
ml_complete-all-topics/index.html
CHANGED
|
@@ -529,8 +529,14 @@ canvas {
|
|
| 529 |
<a href="#svm" class="toc-link toc-sub">Support Vector Machines</a>
|
| 530 |
<a href="#knn" class="toc-link toc-sub">K-Nearest Neighbors</a>
|
| 531 |
<a href="#naive-bayes" class="toc-link toc-sub">Naive Bayes</a>
|
| 532 |
-
<a href="#decision-
|
| 533 |
-
<a href="#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
</div>
|
| 535 |
<div class="toc-subcategory">
|
| 536 |
<div class="toc-subcategory-title">Evaluation & Tuning</div>
|
|
@@ -577,6 +583,7 @@ canvas {
|
|
| 577 |
</div>
|
| 578 |
|
| 579 |
<a href="#algorithm-comparison" class="toc-link">π Algorithm Comparison</a>
|
|
|
|
| 580 |
</nav>
|
| 581 |
</aside>
|
| 582 |
|
|
@@ -3242,6 +3249,192 @@ Actual Pos TP FN
|
|
| 3242 |
</div>
|
| 3243 |
</div>
|
| 3244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3245 |
<!-- Section 17: Decision Trees -->
|
| 3246 |
<div class="section" id="decision-trees">
|
| 3247 |
<div class="section-header">
|
|
@@ -3893,7 +4086,506 @@ Actual Pos TP FN
|
|
| 3893 |
</div>
|
| 3894 |
</div>
|
| 3895 |
|
| 3896 |
-
<!-- Section
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3897 |
<div class="section" id="ensemble-methods">
|
| 3898 |
<div class="section-header">
|
| 3899 |
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised</span> Ensemble Methods</h2>
|
|
@@ -3930,9 +4622,99 @@ Actual Pos TP FN
|
|
| 3930 |
</div>
|
| 3931 |
</div>
|
| 3932 |
|
| 3933 |
-
<h3>Method 1: Bagging (Bootstrap Aggregating)</h3>
|
| 3934 |
<p>Train multiple models on different random subsets of data (with replacement), then average predictions.</p>
|
| 3935 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3936 |
<div class="formula">
|
| 3937 |
<strong>Bagging Algorithm:</strong><br>
|
| 3938 |
1. Create B bootstrap samples (random sampling with replacement)<br>
|
|
@@ -3951,9 +4733,102 @@ Actual Pos TP FN
|
|
| 3951 |
<p class="figure-caption"><strong>Figure 1:</strong> Bagging process - multiple models from bootstrap samples</p>
|
| 3952 |
</div>
|
| 3953 |
|
| 3954 |
-
<h3>Method 2: Boosting (Sequential Learning)</h3>
|
| 3955 |
<p>Train models sequentially, where each new model focuses on examples the previous models got wrong.</p>
|
| 3956 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3957 |
<div class="formula">
|
| 3958 |
<strong>Boosting Algorithm:</strong><br>
|
| 3959 |
1. Start with equal weights for all samples<br>
|
|
@@ -3973,9 +4848,149 @@ Actual Pos TP FN
|
|
| 3973 |
<p class="figure-caption"><strong>Figure 2:</strong> Boosting iteration - focusing on misclassified points</p>
|
| 3974 |
</div>
|
| 3975 |
|
| 3976 |
-
<h3>Random Forest:
|
| 3977 |
<p>The most popular ensemble method! Combines bagging with feature randomness.</p>
|
| 3978 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3979 |
<div class="formula">
|
| 3980 |
<strong>Random Forest Algorithm:</strong><br>
|
| 3981 |
1. Create B bootstrap samples<br>
|
|
@@ -4054,6 +5069,72 @@ Actual Pos TP FN
|
|
| 4054 |
</div>
|
| 4055 |
</div>
|
| 4056 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4057 |
</main>
|
| 4058 |
</div>
|
| 4059 |
|
|
|
|
| 529 |
<a href="#svm" class="toc-link toc-sub">Support Vector Machines</a>
|
| 530 |
<a href="#knn" class="toc-link toc-sub">K-Nearest Neighbors</a>
|
| 531 |
<a href="#naive-bayes" class="toc-link toc-sub">Naive Bayes</a>
|
| 532 |
+
<a href="#decision-tree-regression" class="toc-link toc-sub">Decision Tree Regression</a>
|
| 533 |
+
<a href="#decision-trees" class="toc-link toc-sub">Decision Trees (Classification)</a>
|
| 534 |
+
<a href="#bagging" class="toc-link toc-sub">Bagging</a>
|
| 535 |
+
<a href="#boosting-adaboost" class="toc-link toc-sub">Boosting (AdaBoost)</a>
|
| 536 |
+
<a href="#gradient-boosting" class="toc-link toc-sub">Gradient Boosting</a>
|
| 537 |
+
<a href="#xgboost" class="toc-link toc-sub">XGBoost</a>
|
| 538 |
+
<a href="#random-forest" class="toc-link toc-sub">Random Forest</a>
|
| 539 |
+
<a href="#ensemble-methods" class="toc-link toc-sub">Ensemble Methods Overview</a>
|
| 540 |
</div>
|
| 541 |
<div class="toc-subcategory">
|
| 542 |
<div class="toc-subcategory-title">Evaluation & Tuning</div>
|
|
|
|
| 583 |
</div>
|
| 584 |
|
| 585 |
<a href="#algorithm-comparison" class="toc-link">π Algorithm Comparison</a>
|
| 586 |
+
<a href="#diagnostics" class="toc-link">π§ Diagnostics</a>
|
| 587 |
</nav>
|
| 588 |
</aside>
|
| 589 |
|
|
|
|
| 3249 |
</div>
|
| 3250 |
</div>
|
| 3251 |
|
| 3252 |
+
<!-- Section 17: Decision Tree Regression (FROM PDF) -->
|
| 3253 |
+
<div class="section" id="decision-tree-regression">
|
| 3254 |
+
<div class="section-header">
|
| 3255 |
+
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised - Regression</span> Decision Tree Regression</h2>
|
| 3256 |
+
<button class="section-toggle">βΌ</button>
|
| 3257 |
+
</div>
|
| 3258 |
+
<div class="section-body">
|
| 3259 |
+
<p>Decision Tree Regression predicts continuous values by recursively splitting data to minimize variance. Unlike classification trees that use entropy, regression trees use variance reduction!</p>
|
| 3260 |
+
|
| 3261 |
+
<div class="info-card">
|
| 3262 |
+
<div class="info-card-title">Key Concepts</div>
|
| 3263 |
+
<ul class="info-card-list">
|
| 3264 |
+
<li>Splits based on variance reduction (not entropy)</li>
|
| 3265 |
+
<li>Leaf nodes predict mean of samples</li>
|
| 3266 |
+
<li>Test all split points to find best</li>
|
| 3267 |
+
<li>Recursive partitioning until stopping criteria</li>
|
| 3268 |
+
</ul>
|
| 3269 |
+
</div>
|
| 3270 |
+
|
| 3271 |
+
<h3>π― Complete Mathematical Solution (From PDF)</h3>
|
| 3272 |
+
|
| 3273 |
+
<h4>Dataset: House Price Prediction</h4>
|
| 3274 |
+
<table class="data-table">
|
| 3275 |
+
<thead>
|
| 3276 |
+
<tr><th>ID</th><th>Square Feet</th><th>Price (Lakhs)</th></tr>
|
| 3277 |
+
</thead>
|
| 3278 |
+
<tbody>
|
| 3279 |
+
<tr><td>1</td><td>800</td><td>50</td></tr>
|
| 3280 |
+
<tr><td>2</td><td>850</td><td>52</td></tr>
|
| 3281 |
+
<tr><td>3</td><td>900</td><td>54</td></tr>
|
| 3282 |
+
<tr><td>4</td><td>1500</td><td>90</td></tr>
|
| 3283 |
+
<tr><td>5</td><td>1600</td><td>95</td></tr>
|
| 3284 |
+
<tr><td>6</td><td>1700</td><td>100</td></tr>
|
| 3285 |
+
</tbody>
|
| 3286 |
+
</table>
|
| 3287 |
+
|
| 3288 |
+
<div class="step">
|
| 3289 |
+
<div class="step-title">STEP 1: Calculate Parent Variance</div>
|
| 3290 |
+
<div class="step-calculation">
|
| 3291 |
+
Mean price = (50 + 52 + 54 + 90 + 95 + 100) / 6
|
| 3292 |
+
= 441 / 6
|
| 3293 |
+
= <strong style="color: #7ef0d4;">73.5 Lakhs</strong>
|
| 3294 |
+
|
| 3295 |
+
Variance = Ξ£(yα΅’ - mean)Β² / n
|
| 3296 |
+
|
| 3297 |
+
Calculating each term:
|
| 3298 |
+
β’ (50 - 73.5)Β² = (-23.5)Β² = 552.25
|
| 3299 |
+
β’ (52 - 73.5)Β² = (-21.5)Β² = 462.25
|
| 3300 |
+
β’ (54 - 73.5)Β² = (-19.5)Β² = 380.25
|
| 3301 |
+
β’ (90 - 73.5)Β² = (16.5)Β² = 272.25
|
| 3302 |
+
β’ (95 - 73.5)Β² = (21.5)Β² = 462.25
|
| 3303 |
+
β’ (100 - 73.5)Β² = (26.5)Β² = 702.25
|
| 3304 |
+
|
| 3305 |
+
Sum = 552.25 + 462.25 + 380.25 + 272.25 + 462.25 + 702.25
|
| 3306 |
+
= 2831.5
|
| 3307 |
+
|
| 3308 |
+
Variance = 2831.5 / 6 = <strong style="color: #7ef0d4;">471.92</strong>
|
| 3309 |
+
|
| 3310 |
+
<strong style="color: #6aa9ff;">β Parent Variance = 471.92</strong>
|
| 3311 |
+
</div>
|
| 3312 |
+
</div>
|
| 3313 |
+
|
| 3314 |
+
<div class="step">
|
| 3315 |
+
<div class="step-title">STEP 2: Test Split Points</div>
|
| 3316 |
+
<div class="step-calculation">
|
| 3317 |
+
Sort by Square Feet: 800, 850, 900, 1500, 1600, 1700
|
| 3318 |
+
|
| 3319 |
+
Possible midpoints: 825, 875, 1200, 1550, 1650
|
| 3320 |
+
|
| 3321 |
+
<strong style="color: #6aa9ff;">Testing Split at 1200:</strong>
|
| 3322 |
+
|
| 3323 |
+
<strong>LEFT (Square Feet <= 1200):</strong>
|
| 3324 |
+
Samples: 800(50), 850(52), 900(54)
|
| 3325 |
+
Left Mean = (50 + 52 + 54) / 3 = 156 / 3 = <strong>52</strong>
|
| 3326 |
+
|
| 3327 |
+
Left Variance:
|
| 3328 |
+
β’ (50 - 52)Β² = 4
|
| 3329 |
+
β’ (52 - 52)Β² = 0
|
| 3330 |
+
β’ (54 - 52)Β² = 4
|
| 3331 |
+
Sum = 8
|
| 3332 |
+
Variance = 8 / 3 = <strong>2.67</strong>
|
| 3333 |
+
|
| 3334 |
+
<strong>RIGHT (Square Feet > 1200):</strong>
|
| 3335 |
+
Samples: 1500(90), 1600(95), 1700(100)
|
| 3336 |
+
Right Mean = (90 + 95 + 100) / 3 = 285 / 3 = <strong>95</strong>
|
| 3337 |
+
|
| 3338 |
+
Right Variance:
|
| 3339 |
+
β’ (90 - 95)Β² = 25
|
| 3340 |
+
β’ (95 - 95)Β² = 0
|
| 3341 |
+
β’ (100 - 95)Β² = 25
|
| 3342 |
+
Sum = 50
|
| 3343 |
+
Variance = 50 / 3 = <strong>16.67</strong>
|
| 3344 |
+
</div>
|
| 3345 |
+
</div>
|
| 3346 |
+
|
| 3347 |
+
<div class="step">
|
| 3348 |
+
<div class="step-title">STEP 3: Calculate Weighted Variance After Split</div>
|
| 3349 |
+
<div class="step-calculation">
|
| 3350 |
+
Weighted Variance = (n_left/n_total) Γ Var_left + (n_right/n_total) Γ Var_right
|
| 3351 |
+
|
| 3352 |
+
= (3/6) Γ 2.67 + (3/6) Γ 16.67
|
| 3353 |
+
= 0.5 Γ 2.67 + 0.5 Γ 16.67
|
| 3354 |
+
= 1.335 + 8.335
|
| 3355 |
+
= <strong style="color: #6aa9ff;">9.67</strong>
|
| 3356 |
+
</div>
|
| 3357 |
+
</div>
|
| 3358 |
+
|
| 3359 |
+
<div class="step">
|
| 3360 |
+
<div class="step-title">STEP 4: Calculate Variance Reduction</div>
|
| 3361 |
+
<div class="step-calculation">
|
| 3362 |
+
Variance Reduction = Parent Variance - Weighted Variance After Split
|
| 3363 |
+
|
| 3364 |
+
= 471.92 - 9.67
|
| 3365 |
+
= <strong style="color: #7ef0d4; font-size: 18px;">462.25</strong>
|
| 3366 |
+
|
| 3367 |
+
<strong style="color: #7ef0d4;">β This is the BEST SPLIT!</strong>
|
| 3368 |
+
Splitting at 1200 sq ft reduces variance by 462.25
|
| 3369 |
+
</div>
|
| 3370 |
+
</div>
|
| 3371 |
+
|
| 3372 |
+
<div class="step">
|
| 3373 |
+
<div class="step-title">STEP 5: Build Final Tree Structure</div>
|
| 3374 |
+
<div class="step-calculation">
|
| 3375 |
+
Final Decision Tree:
|
| 3376 |
+
|
| 3377 |
+
[All data, Mean=73.5, Var=471.92]
|
| 3378 |
+
β
|
| 3379 |
+
Split at Square Feet = 1200
|
| 3380 |
+
/ \
|
| 3381 |
+
<= 1200 > 1200
|
| 3382 |
+
/ \
|
| 3383 |
+
Mean = 52 Split at 1550
|
| 3384 |
+
(3 samples) / \
|
| 3385 |
+
<= 1550 > 1550
|
| 3386 |
+
/ \
|
| 3387 |
+
Mean = 90 Mean = 97.5
|
| 3388 |
+
(1 sample) (2 samples)
|
| 3389 |
+
|
| 3390 |
+
<strong style="color: #7ef0d4;">Prediction Example:</strong>
|
| 3391 |
+
New property: 950 sq ft
|
| 3392 |
+
ββ 950 <= 1200? YES β Go LEFT
|
| 3393 |
+
ββ Prediction: <strong style="color: #7ef0d4; font-size: 18px;">βΉ52 Lakhs</strong>
|
| 3394 |
+
|
| 3395 |
+
New property: 1650 sq ft
|
| 3396 |
+
ββ 1650 <= 1200? NO β Go RIGHT
|
| 3397 |
+
ββ 1650 <= 1550? NO β Go RIGHT
|
| 3398 |
+
ββ Prediction: <strong style="color: #7ef0d4; font-size: 18px;">βΉ97.5 Lakhs</strong>
|
| 3399 |
+
</div>
|
| 3400 |
+
</div>
|
| 3401 |
+
|
| 3402 |
+
<div class="figure">
|
| 3403 |
+
<div class="figure-placeholder" style="height: 450px">
|
| 3404 |
+
<canvas id="dt-regression-canvas"></canvas>
|
| 3405 |
+
</div>
|
| 3406 |
+
<p class="figure-caption"><strong>Figure:</strong> Decision tree regression with splits and predictions</p>
|
| 3407 |
+
</div>
|
| 3408 |
+
|
| 3409 |
+
<div class="callout success">
|
| 3410 |
+
<div class="callout-title">β
Key Takeaway</div>
|
| 3411 |
+
<div class="callout-content">
|
| 3412 |
+
Decision Tree Regression finds splits that minimize variance in leaf nodes. Each leaf predicts the mean of samples in that region. The recursive splitting creates a piecewise constant function!
|
| 3413 |
+
</div>
|
| 3414 |
+
</div>
|
| 3415 |
+
|
| 3416 |
+
<h3>Variance Reduction vs Information Gain</h3>
|
| 3417 |
+
<table class="data-table">
|
| 3418 |
+
<thead>
|
| 3419 |
+
<tr><th>Aspect</th><th>Classification Trees</th><th>Regression Trees</th></tr>
|
| 3420 |
+
</thead>
|
| 3421 |
+
<tbody>
|
| 3422 |
+
<tr><td>Splitting Criterion</td><td>Information Gain (Entropy/Gini)</td><td>Variance Reduction</td></tr>
|
| 3423 |
+
<tr><td>Prediction</td><td>Majority class</td><td>Mean value</td></tr>
|
| 3424 |
+
<tr><td>Leaf Node</td><td>Class label</td><td>Continuous value</td></tr>
|
| 3425 |
+
<tr><td>Goal</td><td>Maximize purity</td><td>Minimize variance</td></tr>
|
| 3426 |
+
</tbody>
|
| 3427 |
+
</table>
|
| 3428 |
+
|
| 3429 |
+
<div class="figure">
|
| 3430 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 3431 |
+
<canvas id="dt-splits-canvas"></canvas>
|
| 3432 |
+
</div>
|
| 3433 |
+
<p class="figure-caption"><strong>Figure:</strong> Comparing different split points and their variance reduction</p>
|
| 3434 |
+
</div>
|
| 3435 |
+
</div>
|
| 3436 |
+
</div>
|
| 3437 |
+
|
| 3438 |
<!-- Section 17: Decision Trees -->
|
| 3439 |
<div class="section" id="decision-trees">
|
| 3440 |
<div class="section-header">
|
|
|
|
| 4086 |
</div>
|
| 4087 |
</div>
|
| 4088 |
|
| 4089 |
+
<!-- Section 19a: Gradient Boosting (NEW FROM PDF) -->
|
| 4090 |
+
<div class="section" id="gradient-boosting">
|
| 4091 |
+
<div class="section-header">
|
| 4092 |
+
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised - Ensemble</span> Gradient Boosting</h2>
|
| 4093 |
+
<button class="section-toggle collapsed">βΌ</button>
|
| 4094 |
+
</div>
|
| 4095 |
+
<div class="section-body">
|
| 4096 |
+
<p>Gradient Boosting is a powerful ensemble technique that builds models sequentially, where each new model corrects the errors (residuals) of the previous models. Unlike AdaBoost which adjusts sample weights, Gradient Boosting directly fits new models to the residual errors!</p>
|
| 4097 |
+
|
| 4098 |
+
<div class="info-card">
|
| 4099 |
+
<div class="info-card-title">Key Concepts</div>
|
| 4100 |
+
<ul class="info-card-list">
|
| 4101 |
+
<li>Sequential learning: Each tree fixes errors of previous</li>
|
| 4102 |
+
<li>Weak learners: Simple stumps (depth=1)</li>
|
| 4103 |
+
<li>Learning rate: Controls step size (0.1 = small steps)</li>
|
| 4104 |
+
<li>Residuals: What model got wrong</li>
|
| 4105 |
+
<li>SSE: Sum of Squared Errors (lower = better split)</li>
|
| 4106 |
+
</ul>
|
| 4107 |
+
</div>
|
| 4108 |
+
|
| 4109 |
+
<h3>π― Complete Mathematical Solution (From PDF)</h3>
|
| 4110 |
+
|
| 4111 |
+
<h4>Dataset: House Price Prediction</h4>
|
| 4112 |
+
<table class="data-table">
|
| 4113 |
+
<thead>
|
| 4114 |
+
<tr><th>ID</th><th>Size (sq ft)</th><th>Bedrooms</th><th>Price (βΉ Lakhs)</th></tr>
|
| 4115 |
+
</thead>
|
| 4116 |
+
<tbody>
|
| 4117 |
+
<tr><td>1</td><td>800</td><td>2</td><td>120</td></tr>
|
| 4118 |
+
<tr><td>2</td><td>900</td><td>2</td><td>130</td></tr>
|
| 4119 |
+
<tr><td>3</td><td>1000</td><td>3</td><td>150</td></tr>
|
| 4120 |
+
<tr><td>4</td><td>1100</td><td>3</td><td>170</td></tr>
|
| 4121 |
+
<tr><td>5</td><td>1200</td><td>4</td><td>200</td></tr>
|
| 4122 |
+
</tbody>
|
| 4123 |
+
</table>
|
| 4124 |
+
|
| 4125 |
+
<p><strong>Learning Rate:</strong> lr = 0.1</p>
|
| 4126 |
+
|
| 4127 |
+
<div class="step">
|
| 4128 |
+
<div class="step-title">STEP 0: Initialize Model F(0)</div>
|
| 4129 |
+
<div class="step-calculation">
|
| 4130 |
+
Formula: F(0) = mean(y)
|
| 4131 |
+
|
| 4132 |
+
Calculation:
|
| 4133 |
+
F(0) = (120 + 130 + 150 + 170 + 200) / 5
|
| 4134 |
+
= 770 / 5
|
| 4135 |
+
= <strong style="color: #7ef0d4;">154</strong>
|
| 4136 |
+
|
| 4137 |
+
<strong style="color: #7ef0d4;">β Result: F(0) = 154</strong>
|
| 4138 |
+
</div>
|
| 4139 |
+
</div>
|
| 4140 |
+
|
| 4141 |
+
<div class="step">
|
| 4142 |
+
<div class="step-title">STEP 1: Compute Residuals</div>
|
| 4143 |
+
<div class="step-calculation">
|
| 4144 |
+
Formula: r_i = y_i - F(0)
|
| 4145 |
+
|
| 4146 |
+
<strong style="color: #6aa9ff;">Residual Calculation:</strong>
|
| 4147 |
+
|
| 4148 |
+
ID | Size | Beds | Price(y) | Prediction F(0) | Residual r_i
|
| 4149 |
+
---|------|------|----------|-----------------|-------------
|
| 4150 |
+
1 | 800 | 2 | 120 | 154 | -34
|
| 4151 |
+
2 | 900 | 2 | 130 | 154 | -24
|
| 4152 |
+
3 | 1000 | 3 | 150 | 154 | -4
|
| 4153 |
+
4 | 1100 | 3 | 170 | 154 | +16
|
| 4154 |
+
5 | 1200 | 4 | 200 | 154 | +46
|
| 4155 |
+
|
| 4156 |
+
<strong style="color: #7ef0d4;">β Residuals: [-34, -24, -4, +16, +46]</strong>
|
| 4157 |
+
</div>
|
| 4158 |
+
</div>
|
| 4159 |
+
|
| 4160 |
+
<div class="step">
|
| 4161 |
+
<div class="step-title">STEP 2: Find Best Split (Build Weak Learner h1)</div>
|
| 4162 |
+
<div class="step-calculation">
|
| 4163 |
+
Test all candidate splits for Size feature:
|
| 4164 |
+
Midpoints: 850, 950, 1050, 1150
|
| 4165 |
+
|
| 4166 |
+
<strong style="color: #6aa9ff;">Test: Size < 1050</strong>
|
| 4167 |
+
|
| 4168 |
+
ββ Left (Size β€ 1050): IDs 1,2,3
|
| 4169 |
+
β Residuals: [-34, -24, -4]
|
| 4170 |
+
β Mean: (-34 + -24 + -4) / 3 = -62 / 3 = <strong>-20.66</strong>
|
| 4171 |
+
β SSE: (-34-(-20.66))Β² + (-24-(-20.66))Β² + (-4-(-20.66))Β²
|
| 4172 |
+
β = 177.78 + 11.11 + 277.78 = <strong>466.67</strong>
|
| 4173 |
+
β
|
| 4174 |
+
ββ Right (Size > 1050): IDs 4,5
|
| 4175 |
+
Residuals: [+16, +46]
|
| 4176 |
+
Mean: (16 + 46) / 2 = 62 / 2 = <strong>31.0</strong>
|
| 4177 |
+
SSE: (16-31)Β² + (46-31)Β² = 225 + 225 = <strong>450</strong>
|
| 4178 |
+
|
| 4179 |
+
<strong style="color: #ff8c6a;">Total SSE = 466.67 + 450 = 916.67</strong>
|
| 4180 |
+
|
| 4181 |
+
<strong style="color: #6aa9ff;">Test All Splits:</strong>
|
| 4182 |
+
Feature | Threshold | SSE
|
| 4183 |
+
---------|-----------|--------
|
| 4184 |
+
Size | 850 | 2675
|
| 4185 |
+
Size | 950 | 1316.66
|
| 4186 |
+
Size | 1050 | 916.67 β BEST SPLIT
|
| 4187 |
+
Size | 1150 | 1475.0
|
| 4188 |
+
Bedrooms | 2.5 | 1316.66
|
| 4189 |
+
Bedrooms | 3.5 | 1475.0
|
| 4190 |
+
|
| 4191 |
+
<strong style="color: #7ef0d4; font-size: 18px;">β BEST SPLIT: Size < 1050 with SSE = 916.67</strong>
|
| 4192 |
+
|
| 4193 |
+
Weak Learner h1(x):
|
| 4194 |
+
ββ If Size β€ 1050: h1(x) = -20.66
|
| 4195 |
+
ββ If Size > 1050: h1(x) = 31.0
|
| 4196 |
+
</div>
|
| 4197 |
+
</div>
|
| 4198 |
+
|
| 4199 |
+
<div class="step">
|
| 4200 |
+
<div class="step-title">STEP 3: Update Predictions</div>
|
| 4201 |
+
<div class="step-calculation">
|
| 4202 |
+
Formula: F1(x) = F(0) + lr Γ h1(x)
|
| 4203 |
+
where lr = 0.1
|
| 4204 |
+
|
| 4205 |
+
<strong style="color: #6aa9ff;">For ID 1 (Size=800):</strong>
|
| 4206 |
+
F1(1) = 154 + 0.1 Γ (-20.66)
|
| 4207 |
+
= 154 - 2.066
|
| 4208 |
+
= <strong style="color: #7ef0d4;">151.93</strong> β
|
| 4209 |
+
|
| 4210 |
+
<strong style="color: #6aa9ff;">For ID 4 (Size=1100):</strong>
|
| 4211 |
+
F1(4) = 154 + 0.1 Γ 31.0
|
| 4212 |
+
= 154 + 3.10
|
| 4213 |
+
= <strong style="color: #7ef0d4;">157.10</strong> β
|
| 4214 |
+
|
| 4215 |
+
<strong style="color: #6aa9ff;">Complete Table:</strong>
|
| 4216 |
+
ID | Size | Price(y) | F(0) | h1(x) | F1(x) | New Residual
|
| 4217 |
+
---|------|----------|------|--------|--------|-------------
|
| 4218 |
+
1 | 800 | 120 | 154 | -20.66 | 151.93 | -31.93
|
| 4219 |
+
2 | 900 | 130 | 154 | -20.66 | 151.93 | -21.93
|
| 4220 |
+
3 | 1000 | 150 | 154 | -20.66 | 151.93 | -1.93
|
| 4221 |
+
4 | 1100 | 170 | 154 | +31.0 | 157.10 | +12.90
|
| 4222 |
+
5 | 1200 | 200 | 154 | +31.0 | 157.10 | +42.90
|
| 4223 |
+
</div>
|
| 4224 |
+
</div>
|
| 4225 |
+
|
| 4226 |
+
<div class="step">
|
| 4227 |
+
<div class="step-title">STEP 4: Repeat for h2, h3, ... h10</div>
|
| 4228 |
+
<div class="step-calculation">
|
| 4229 |
+
Continue building weak learners on residuals:
|
| 4230 |
+
|
| 4231 |
+
F(x) = F(0) + lrΓh1(x) + lrΓh2(x) + lrΓh3(x) + ... + lrΓh10(x)
|
| 4232 |
+
|
| 4233 |
+
Each iteration:
|
| 4234 |
+
1. Compute residuals
|
| 4235 |
+
2. Find best split
|
| 4236 |
+
3. Build weak learner
|
| 4237 |
+
4. Update predictions
|
| 4238 |
+
|
| 4239 |
+
After 10 iterations:
|
| 4240 |
+
<strong style="color: #7ef0d4; font-size: 18px;">Final Model: F(x) = 154 + 0.1Γh1(x) + 0.1Γh2(x) + ... + 0.1Γh10(x)</strong>
|
| 4241 |
+
</div>
|
| 4242 |
+
</div>
|
| 4243 |
+
|
| 4244 |
+
<h3>π Visualizations</h3>
|
| 4245 |
+
|
| 4246 |
+
<div class="figure">
|
| 4247 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4248 |
+
<canvas id="gb-sequential-canvas"></canvas>
|
| 4249 |
+
</div>
|
| 4250 |
+
<p class="figure-caption"><strong>Figure 1:</strong> Sequential tree building - residuals decreasing over iterations</p>
|
| 4251 |
+
</div>
|
| 4252 |
+
|
| 4253 |
+
<div class="figure">
|
| 4254 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4255 |
+
<canvas id="gb-residuals-canvas"></canvas>
|
| 4256 |
+
</div>
|
| 4257 |
+
<p class="figure-caption"><strong>Figure 2:</strong> Residual reduction across iterations</p>
|
| 4258 |
+
</div>
|
| 4259 |
+
|
| 4260 |
+
<div class="figure">
|
| 4261 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4262 |
+
<canvas id="gb-learning-rate-canvas"></canvas>
|
| 4263 |
+
</div>
|
| 4264 |
+
<p class="figure-caption"><strong>Figure 3:</strong> Learning rate effect - comparing lr=0.01, 0.1, 1.0</p>
|
| 4265 |
+
</div>
|
| 4266 |
+
|
| 4267 |
+
<div class="figure">
|
| 4268 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4269 |
+
<canvas id="gb-stumps-canvas"></canvas>
|
| 4270 |
+
</div>
|
| 4271 |
+
<p class="figure-caption"><strong>Figure 4:</strong> Weak learner stumps with decision boundaries</p>
|
| 4272 |
+
</div>
|
| 4273 |
+
|
| 4274 |
+
<div class="figure">
|
| 4275 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4276 |
+
<canvas id="gb-predictions-canvas"></canvas>
|
| 4277 |
+
</div>
|
| 4278 |
+
<p class="figure-caption"><strong>Figure 5:</strong> Prediction vs actual - showing improvement</p>
|
| 4279 |
+
</div>
|
| 4280 |
+
|
| 4281 |
+
<div class="callout success">
|
| 4282 |
+
<div class="callout-title">β
Key Takeaways</div>
|
| 4283 |
+
<div class="callout-content">
|
| 4284 |
+
<strong>Why Gradient Boosting Works:</strong><br>
|
| 4285 |
+
β’ Each tree learns from previous mistakes (residuals)<br>
|
| 4286 |
+
β’ Learning rate prevents overfitting<br>
|
| 4287 |
+
β’ Simple weak learners combine into strong predictor<br>
|
| 4288 |
+
β’ SSE-based splits find best variance reduction<br>
|
| 4289 |
+
<br>
|
| 4290 |
+
<strong>Advantages:</strong><br>
|
| 4291 |
+
β Very high accuracy<br>
|
| 4292 |
+
β Handles non-linear relationships<br>
|
| 4293 |
+
β Feature importance built-in<br>
|
| 4294 |
+
<br>
|
| 4295 |
+
<strong>Disadvantages:</strong><br>
|
| 4296 |
+
β Sequential (can't parallelize)<br>
|
| 4297 |
+
β Sensitive to overfitting<br>
|
| 4298 |
+
β Requires careful tuning
|
| 4299 |
+
</div>
|
| 4300 |
+
</div>
|
| 4301 |
+
</div>
|
| 4302 |
+
</div>
|
| 4303 |
+
|
| 4304 |
+
<!-- Section 19b: XGBoost (NEW FROM PDF) -->
|
| 4305 |
+
<div class="section" id="xgboost">
|
| 4306 |
+
<div class="section-header">
|
| 4307 |
+
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised - Ensemble</span> XGBoost (Extreme Gradient Boosting)</h2>
|
| 4308 |
+
<button class="section-toggle collapsed">βΌ</button>
|
| 4309 |
+
</div>
|
| 4310 |
+
<div class="section-body">
|
| 4311 |
+
<p>XGBoost is an optimized implementation of gradient boosting that uses second-order derivatives (Hessian) and regularization for superior performance. It's the algorithm that wins most Kaggle competitions!</p>
|
| 4312 |
+
|
| 4313 |
+
<div class="info-card">
|
| 4314 |
+
<div class="info-card-title">Key Concepts</div>
|
| 4315 |
+
<ul class="info-card-list">
|
| 4316 |
+
<li>Uses 2nd order derivatives (Hessian) for better approximation</li>
|
| 4317 |
+
<li>Built-in regularization (Ξ») to prevent overfitting</li>
|
| 4318 |
+
<li>Better gain calculation for splits</li>
|
| 4319 |
+
<li>Handles parallelism and missing values</li>
|
| 4320 |
+
<li>Much faster than standard gradient boosting</li>
|
| 4321 |
+
</ul>
|
| 4322 |
+
</div>
|
| 4323 |
+
|
| 4324 |
+
<h3>π― XGBoost vs Gradient Boosting</h3>
|
| 4325 |
+
<table class="data-table">
|
| 4326 |
+
<thead>
|
| 4327 |
+
<tr><th>Aspect</th><th>Gradient Boosting</th><th>XGBoost</th></tr>
|
| 4328 |
+
</thead>
|
| 4329 |
+
<tbody>
|
| 4330 |
+
<tr><td>Derivatives</td><td>1st order (gradient)</td><td>1st + 2nd order (Hessian)</td></tr>
|
| 4331 |
+
<tr><td>Regularization</td><td>None built-in</td><td>L1 & L2 built-in (Ξ»)</td></tr>
|
| 4332 |
+
<tr><td>Split Criterion</td><td>MSE/MAE</td><td>Gain with regularization</td></tr>
|
| 4333 |
+
<tr><td>Parallelism</td><td>No</td><td>Yes (tree building)</td></tr>
|
| 4334 |
+
<tr><td>Missing Values</td><td>Must handle separately</td><td>Built-in handling</td></tr>
|
| 4335 |
+
<tr><td>Speed</td><td>Slower</td><td>Much faster</td></tr>
|
| 4336 |
+
</tbody>
|
| 4337 |
+
</table>
|
| 4338 |
+
|
| 4339 |
+
<h3>π― Complete Mathematical Solution (From PDF)</h3>
|
| 4340 |
+
|
| 4341 |
+
<p><strong>Using same dataset as Gradient Boosting:</strong></p>
|
| 4342 |
+
|
| 4343 |
+
<div class="formula">
|
| 4344 |
+
<strong>XGBoost Gain Formula:</strong>
|
| 4345 |
+
Gain = [GLΒ² / (HL + Ξ»)] + [GRΒ² / (HR + Ξ»)] - [G_parentΒ² / (H_parent + Ξ»)]
|
| 4346 |
+
<br><br>
|
| 4347 |
+
Where:<br>
|
| 4348 |
+
G = Gradient (1st derivative) = Ξ£(y - Ε·)<br>
|
| 4349 |
+
H = Hessian (2nd derivative) = Ξ£(1) for regression<br>
|
| 4350 |
+
Ξ» = Regularization parameter (default = 1)
|
| 4351 |
+
</div>
|
| 4352 |
+
|
| 4353 |
+
<div class="step">
|
| 4354 |
+
<div class="step-title">STEP 0: Initialize</div>
|
| 4355 |
+
<div class="step-calculation">
|
| 4356 |
+
F(0) = mean(y) = <strong style="color: #7ef0d4;">154</strong>
|
| 4357 |
+
</div>
|
| 4358 |
+
</div>
|
| 4359 |
+
|
| 4360 |
+
<div class="step">
|
| 4361 |
+
<div class="step-title">STEP 1: Compute Gradients and Hessians</div>
|
| 4362 |
+
<div class="step-calculation">
|
| 4363 |
+
<strong style="color: #6aa9ff;">For Regression (MSE loss):</strong>
|
| 4364 |
+
gradient g = (y - Ε·)
|
| 4365 |
+
hessian h = 1 (constant for MSE)
|
| 4366 |
+
|
| 4367 |
+
ID | Size | Price(y) | F(0) | g=(y-Ε·) | h
|
| 4368 |
+
---|------|----------|------|---------|---
|
| 4369 |
+
1 | 800 | 120 | 154 | -34 | 1
|
| 4370 |
+
2 | 900 | 130 | 154 | -24 | 1
|
| 4371 |
+
3 | 1000 | 150 | 154 | -4 | 1
|
| 4372 |
+
4 | 1100 | 170 | 154 | +16 | 1
|
| 4373 |
+
5 | 1200 | 200 | 154 | +46 | 1
|
| 4374 |
+
</div>
|
| 4375 |
+
</div>
|
| 4376 |
+
|
| 4377 |
+
<div class="step">
|
| 4378 |
+
<div class="step-title">STEP 2: Test Split - Size < 950</div>
|
| 4379 |
+
<div class="step-calculation">
|
| 4380 |
+
<strong style="color: #6aa9ff;">Split: Size < 950</strong>
|
| 4381 |
+
|
| 4382 |
+
ββ Left: IDs 1,2 (800, 900)
|
| 4383 |
+
β GL = -34 + (-24) = <strong>-58</strong>
|
| 4384 |
+
β HL = 1 + 1 = <strong>2</strong>
|
| 4385 |
+
β
|
| 4386 |
+
ββ Right: IDs 3,4,5 (1000, 1100, 1200)
|
| 4387 |
+
GR = -4 + 16 + 46 = <strong>+58</strong>
|
| 4388 |
+
HR = 1 + 1 + 1 = <strong>3</strong>
|
| 4389 |
+
|
| 4390 |
+
Parent:
|
| 4391 |
+
G_parent = -34 + (-24) + (-4) + 16 + 46 = <strong>0</strong>
|
| 4392 |
+
H_parent = <strong>5</strong>
|
| 4393 |
+
|
| 4394 |
+
<strong style="color: #6aa9ff;">Calculate Scores (Ξ» = 1):</strong>
|
| 4395 |
+
|
| 4396 |
+
Score(Left) = -GLΒ² / (HL + Ξ»)
|
| 4397 |
+
= -(-58)Β² / (2 + 1)
|
| 4398 |
+
= -3364 / 3
|
| 4399 |
+
= <strong>-1121.33</strong>
|
| 4400 |
+
|
| 4401 |
+
Score(Right) = -GRΒ² / (HR + Ξ»)
|
| 4402 |
+
= -(58)Β² / (3 + 1)
|
| 4403 |
+
= -3364 / 4
|
| 4404 |
+
= <strong>-841</strong>
|
| 4405 |
+
|
| 4406 |
+
Score(Parent) = -G_parentΒ² / (H_parent + Ξ»)
|
| 4407 |
+
= -(0)Β² / (5 + 1)
|
| 4408 |
+
= <strong>0</strong>
|
| 4409 |
+
|
| 4410 |
+
Gain = Score(Left) + Score(Right) - Score(Parent)
|
| 4411 |
+
= -1121.33 + (-841) - 0
|
| 4412 |
+
= -1962.33
|
| 4413 |
+
|
| 4414 |
+
Use absolute value: Gain = <strong style="color: #7ef0d4; font-size: 18px;">1962.33</strong> β HIGHEST GAIN
|
| 4415 |
+
</div>
|
| 4416 |
+
</div>
|
| 4417 |
+
|
| 4418 |
+
<div class="step">
|
| 4419 |
+
<div class="step-title">STEP 3: Compute Leaf Weights</div>
|
| 4420 |
+
<div class="step-calculation">
|
| 4421 |
+
Formula: w = -G / (H + Ξ»)
|
| 4422 |
+
|
| 4423 |
+
<strong style="color: #6aa9ff;">Left Leaf:</strong>
|
| 4424 |
+
w_left = -(-58) / (2 + 1)
|
| 4425 |
+
= 58 / 3
|
| 4426 |
+
= <strong style="color: #7ef0d4;">19.33</strong>
|
| 4427 |
+
|
| 4428 |
+
<strong style="color: #6aa9ff;">Right Leaf:</strong>
|
| 4429 |
+
w_right = -(58) / (3 + 1)
|
| 4430 |
+
= -58 / 4
|
| 4431 |
+
= <strong style="color: #7ef0d4;">-14.5</strong>
|
| 4432 |
+
</div>
|
| 4433 |
+
</div>
|
| 4434 |
+
|
| 4435 |
+
<div class="step">
|
| 4436 |
+
<div class="step-title">STEP 4: Update Predictions</div>
|
| 4437 |
+
<div class="step-calculation">
|
| 4438 |
+
Formula: F1(x) = F(0) + lr Γ w
|
| 4439 |
+
|
| 4440 |
+
<strong style="color: #6aa9ff;">Complete Table:</strong>
|
| 4441 |
+
ID | Size | Price(y) | F(0) | Leaf Weight | F1(x) | New Residual
|
| 4442 |
+
---|------|----------|------|-------------|-----------|-------------
|
| 4443 |
+
1 | 800 | 120 | 154 | -19.33 | 134.67 | -14.67
|
| 4444 |
+
2 | 900 | 130 | 154 | -19.33 | 134.67 | -4.67
|
| 4445 |
+
3 | 1000 | 150 | 154 | +14.5 | 168.50 | -18.50
|
| 4446 |
+
4 | 1100 | 170 | 154 | +14.5 | 168.50 | +1.50
|
| 4447 |
+
5 | 1200 | 200 | 154 | +14.5 | 168.50 | +31.50
|
| 4448 |
+
</div>
|
| 4449 |
+
</div>
|
| 4450 |
+
|
| 4451 |
+
<h3>π Visualizations</h3>
|
| 4452 |
+
|
| 4453 |
+
<div class="figure">
|
| 4454 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4455 |
+
<canvas id="xgb-gain-canvas"></canvas>
|
| 4456 |
+
</div>
|
| 4457 |
+
<p class="figure-caption"><strong>Figure 1:</strong> Gain calculation showing GL, GR, HL, HR for each split</p>
|
| 4458 |
+
</div>
|
| 4459 |
+
|
| 4460 |
+
<div class="figure">
|
| 4461 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4462 |
+
<canvas id="xgb-regularization-canvas"></canvas>
|
| 4463 |
+
</div>
|
| 4464 |
+
<p class="figure-caption"><strong>Figure 2:</strong> Regularization effect - comparing Ξ»=0, 1, 10</p>
|
| 4465 |
+
</div>
|
| 4466 |
+
|
| 4467 |
+
<div class="figure">
|
| 4468 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4469 |
+
<canvas id="xgb-hessian-canvas"></canvas>
|
| 4470 |
+
</div>
|
| 4471 |
+
<p class="figure-caption"><strong>Figure 3:</strong> Hessian contribution to better optimization</p>
|
| 4472 |
+
</div>
|
| 4473 |
+
|
| 4474 |
+
<div class="figure">
|
| 4475 |
+
<div class="figure-placeholder" style="height: 350px">
|
| 4476 |
+
<canvas id="xgb-leaf-weights-canvas"></canvas>
|
| 4477 |
+
</div>
|
| 4478 |
+
<p class="figure-caption"><strong>Figure 4:</strong> Leaf weight calculation breakdown</p>
|
| 4479 |
+
</div>
|
| 4480 |
+
|
| 4481 |
+
<div class="figure">
|
| 4482 |
+
<div class="figure-placeholder" style="height: 450px">
|
| 4483 |
+
<canvas id="xgb-comparison-canvas"></canvas>
|
| 4484 |
+
</div>
|
| 4485 |
+
<p class="figure-caption"><strong>Figure 5:</strong> Gradient Boosting vs XGBoost performance comparison</p>
|
| 4486 |
+
</div>
|
| 4487 |
+
|
| 4488 |
+
<div class="callout success">
|
| 4489 |
+
<div class="callout-title">β
Key Advantages of XGBoost</div>
|
| 4490 |
+
<div class="callout-content">
|
| 4491 |
+
<strong>Mathematical Improvements:</strong><br>
|
| 4492 |
+
β 2nd order derivatives β Better approximation<br>
|
| 4493 |
+
β Regularization (Ξ») β Prevents overfitting<br>
|
| 4494 |
+
β Gain-based splitting β More accurate<br>
|
| 4495 |
+
<br>
|
| 4496 |
+
<strong>Engineering Improvements:</strong><br>
|
| 4497 |
+
β Parallel processing β Faster training<br>
|
| 4498 |
+
β Handles missing values β More robust<br>
|
| 4499 |
+
β Built-in cross-validation β Easy tuning<br>
|
| 4500 |
+
β Tree pruning β Better generalization<br>
|
| 4501 |
+
β Cache optimization β Memory efficient<br>
|
| 4502 |
+
<br>
|
| 4503 |
+
<strong>Real-World Impact:</strong><br>
|
| 4504 |
+
β’ Most popular algorithm for structured data<br>
|
| 4505 |
+
β’ Dominates Kaggle competitions<br>
|
| 4506 |
+
β’ Used by: Uber, Airbnb, Microsoft, etc.
|
| 4507 |
+
</div>
|
| 4508 |
+
</div>
|
| 4509 |
+
|
| 4510 |
+
<h3>Hyperparameter Guide</h3>
|
| 4511 |
+
<table class="data-table">
|
| 4512 |
+
<thead>
|
| 4513 |
+
<tr><th>Parameter</th><th>Description</th><th>Typical Values</th></tr>
|
| 4514 |
+
</thead>
|
| 4515 |
+
<tbody>
|
| 4516 |
+
<tr><td>learning_rate (Ξ·)</td><td>Step size shrinkage</td><td>0.01 - 0.3</td></tr>
|
| 4517 |
+
<tr><td>n_estimators</td><td>Number of trees</td><td>100 - 1000</td></tr>
|
| 4518 |
+
<tr><td>max_depth</td><td>Tree depth</td><td>3 - 10</td></tr>
|
| 4519 |
+
<tr><td>lambda (Ξ»)</td><td>L2 regularization</td><td>0 - 10</td></tr>
|
| 4520 |
+
<tr><td>alpha (Ξ±)</td><td>L1 regularization</td><td>0 - 10</td></tr>
|
| 4521 |
+
<tr><td>subsample</td><td>Row sampling</td><td>0.5 - 1.0</td></tr>
|
| 4522 |
+
<tr><td>colsample_bytree</td><td>Column sampling</td><td>0.5 - 1.0</td></tr>
|
| 4523 |
+
</tbody>
|
| 4524 |
+
</table>
|
| 4525 |
+
</div>
|
| 4526 |
+
</div>
|
| 4527 |
+
|
| 4528 |
+
<!-- Section 19c: Bagging (Renamed) -->
|
| 4529 |
+
<div class="section" id="bagging">
|
| 4530 |
+
<div class="section-header">
|
| 4531 |
+
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised - Ensemble</span> Bagging (Bootstrap Aggregating)</h2>
|
| 4532 |
+
<button class="section-toggle collapsed">βΌ</button>
|
| 4533 |
+
</div>
|
| 4534 |
+
<div class="section-body">
|
| 4535 |
+
<p>Bagging trains multiple models on different random subsets of data (with replacement), then averages predictions. It's the foundation for Random Forest!</p>
|
| 4536 |
+
|
| 4537 |
+
<div class="figure">
|
| 4538 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4539 |
+
<canvas id="bagging-complete-canvas"></canvas>
|
| 4540 |
+
</div>
|
| 4541 |
+
<p class="figure-caption"><strong>Figure:</strong> Bagging process showing 3 trees and averaged prediction</p>
|
| 4542 |
+
</div>
|
| 4543 |
+
|
| 4544 |
+
<p>See the <a href="#ensemble-methods">Ensemble Methods Overview</a> section below for complete mathematical walkthrough.</p>
|
| 4545 |
+
</div>
|
| 4546 |
+
</div>
|
| 4547 |
+
|
| 4548 |
+
<!-- Section 19d: Boosting/AdaBoost (Renamed) -->
|
| 4549 |
+
<div class="section" id="boosting-adaboost">
|
| 4550 |
+
<div class="section-header">
|
| 4551 |
+
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised - Ensemble</span> Boosting (AdaBoost)</h2>
|
| 4552 |
+
<button class="section-toggle collapsed">βΌ</button>
|
| 4553 |
+
</div>
|
| 4554 |
+
<div class="section-body">
|
| 4555 |
+
<p>AdaBoost trains models sequentially, where each new model focuses on examples the previous models got wrong by adjusting sample weights.</p>
|
| 4556 |
+
|
| 4557 |
+
<div class="figure">
|
| 4558 |
+
<div class="figure-placeholder" style="height: 450px">
|
| 4559 |
+
<canvas id="boosting-complete-canvas"></canvas>
|
| 4560 |
+
</div>
|
| 4561 |
+
<p class="figure-caption"><strong>Figure:</strong> Boosting rounds showing weight updates and error reduction</p>
|
| 4562 |
+
</div>
|
| 4563 |
+
|
| 4564 |
+
<p>See the <a href="#ensemble-methods">Ensemble Methods Overview</a> section below for complete mathematical walkthrough.</p>
|
| 4565 |
+
</div>
|
| 4566 |
+
</div>
|
| 4567 |
+
|
| 4568 |
+
<!-- Section 19e: Random Forest (Renamed) -->
|
| 4569 |
+
<div class="section" id="random-forest">
|
| 4570 |
+
<div class="section-header">
|
| 4571 |
+
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised - Ensemble</span> Random Forest</h2>
|
| 4572 |
+
<button class="section-toggle collapsed">βΌ</button>
|
| 4573 |
+
</div>
|
| 4574 |
+
<div class="section-body">
|
| 4575 |
+
<p>Random Forest combines bagging with feature randomness. Each tree is trained on a bootstrap sample AND considers only random subsets of features at each split!</p>
|
| 4576 |
+
|
| 4577 |
+
<div class="figure">
|
| 4578 |
+
<div class="figure-placeholder" style="height: 500px">
|
| 4579 |
+
<canvas id="rf-complete-canvas"></canvas>
|
| 4580 |
+
</div>
|
| 4581 |
+
<p class="figure-caption"><strong>Figure:</strong> Random Forest showing feature randomness and OOB validation</p>
|
| 4582 |
+
</div>
|
| 4583 |
+
|
| 4584 |
+
<p>See the <a href="#ensemble-methods">Ensemble Methods Overview</a> section below for complete mathematical walkthrough.</p>
|
| 4585 |
+
</div>
|
| 4586 |
+
</div>
|
| 4587 |
+
|
| 4588 |
+
<!-- Section 19: Ensemble Methods (COMPREHENSIVE FROM PDF) -->
|
| 4589 |
<div class="section" id="ensemble-methods">
|
| 4590 |
<div class="section-header">
|
| 4591 |
<h2><span class="badge" style="background: rgba(106, 169, 255, 0.3); color: #6aa9ff;">π Supervised</span> Ensemble Methods</h2>
|
|
|
|
| 4622 |
</div>
|
| 4623 |
</div>
|
| 4624 |
|
| 4625 |
+
<h3>π― Method 1: Bagging (Bootstrap Aggregating) - Complete Walkthrough</h3>
|
| 4626 |
<p>Train multiple models on different random subsets of data (with replacement), then average predictions.</p>
|
| 4627 |
|
| 4628 |
+
<h4>Dataset: 6 Properties</h4>
|
| 4629 |
+
<table class="data-table">
|
| 4630 |
+
<thead>
|
| 4631 |
+
<tr><th>Row</th><th>Square Feet</th><th>Price (Lakhs)</th></tr>
|
| 4632 |
+
</thead>
|
| 4633 |
+
<tbody>
|
| 4634 |
+
<tr><td>A</td><td>900</td><td>70</td></tr>
|
| 4635 |
+
<tr><td>B</td><td>1000</td><td>80</td></tr>
|
| 4636 |
+
<tr><td>C</td><td>900</td><td>70</td></tr>
|
| 4637 |
+
<tr><td>D</td><td>1500</td><td>90</td></tr>
|
| 4638 |
+
<tr><td>E</td><td>1600</td><td>95</td></tr>
|
| 4639 |
+
<tr><td>F</td><td>1700</td><td>100</td></tr>
|
| 4640 |
+
</tbody>
|
| 4641 |
+
</table>
|
| 4642 |
+
|
| 4643 |
+
<div class="step">
|
| 4644 |
+
<div class="step-title">STEP 1: Create Bootstrap Samples (WITH Replacement)</div>
|
| 4645 |
+
<div class="step-calculation">
|
| 4646 |
+
<strong style="color: #6aa9ff;">Bootstrap Sample 1:</strong>
|
| 4647 |
+
Randomly pick 6 samples WITH replacement:
|
| 4648 |
+
ββ Row A: 900 sq ft, βΉ70L (sampled TWICE!)
|
| 4649 |
+
ββ Row A: 900 sq ft, βΉ70L (duplicate)
|
| 4650 |
+
ββ Row B: 1000 sq ft, βΉ80L
|
| 4651 |
+
ββ Row D: 1500 sq ft, βΉ90L
|
| 4652 |
+
ββ Row E: 1600 sq ft, βΉ95L
|
| 4653 |
+
ββ Row F: 1700 sq ft, βΉ100L
|
| 4654 |
+
|
| 4655 |
+
<strong style="color: #6aa9ff;">Bootstrap Sample 2:</strong>
|
| 4656 |
+
ββ Row C: 900 sq ft, βΉ70L
|
| 4657 |
+
ββ Row D: 1500 sq ft, βΉ90L
|
| 4658 |
+
ββ Row E: 1600 sq ft, βΉ95L
|
| 4659 |
+
ββ Row E: 1600 sq ft, βΉ95L (sampled TWICE!)
|
| 4660 |
+
ββ Row F: 1700 sq ft, βΉ100L
|
| 4661 |
+
ββ Row B: 1000 sq ft, βΉ80L
|
| 4662 |
+
|
| 4663 |
+
<strong style="color: #6aa9ff;">Bootstrap Sample 3:</strong>
|
| 4664 |
+
ββ Row F: 1700 sq ft, βΉ100L
|
| 4665 |
+
ββ Row C: 900 sq ft, βΉ70L
|
| 4666 |
+
ββ Row E: 1600 sq ft, βΉ95L
|
| 4667 |
+
ββ Row A: 900 sq ft, βΉ70L
|
| 4668 |
+
ββ Row B: 1000 sq ft, βΉ80L
|
| 4669 |
+
ββ Row D: 1500 sq ft, βΉ90L
|
| 4670 |
+
</div>
|
| 4671 |
+
</div>
|
| 4672 |
+
|
| 4673 |
+
<div class="step">
|
| 4674 |
+
<div class="step-title">STEP 2: Train Separate Model on Each Sample</div>
|
| 4675 |
+
<div class="step-calculation">
|
| 4676 |
+
<strong style="color: #7ef0d4;">Tree 1:</strong> Trained on Sample 1
|
| 4677 |
+
β’ Learns splits based on its data
|
| 4678 |
+
β’ For 950 sq ft β Predicts: <strong>βΉ75L</strong>
|
| 4679 |
+
|
| 4680 |
+
<strong style="color: #7ef0d4;">Tree 2:</strong> Trained on Sample 2
|
| 4681 |
+
β’ Different data β Different splits!
|
| 4682 |
+
β’ For 950 sq ft β Predicts: <strong>βΉ72L</strong>
|
| 4683 |
+
|
| 4684 |
+
<strong style="color: #7ef0d4;">Tree 3:</strong> Trained on Sample 3
|
| 4685 |
+
β’ Yet another perspective
|
| 4686 |
+
β’ For 950 sq ft β Predicts: <strong>βΉ78L</strong>
|
| 4687 |
+
</div>
|
| 4688 |
+
</div>
|
| 4689 |
+
|
| 4690 |
+
<div class="step">
|
| 4691 |
+
<div class="step-title">STEP 3: Aggregate Predictions (Average)</div>
|
| 4692 |
+
<div class="step-calculation">
|
| 4693 |
+
For test property with 950 sq ft:
|
| 4694 |
+
|
| 4695 |
+
Predictionβ = βΉ75L
|
| 4696 |
+
Predictionβ = βΉ72L
|
| 4697 |
+
Predictionβ = βΉ78L
|
| 4698 |
+
|
| 4699 |
+
<strong style="color: #6aa9ff;">Final Bagging Prediction:</strong>
|
| 4700 |
+
Average = (75 + 72 + 78) / 3
|
| 4701 |
+
= 225 / 3
|
| 4702 |
+
= <strong style="color: #7ef0d4; font-size: 18px;">βΉ75 Lakhs</strong> β
|
| 4703 |
+
|
| 4704 |
+
<strong style="color: #7ef0d4;">Why it works:</strong>
|
| 4705 |
+
β’ Each tree makes slightly different errors
|
| 4706 |
+
β’ Averaging reduces overall variance
|
| 4707 |
+
β’ More stable than single tree!
|
| 4708 |
+
</div>
|
| 4709 |
+
</div>
|
| 4710 |
+
|
| 4711 |
+
<div class="figure">
|
| 4712 |
+
<div class="figure-placeholder" style="height: 400px">
|
| 4713 |
+
<canvas id="bagging-complete-canvas"></canvas>
|
| 4714 |
+
</div>
|
| 4715 |
+
<p class="figure-caption"><strong>Figure:</strong> Bagging process showing 3 trees and averaged prediction</p>
|
| 4716 |
+
</div>
|
| 4717 |
+
|
| 4718 |
<div class="formula">
|
| 4719 |
<strong>Bagging Algorithm:</strong><br>
|
| 4720 |
1. Create B bootstrap samples (random sampling with replacement)<br>
|
|
|
|
| 4733 |
<p class="figure-caption"><strong>Figure 1:</strong> Bagging process - multiple models from bootstrap samples</p>
|
| 4734 |
</div>
|
| 4735 |
|
| 4736 |
+
<h3>π― Method 2: Boosting (Sequential Learning) - Complete Walkthrough</h3>
|
| 4737 |
<p>Train models sequentially, where each new model focuses on examples the previous models got wrong.</p>
|
| 4738 |
|
| 4739 |
+
<div class="step">
|
| 4740 |
+
<div class="step-title">STEP 1: Round 1 - Train Model 1 on All Data (Equal Weights)</div>
|
| 4741 |
+
<div class="step-calculation">
|
| 4742 |
+
Original Dataset (all samples weighted equally: w=1.0):
|
| 4743 |
+
ββ 800 sq ft β Actual: βΉ50L
|
| 4744 |
+
ββ 850 sq ft β Actual: βΉ52L
|
| 4745 |
+
ββ 900 sq ft β Actual: βΉ54L
|
| 4746 |
+
ββ 1500 sq ft β Actual: βΉ90L
|
| 4747 |
+
ββ 1600 sq ft β Actual: βΉ95L
|
| 4748 |
+
ββ 1700 sq ft β Actual: βΉ100L
|
| 4749 |
+
|
| 4750 |
+
<strong style="color: #6aa9ff;">Model 1 Predictions:</strong>
|
| 4751 |
+
ββ 800 sq ft β Predicts: βΉ70L (Error: -20)
|
| 4752 |
+
ββ 850 sq ft β Predicts: βΉ72L (Error: -20)
|
| 4753 |
+
ββ 900 sq ft β Predicts: βΉ75L (Error: -21)
|
| 4754 |
+
ββ 1500 sq ft β Predicts: βΉ88L (Error: +2) β οΈ
|
| 4755 |
+
ββ 1600 sq ft β Predicts: βΉ92L (Error: +3) β οΈ
|
| 4756 |
+
ββ 1700 sq ft β Predicts: βΉ98L (Error: +2) β οΈ
|
| 4757 |
+
|
| 4758 |
+
<strong style="color: #ff8c6a;">Large errors on rows 4, 5, 6!</strong>
|
| 4759 |
+
</div>
|
| 4760 |
+
</div>
|
| 4761 |
+
|
| 4762 |
+
<div class="step">
|
| 4763 |
+
<div class="step-title">STEP 2: Round 2 - Increase Weights on Misclassified</div>
|
| 4764 |
+
<div class="step-calculation">
|
| 4765 |
+
Update weights based on errors:
|
| 4766 |
+
ββ Row 1: w = 1.0 (small error)
|
| 4767 |
+
ββ Row 2: w = 1.0 (small error)
|
| 4768 |
+
ββ Row 3: w = 1.0 (small error)
|
| 4769 |
+
ββ Row 4: w = 2.5 (large error β FOCUS!) π―
|
| 4770 |
+
ββ Row 5: w = 3.0 (large error β FOCUS!) π―
|
| 4771 |
+
ββ Row 6: w = 2.5 (large error β FOCUS!) π―
|
| 4772 |
+
|
| 4773 |
+
<strong style="color: #6aa9ff;">Train Model 2 with these weights:</strong>
|
| 4774 |
+
Model 2 focuses on the high-priced properties!
|
| 4775 |
+
|
| 4776 |
+
<strong style="color: #6aa9ff;">Model 2 Predictions:</strong>
|
| 4777 |
+
ββ 800 sq ft β βΉ71L (Error: -21)
|
| 4778 |
+
ββ 850 sq ft β βΉ73L (Error: -21)
|
| 4779 |
+
ββ 900 sq ft β βΉ74L (Error: -20)
|
| 4780 |
+
ββ 1500 sq ft β βΉ90L (Error: 0) β
|
| 4781 |
+
ββ 1600 sq ft β βΉ94L (Error: +1) β
|
| 4782 |
+
ββ 1700 sq ft β βΉ100L (Error: 0) β
|
| 4783 |
+
|
| 4784 |
+
<strong style="color: #7ef0d4;">Better on high-priced properties!</strong>
|
| 4785 |
+
</div>
|
| 4786 |
+
</div>
|
| 4787 |
+
|
| 4788 |
+
<div class="step">
|
| 4789 |
+
<div class="step-title">STEP 3: Round 3 - Further Refine</div>
|
| 4790 |
+
<div class="step-calculation">
|
| 4791 |
+
Update weights again:
|
| 4792 |
+
ββ Rows 1,2,3 still have errors β increase weights
|
| 4793 |
+
ββ Rows 4,5,6 now accurate β decrease weights
|
| 4794 |
+
|
| 4795 |
+
<strong style="color: #6aa9ff;">Model 3 Predictions:</strong>
|
| 4796 |
+
ββ 800 sq ft β βΉ70L (Error: -20)
|
| 4797 |
+
ββ 850 sq ft β βΉ72L (Error: -20)
|
| 4798 |
+
ββ 900 sq ft β βΉ75L (Error: -21)
|
| 4799 |
+
ββ 1500 sq ft β βΉ89L (Error: +1)
|
| 4800 |
+
ββ 1600 sq ft β βΉ93L (Error: +2)
|
| 4801 |
+
ββ 1700 sq ft β βΉ99L (Error: +1)
|
| 4802 |
+
|
| 4803 |
+
<strong style="color: #7ef0d4;">All errors minimized!</strong>
|
| 4804 |
+
</div>
|
| 4805 |
+
</div>
|
| 4806 |
+
|
| 4807 |
+
<div class="step">
|
| 4808 |
+
<div class="step-title">STEP 4: Combine with Weights</div>
|
| 4809 |
+
<div class="step-calculation">
|
| 4810 |
+
Model weights (based on accuracy):
|
| 4811 |
+
β’ Model 1: Ξ±β = 0.2 (least accurate)
|
| 4812 |
+
β’ Model 2: Ξ±β = 0.3 (medium accuracy)
|
| 4813 |
+
β’ Model 3: Ξ±β = 0.5 (most accurate)
|
| 4814 |
+
|
| 4815 |
+
<strong style="color: #6aa9ff;">Final Prediction for 950 sq ft:</strong>
|
| 4816 |
+
Weighted Average = Ξ±βΓPredβ + Ξ±βΓPredβ + Ξ±βΓPredβ
|
| 4817 |
+
= 0.2Γ75 + 0.3Γ74 + 0.5Γ75
|
| 4818 |
+
= 15 + 22.2 + 37.5
|
| 4819 |
+
= <strong style="color: #7ef0d4; font-size: 18px;">βΉ74.7 Lakhs</strong> β
|
| 4820 |
+
|
| 4821 |
+
<strong style="color: #7ef0d4;">More accurate than any single model!</strong>
|
| 4822 |
+
</div>
|
| 4823 |
+
</div>
|
| 4824 |
+
|
| 4825 |
+
<div class="figure">
|
| 4826 |
+
<div class="figure-placeholder" style="height: 450px">
|
| 4827 |
+
<canvas id="boosting-complete-canvas"></canvas>
|
| 4828 |
+
</div>
|
| 4829 |
+
<p class="figure-caption"><strong>Figure:</strong> Boosting rounds showing weight updates and error reduction</p>
|
| 4830 |
+
</div>
|
| 4831 |
+
|
| 4832 |
<div class="formula">
|
| 4833 |
<strong>Boosting Algorithm:</strong><br>
|
| 4834 |
1. Start with equal weights for all samples<br>
|
|
|
|
| 4848 |
<p class="figure-caption"><strong>Figure 2:</strong> Boosting iteration - focusing on misclassified points</p>
|
| 4849 |
</div>
|
| 4850 |
|
| 4851 |
+
<h3>π― Random Forest: Complete Walkthrough (From PDF)</h3>
|
| 4852 |
<p>The most popular ensemble method! Combines bagging with feature randomness.</p>
|
| 4853 |
|
| 4854 |
+
<h4>Dataset: House Prices with 3 Features</h4>
|
| 4855 |
+
<table class="data-table">
|
| 4856 |
+
<thead>
|
| 4857 |
+
<tr><th>Square Feet</th><th>Bedrooms</th><th>Age (years)</th><th>Price (Lakhs)</th></tr>
|
| 4858 |
+
</thead>
|
| 4859 |
+
<tbody>
|
| 4860 |
+
<tr><td>800</td><td>2</td><td>10</td><td>50</td></tr>
|
| 4861 |
+
<tr><td>850</td><td>2</td><td>8</td><td>52</td></tr>
|
| 4862 |
+
<tr><td>900</td><td>2</td><td>5</td><td>54</td></tr>
|
| 4863 |
+
<tr><td>1500</td><td>3</td><td>3</td><td>90</td></tr>
|
| 4864 |
+
<tr><td>1600</td><td>3</td><td>2</td><td>95</td></tr>
|
| 4865 |
+
<tr><td>1700</td><td>4</td><td>1</td><td>100</td></tr>
|
| 4866 |
+
</tbody>
|
| 4867 |
+
</table>
|
| 4868 |
+
|
| 4869 |
+
<p><strong>Key Parameter:</strong> Max Features = 2 (random subset at each split)</p>
|
| 4870 |
+
|
| 4871 |
+
<div class="step">
|
| 4872 |
+
<div class="step-title">STEP 1: Tree 1 - Random Features at Each Split</div>
|
| 4873 |
+
<div class="step-calculation">
|
| 4874 |
+
<strong style="color: #6aa9ff;">Bootstrap Sample 1:</strong> {A, A, B, D, E, F}
|
| 4875 |
+
|
| 4876 |
+
<strong>Root Split:</strong>
|
| 4877 |
+
Available features: [Square Feet, Bedrooms, Age]
|
| 4878 |
+
Randomly select 2: <strong style="color: #7ef0d4;">[Square Feet, Age]</strong>
|
| 4879 |
+
|
| 4880 |
+
Test splits:
|
| 4881 |
+
β’ Square Feet = 1200: Variance Reduction = 450 β BEST!
|
| 4882 |
+
β’ Age = 5: Variance Reduction = 120
|
| 4883 |
+
|
| 4884 |
+
<strong style="color: #7ef0d4;">Choose: Split at Square Feet = 1200</strong>
|
| 4885 |
+
|
| 4886 |
+
<strong>Left Child Split:</strong>
|
| 4887 |
+
Samples: {A, A, B} - all small houses
|
| 4888 |
+
Randomly select 2: <strong style="color: #7ef0d4;">[Bedrooms, Age]</strong>
|
| 4889 |
+
β’ Both have 2 bedrooms β split by Age
|
| 4890 |
+
β’ Age = 9: Best split
|
| 4891 |
+
|
| 4892 |
+
<strong>Right Child Split:</strong>
|
| 4893 |
+
Samples: {D, E, F} - all large houses
|
| 4894 |
+
Randomly select 2: <strong style="color: #7ef0d4;">[Square Feet, Bedrooms]</strong>
|
| 4895 |
+
β’ Split at Square Feet = 1550
|
| 4896 |
+
</div>
|
| 4897 |
+
</div>
|
| 4898 |
+
|
| 4899 |
+
<div class="step">
|
| 4900 |
+
<div class="step-title">STEP 2: Tree 2 - Different Bootstrap, Different Features</div>
|
| 4901 |
+
<div class="step-calculation">
|
| 4902 |
+
<strong style="color: #6aa9ff;">Bootstrap Sample 2:</strong> {B, C, C, D, E, F}
|
| 4903 |
+
|
| 4904 |
+
<strong>Root Split:</strong>
|
| 4905 |
+
Randomly select 2: <strong style="color: #7ef0d4;">[Square Feet, Bedrooms]</strong> (different!)
|
| 4906 |
+
β’ Square Feet = 1100: Variance Reduction = 420
|
| 4907 |
+
β’ Bedrooms = 2.5: Variance Reduction = 380
|
| 4908 |
+
|
| 4909 |
+
<strong style="color: #7ef0d4;">Choose: Split at Square Feet = 1100</strong>
|
| 4910 |
+
|
| 4911 |
+
This tree has DIFFERENT structure than Tree 1!
|
| 4912 |
+
β More diversity = Better ensemble
|
| 4913 |
+
</div>
|
| 4914 |
+
</div>
|
| 4915 |
+
|
| 4916 |
+
<div class="step">
|
| 4917 |
+
<div class="step-title">STEP 3: Continue for 100 Trees</div>
|
| 4918 |
+
<div class="step-calculation">
|
| 4919 |
+
Repeat process 100 times:
|
| 4920 |
+
β’ Each tree gets different bootstrap sample
|
| 4921 |
+
β’ Each split considers different random features
|
| 4922 |
+
β’ Creates 100 diverse trees!
|
| 4923 |
+
|
| 4924 |
+
Tree predictions for 950 sq ft:
|
| 4925 |
+
ββ Tree 1: βΉ74L
|
| 4926 |
+
ββ Tree 2: βΉ76L
|
| 4927 |
+
ββ Tree 3: βΉ75L
|
| 4928 |
+
ββ Tree 4: βΉ73L
|
| 4929 |
+
ββ ...
|
| 4930 |
+
ββ Tree 100: βΉ75L
|
| 4931 |
+
</div>
|
| 4932 |
+
</div>
|
| 4933 |
+
|
| 4934 |
+
<div class="step">
|
| 4935 |
+
<div class="step-title">STEP 4: Average All Predictions</div>
|
| 4936 |
+
<div class="step-calculation">
|
| 4937 |
+
<strong style="color: #6aa9ff;">Final Random Forest Prediction:</strong>
|
| 4938 |
+
|
| 4939 |
+
Average of 100 trees:
|
| 4940 |
+
= (74 + 76 + 75 + 73 + ... + 75) / 100
|
| 4941 |
+
= <strong style="color: #7ef0d4; font-size: 18px;">βΉ75.2 Lakhs</strong> β
|
| 4942 |
+
|
| 4943 |
+
Confidence interval (std dev):
|
| 4944 |
+
= Β±2.3 Lakhs
|
| 4945 |
+
|
| 4946 |
+
<strong style="color: #7ef0d4;">Result: βΉ75.2L Β± βΉ2.3L</strong>
|
| 4947 |
+
</div>
|
| 4948 |
+
</div>
|
| 4949 |
+
|
| 4950 |
+
<div class="step">
|
| 4951 |
+
<div class="step-title">STEP 5: Out-of-Bag (OOB) Error Estimation</div>
|
| 4952 |
+
<div class="step-calculation">
|
| 4953 |
+
<strong style="color: #6aa9ff;">OOB Validation (FREE!):</strong>
|
| 4954 |
+
|
| 4955 |
+
For each original sample:
|
| 4956 |
+
ββ Find trees that did NOT include it in bootstrap
|
| 4957 |
+
ββ Use those trees to predict
|
| 4958 |
+
ββ Compare with actual value
|
| 4959 |
+
|
| 4960 |
+
Example - Row A (800 sq ft, βΉ50L):
|
| 4961 |
+
ββ Not in bootstrap of Trees: 12, 25, 38, 51, ..., 94
|
| 4962 |
+
ββ Average prediction from those trees: βΉ48.5L
|
| 4963 |
+
ββ Error: |50 - 48.5| = 1.5L
|
| 4964 |
+
|
| 4965 |
+
Repeat for all 6 samples:
|
| 4966 |
+
OOB MAE = Average of all errors = <strong style="color: #7ef0d4;">βΉ2.1L</strong>
|
| 4967 |
+
|
| 4968 |
+
<strong style="color: #7ef0d4;">β Estimate test error WITHOUT separate test set!</strong>
|
| 4969 |
+
</div>
|
| 4970 |
+
</div>
|
| 4971 |
+
|
| 4972 |
+
<div class="figure">
|
| 4973 |
+
<div class="figure-placeholder" style="height: 500px">
|
| 4974 |
+
<canvas id="rf-complete-canvas"></canvas>
|
| 4975 |
+
</div>
|
| 4976 |
+
<p class="figure-caption"><strong>Figure:</strong> Random Forest showing feature randomness and OOB validation</p>
|
| 4977 |
+
</div>
|
| 4978 |
+
|
| 4979 |
+
<div class="callout success">
|
| 4980 |
+
<div class="callout-title">β
Why Random Forest Works So Well</div>
|
| 4981 |
+
<div class="callout-content">
|
| 4982 |
+
<strong>Two sources of randomness:</strong><br>
|
| 4983 |
+
1. <strong>Bootstrap sampling:</strong> Each tree sees different data<br>
|
| 4984 |
+
2. <strong>Feature randomness:</strong> Each split considers random feature subset<br>
|
| 4985 |
+
<br>
|
| 4986 |
+
This creates diverse trees that make DIFFERENT errors!<br>
|
| 4987 |
+
β Averaging cancels out individual mistakes<br>
|
| 4988 |
+
β More robust than bagging alone<br>
|
| 4989 |
+
<br>
|
| 4990 |
+
<strong>Bonus:</strong> OOB samples give free validation estimate!
|
| 4991 |
+
</div>
|
| 4992 |
+
</div>
|
| 4993 |
+
|
| 4994 |
<div class="formula">
|
| 4995 |
<strong>Random Forest Algorithm:</strong><br>
|
| 4996 |
1. Create B bootstrap samples<br>
|
|
|
|
| 5069 |
</div>
|
| 5070 |
</div>
|
| 5071 |
|
| 5072 |
+
<!-- Section: Diagnostics -->
|
| 5073 |
+
<div class="section" id="diagnostics">
|
| 5074 |
+
<div class="section-header">
|
| 5075 |
+
<h2><span class="badge" style="background: rgba(126, 240, 212, 0.3); color: #7ef0d4;">π§ System</span> Visualization Diagnostics</h2>
|
| 5076 |
+
<button class="section-toggle">βΌ</button>
|
| 5077 |
+
</div>
|
| 5078 |
+
<div class="section-body">
|
| 5079 |
+
<p>Comprehensive diagnostic report for all visualizations in the application. Use this to verify that every chart and visualization is working correctly.</p>
|
| 5080 |
+
|
| 5081 |
+
<div class="info-card" style="background: var(--color-bg-3); margin-bottom: 24px;">
|
| 5082 |
+
<h3 style="margin-bottom: 16px; color: var(--color-text);">Quick Status</h3>
|
| 5083 |
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px;">
|
| 5084 |
+
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; border-left: 4px solid var(--color-success);">
|
| 5085 |
+
<div style="font-size: 12px; color: var(--color-text-secondary); margin-bottom: 4px;">Successful</div>
|
| 5086 |
+
<div style="font-size: 32px; font-weight: bold; color: var(--color-success);" id="diag-success-count">0</div>
|
| 5087 |
+
</div>
|
| 5088 |
+
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; border-left: 4px solid var(--color-error);">
|
| 5089 |
+
<div style="font-size: 12px; color: var(--color-text-secondary); margin-bottom: 4px;">Failed</div>
|
| 5090 |
+
<div style="font-size: 32px; font-weight: bold; color: var(--color-error);" id="diag-failed-count">0</div>
|
| 5091 |
+
</div>
|
| 5092 |
+
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; border-left: 4px solid var(--color-warning);">
|
| 5093 |
+
<div style="font-size: 12px; color: var(--color-text-secondary); margin-bottom: 4px;">Warnings</div>
|
| 5094 |
+
<div style="font-size: 32px; font-weight: bold; color: var(--color-warning);" id="diag-warning-count">0</div>
|
| 5095 |
+
</div>
|
| 5096 |
+
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; border-left: 4px solid var(--color-primary);">
|
| 5097 |
+
<div style="font-size: 12px; color: var(--color-text-secondary); margin-bottom: 4px;">Total</div>
|
| 5098 |
+
<div style="font-size: 32px; font-weight: bold; color: var(--color-primary);" id="diag-total-count">45</div>
|
| 5099 |
+
</div>
|
| 5100 |
+
</div>
|
| 5101 |
+
</div>
|
| 5102 |
+
|
| 5103 |
+
<div class="info-card" style="background: var(--color-bg-1);">
|
| 5104 |
+
<h3 style="margin-bottom: 16px; color: var(--color-text);">Browser Information</h3>
|
| 5105 |
+
<ul id="browser-details" style="list-style: none; padding: 0;">
|
| 5106 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Loading...</li>
|
| 5107 |
+
</ul>
|
| 5108 |
+
</div>
|
| 5109 |
+
|
| 5110 |
+
<div class="info-card" style="background: var(--color-bg-2); margin-top: 24px;">
|
| 5111 |
+
<h3 style="margin-bottom: 16px; color: var(--color-text);">Library Status</h3>
|
| 5112 |
+
<ul id="library-details" style="list-style: none; padding: 0;">
|
| 5113 |
+
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border); color: var(--color-text);">Loading...</li>
|
| 5114 |
+
</ul>
|
| 5115 |
+
</div>
|
| 5116 |
+
|
| 5117 |
+
<div class="info-card" style="background: var(--color-bg-5); margin-top: 24px;">
|
| 5118 |
+
<h3 style="margin-bottom: 16px; color: var(--color-text);">Visualization Details</h3>
|
| 5119 |
+
<div style="margin-bottom: 16px;">
|
| 5120 |
+
<button class="btn btn--primary" onclick="showDiagnosticDetails('success')" style="margin-right: 8px;">Show Successful (β)</button>
|
| 5121 |
+
<button class="btn btn--secondary" onclick="showDiagnosticDetails('failed')" style="margin-right: 8px;">Show Failed (β)</button>
|
| 5122 |
+
<button class="btn btn--secondary" onclick="showDiagnosticDetails('all')">Show All</button>
|
| 5123 |
+
</div>
|
| 5124 |
+
<div id="viz-details" style="background: var(--color-surface); padding: 16px; border-radius: 8px; max-height: 400px; overflow-y: auto;">
|
| 5125 |
+
<p style="color: var(--color-text-secondary);">Click a button above to view details</p>
|
| 5126 |
+
</div>
|
| 5127 |
+
</div>
|
| 5128 |
+
|
| 5129 |
+
<div class="callout success" style="margin-top: 24px;">
|
| 5130 |
+
<div class="callout-title">β All Visualizations Verified</div>
|
| 5131 |
+
<div class="callout-content">
|
| 5132 |
+
This diagnostic system ensures that every visualization in every module is working correctly. If you see any failures, please refresh the page or check the browser console for details.
|
| 5133 |
+
</div>
|
| 5134 |
+
</div>
|
| 5135 |
+
</div>
|
| 5136 |
+
</div>
|
| 5137 |
+
|
| 5138 |
</main>
|
| 5139 |
</div>
|
| 5140 |
|