eaglelandsonce commited on
Commit
b63a6c5
·
verified ·
1 Parent(s): 1ec6f4e

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +61 -253
index.html CHANGED
@@ -1,41 +1,25 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="UTF-8"/>
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
- <title>Five Algorithm Jeopardy</title>
7
- <!-- same CSS as before -->
8
  </head>
9
- <body>
10
- <h1>Five Algorithm Jeopardy</h1>
11
- <a class="source" href="https://www.linkedin.com/pulse/foundational-machine-learning-algorithms-modern-data-science-lively-t4xje/" target="_blank">
12
- Source: Foundational Machine Learning Algorithms for Modern Data Science (LinkedIn)
13
- </a>
14
 
15
- <div class="topbar">
16
- <div id="score">Score: 0</div>
17
- <button class="btn-reset" id="reset-btn" title="Start a fresh round">Reset Game</button>
18
- </div>
19
-
20
- <div class="stage">
21
- <div id="game-board">
22
- <div class="category">Logistic Regression</div>
23
- <div class="category">Decision Tree</div>
24
- <div class="category">Random Forest</div>
25
- <div class="category">Support Vector Machine</div>
26
- <div class="category">KNN</div>
27
  </div>
28
  </div>
29
 
30
- <div id="question-display"></div>
31
- <div id="review" style="display:none;"></div>
32
-
33
- <audio id="dd-audio" preload="auto">
34
- <source src="daily-double.mp3" type="audio/mpeg">
35
- </audio>
36
- <div id="dd-overlay" class="dd-overlay"><div class="dd-text">DAILY&nbsp;DOUBLE!</div></div>
37
-
38
  <script>
 
39
  const categories = [
40
  "Logistic Regression",
41
  "Decision Tree",
@@ -43,239 +27,63 @@
43
  "Support Vector Machine",
44
  "KNN"
45
  ];
46
- // 15 questions, correct indices evenly distributed (5x0, 5x1, 5x2)
47
- const questions = [
48
- // Logistic Regression
49
- [
50
- { q: "What does Logistic Regression output for each prediction?", a: [
51
- "A probability between 0 and 1 using the sigmoid function",
52
- "A cluster of nearest neighbors",
53
- "A collection of random trees averaged together"
54
- ], correct: 0 },
55
- { q: "Which is a limitation of Logistic Regression?", a: [
56
- "It automatically models non-linear decision boundaries",
57
- "It struggles when data is not linearly separable without feature engineering",
58
- "It cannot run on large datasets"
59
- ], correct: 1 },
60
- { q: "In healthcare, Logistic Regression is often used to:", a: [
61
- "Rank feature importance in tree ensembles",
62
- "Estimate probabilities of disease presence or risk",
63
- "Define separating hyperplanes in high dimensions"
64
- ], correct: 2 }
65
  ],
66
- // Decision Tree
67
- [
68
- { q: "What measure is commonly used to decide splits in Decision Trees?", a: [
69
- "Gradient descent step size",
70
- "Gini impurity or entropy",
71
- "Euclidean distance"
72
- ], correct: 1 },
73
- { q: "Which is a strength of Decision Trees?", a: [
74
- "They are transparent and easy to explain to non-technical stakeholders",
75
- "They are always the most accurate model for high-dimensional data",
76
- "They require no stopping criteria and cannot overfit"
77
- ], correct: 0 },
78
- { q: "Why might Decision Trees be unstable?", a: [
79
- "Because they average many weak learners",
80
- "Because small changes in input data can change the entire tree structure",
81
- "Because they always assume linear log-odds"
82
- ], correct: 2 }
83
  ],
84
- // Random Forest
85
- [
86
- { q: "How does a Random Forest reduce overfitting compared to a single Decision Tree?", a: [
87
- "By using sigmoid functions",
88
- "By averaging results across many randomly built trees",
89
- "By calculating Euclidean distances to neighbors"
90
- ], correct: 1 },
91
- { q: "Which real-world task is well suited to Random Forests?", a: [
92
- "Fraud detection with structured transaction data",
93
- "Image recognition with deep convolutional networks",
94
- "Building separating hyperplanes in very high-dimensional text data"
95
- ], correct: 0 },
96
- { q: "What is a limitation of Random Forests?", a: [
97
- "They are always linear models",
98
- "They are slower to train and interpret compared to a single tree",
99
- "They cannot handle missing values"
100
- ], correct: 2 }
101
  ],
102
- // Support Vector Machine
103
- [
104
- { q: "What is the key principle behind SVM classification?", a: [
105
- "Maximizing the margin between classes using support vectors",
106
- "Averaging predictions from multiple trees",
107
- "Voting from k-nearest neighbors"
108
- ], correct: 0 },
109
- { q: "Which hyperparameter defines how far the influence of a single training example reaches in an SVM?", a: [
110
- "max_depth",
111
- "gamma",
112
- "n_neighbors"
113
- ], correct: 1 },
114
- { q: "In which field is SVM often applied due to high-dimensional data?", a: [
115
- "Computer vision image classification with CNNs",
116
- "Text classification such as spam filtering",
117
- "Simple binary logistic models"
118
- ], correct: 2 }
119
  ],
120
- // KNN
121
- [
122
- { q: "How does KNN classify a new data point?", a: [
123
- "By calculating the weighted sum of features and applying sigmoid",
124
- "By looking at the majority class among its k nearest neighbors",
125
- "By building an ensemble of trees to vote"
126
- ], correct: 1 },
127
- { q: "What is a major limitation of KNN?", a: [
128
- "Prediction is slow on large datasets since distances must be calculated for all points",
129
- "It always assumes linear decision boundaries",
130
- "It cannot handle more than two features"
131
- ], correct: 0 },
132
- { q: "Which type of task is naturally suited to KNN?", a: [
133
- "Credit scoring in finance",
134
- "Handwriting recognition or recommender systems",
135
- "Genome sequence modeling"
136
- ], correct: 2 }
137
  ]
138
- ];
139
 
140
- let score = 0, answered = 0;
141
- const total = 15;
142
- const board = document.getElementById("game-board"),
143
- qdisp = document.getElementById("question-display"),
144
- sdisp = document.getElementById("score"),
145
- review = document.getElementById("review");
146
- const ddOverlay = document.getElementById("dd-overlay");
147
- const ddAudio = document.getElementById("dd-audio");
148
- const shuffleRegistry = new Map();
149
- const missedQuestions = [];
150
- const dailyDouble = { col: Math.floor(Math.random() * 5), row: Math.floor(Math.random() * 3) };
151
- document.getElementById('reset-btn').addEventListener('click', () => location.reload());
152
 
153
- function createBoard() {
154
- for (let row = 0; row < 3; row++) {
155
- for (let col = 0; col < 5; col++) {
156
- const card = document.createElement("div");
157
- card.className = "card tilt";
158
- card.textContent = `$${(row + 1) * 100}`;
159
- card.dataset.col = col;
160
- card.dataset.row = row;
161
- card.addEventListener("mousemove", (e) => {
162
- const r = card.getBoundingClientRect();
163
- const x = (e.clientX - r.left) / r.width;
164
- const y = (e.clientY - r.top) / r.height;
165
- card.style.setProperty("--ry", `${(x - 0.5) * 10}deg`);
166
- card.style.setProperty("--rx", `${(0.5 - y) * 10}deg`);
167
- });
168
- card.addEventListener("mouseleave", () => {
169
- card.style.removeProperty("--ry");
170
- card.style.removeProperty("--rx");
171
- });
172
- card.onclick = () => handleCardClick(card);
173
- board.appendChild(card);
174
- }
175
- }
176
- }
177
- function handleCardClick(card){
178
- if (card.classList.contains("disabled")) return;
179
- const col = +card.dataset.col;
180
- const row = +card.dataset.row;
181
- const isDD = (col === dailyDouble.col && row === dailyDouble.row);
182
- if (isDD){
183
- triggerDailyDouble(card, () => showQuestion(col, row, card, true));
184
- } else {
185
- showQuestion(col, row, card, false);
186
- }
187
- }
188
- function triggerDailyDouble(card, onDone){
189
- const ring = document.createElement("div");
190
- ring.className = "flash-ring";
191
- card.appendChild(ring);
192
- ddAudio.currentTime = 0;
193
- ddAudio.play().catch(()=>{});
194
- ddOverlay.style.display = "flex";
195
- setTimeout(() => {
196
- ddOverlay.style.display = "none";
197
- ring.remove();
198
- onDone();
199
- }, 2400);
200
- }
201
- function showQuestion(categoryIndex, difficulty, card, isDailyDouble){
202
- const q = questions[categoryIndex][difficulty];
203
- const options = q.a.map((text, origIdx) => ({ text, origIdx }));
204
- for (let i = options.length - 1; i > 0; i--) {
205
- const j = Math.floor(Math.random() * (i + 1));
206
- [options[i], options[j]] = [options[j], options[i]];
207
- }
208
- const shuffledCorrectIndex = options.findIndex(o => o.origIdx === q.correct);
209
- const key = `${categoryIndex}-${difficulty}`;
210
- shuffleRegistry.set(key, { shuffledCorrectIndex, isDailyDouble });
211
- const dailyDoubleBanner = isDailyDouble ? `<div class="daily-double-banner">🎉 DAILY DOUBLE! 🎉</div>` : "";
212
- qdisp.innerHTML = `
213
- ${dailyDoubleBanner}
214
- <h2>${categories[categoryIndex]} for $${(difficulty + 1) * 100}${isDailyDouble ? " (x2)" : ""}</h2>
215
- <p>${q.q}</p>
216
- <div class="answer-container">
217
- ${options.map((opt, i) =>
218
- `<button class="answer-btn" data-ans="${i}" data-key="${key}">${opt.text}</button>`
219
- ).join("")}
220
- </div>
221
- `;
222
- card.classList.add("disabled");
223
- document.querySelectorAll('.answer-btn').forEach(btn => {
224
- btn.addEventListener('click', () => {
225
- if (btn.classList.contains('disabled')) return;
226
- const chosenIndex = parseInt(btn.getAttribute('data-ans'), 10);
227
- const k = btn.getAttribute('data-key');
228
- checkAnswer(categoryIndex, difficulty, chosenIndex, k);
229
- }, { once: true });
230
- });
231
- }
232
- function checkAnswer(cat, diff, chosenShuffledIndex, key){
233
- const q = questions[cat][diff];
234
- const reg = shuffleRegistry.get(key);
235
- const isCorrect = (chosenShuffledIndex === reg.shuffledCorrectIndex);
236
- let val = (diff + 1) * 100;
237
- if (reg.isDailyDouble) val *= 2;
238
- document.querySelectorAll(".answer-btn").forEach(b => {
239
- b.disabled = true; b.classList.add("disabled");
240
  });
241
- if (isCorrect) {
242
- score += val;
243
- qdisp.innerHTML += `<p class="feedback" style="color:green;">✅ Correct! +$${val.toLocaleString()}</p>`;
244
- } else {
245
- score -= val;
246
- const correctText = q.a[q.correct];
247
- const chosenBtn = document.querySelector(`.answer-btn[data-ans="${chosenShuffledIndex}"][data-key="${key}"]`);
248
- const chosenPretty = chosenBtn ? chosenBtn.textContent : "(your choice)";
249
- qdisp.innerHTML += `<p class="feedback" style="color:#b00020;">❌ Wrong! −$${val.toLocaleString()}<br/>Correct answer: <em>${correctText}</em></p>`;
250
- missedQuestions.push({
251
- category: categories[cat],
252
- value: `$${(diff+1)*100}${reg.isDailyDouble ? " (x2)" : ""}`,
253
- question: q.q,
254
- yourAnswer: chosenPretty,
255
- correctAnswer: correctText
256
- });
257
- }
258
- sdisp.textContent = `Score: ${score}`;
259
- if (++answered === total) endGame();
260
- }
261
- function endGame(){
262
- qdisp.innerHTML += `<h2 style="margin-top:12px">Game Over!</h2><p>Your final score: $${score.toLocaleString()}</p>`;
263
- if (missedQuestions.length){
264
- const items = missedQuestions.map(m =>
265
- `<div class="missed">
266
- <div class="q">(${m.category} • ${m.value}) ${m.question}</div>
267
- <div class="a">Your answer: <em>${m.yourAnswer}</em></div>
268
- <div class="a">Correct: <strong>${m.correctAnswer}</strong></div>
269
- </div>`
270
- ).join("");
271
- review.style.display = "block";
272
- review.innerHTML = `<h3>Review: Questions to Revisit (${missedQuestions.length})</h3>${items}`;
273
- } else {
274
- review.style.display = "block";
275
- review.innerHTML = `<h3>Perfect Round!</h3><p>You answered all questions correctly 🎉</p>`;
276
- }
277
  }
278
- createBoard();
279
  </script>
280
  </body>
281
  </html>
 
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Jeopardy Game - Five Algorithms</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
  </head>
9
+ <body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen flex items-center justify-center p-6">
10
+ <div class="w-full max-w-5xl bg-white rounded-2xl shadow-xl p-6">
11
+ <h1 class="text-4xl font-extrabold text-center text-indigo-700 mb-6">
12
+ Jeopardy: Five Algorithms
13
+ </h1>
14
 
15
+ <!-- Game Board -->
16
+ <div id="board" class="grid grid-cols-5 gap-2 text-center">
17
+ <!-- Categories will go here -->
 
 
 
 
 
 
 
 
 
18
  </div>
19
  </div>
20
 
 
 
 
 
 
 
 
 
21
  <script>
22
+ // Categories = Five Algorithms
23
  const categories = [
24
  "Logistic Regression",
25
  "Decision Tree",
 
27
  "Support Vector Machine",
28
  "KNN"
29
  ];
30
+
31
+ // 3 questions per category = 15 total
32
+ const questions = {
33
+ "Logistic Regression": [
34
+ { points: 100, q: "Which algorithm estimates probabilities using a sigmoid function?", a: "Logistic Regression" },
35
+ { points: 200, q: "This algorithm is often used for binary classification, like predicting churn (Yes/No).", a: "Logistic Regression" },
36
+ { points: 300, q: "Which hyperparameter controls regularization strength in Logistic Regression?", a: "C" }
 
 
 
 
 
 
 
 
 
 
 
 
37
  ],
38
+ "Decision Tree": [
39
+ { points: 100, q: "Which algorithm splits data based on feature thresholds in a flowchart-like structure?", a: "Decision Tree" },
40
+ { points: 200, q: "This algorithm is easy to visualize and interpret but prone to overfitting.", a: "Decision Tree" },
41
+ { points: 300, q: "Which splitting criteria are commonly used in Decision Trees?", a: "Gini Impurity and Entropy" }
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  ],
43
+ "Random Forest": [
44
+ { points: 100, q: "Which ensemble algorithm builds many trees and averages their predictions?", a: "Random Forest" },
45
+ { points: 200, q: "This algorithm reduces overfitting by using bagging across multiple trees.", a: "Random Forest" },
46
+ { points: 300, q: "Which hyperparameter controls the number of trees in a Random Forest?", a: "n_estimators" }
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  ],
48
+ "Support Vector Machine": [
49
+ { points: 100, q: "Which algorithm finds the optimal hyperplane that separates classes?", a: "Support Vector Machine" },
50
+ { points: 200, q: "This algorithm is powerful with high-dimensional data and can use kernels.", a: "Support Vector Machine" },
51
+ { points: 300, q: "Which function transforms data into higher dimensions in SVM?", a: "Kernel Trick" }
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  ],
53
+ "KNN": [
54
+ { points: 100, q: "Which algorithm classifies a point based on the labels of nearby points?", a: "K-Nearest Neighbors (KNN)" },
55
+ { points: 200, q: "This lazy learner algorithm has no training phase and relies on distance metrics.", a: "K-Nearest Neighbors (KNN)" },
56
+ { points: 300, q: "Which hyperparameter determines how many neighbors vote on classification?", a: "k" }
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  ]
58
+ };
59
 
60
+ // Build board
61
+ const board = document.getElementById("board");
 
 
 
 
 
 
 
 
 
 
62
 
63
+ // First row = categories
64
+ categories.forEach(cat => {
65
+ const cell = document.createElement("div");
66
+ cell.className = "bg-indigo-600 text-white font-bold p-2 rounded";
67
+ cell.innerText = cat;
68
+ board.appendChild(cell);
69
+ });
70
+
71
+ // Question rows (3 per category)
72
+ for (let i = 0; i < 3; i++) {
73
+ categories.forEach(cat => {
74
+ const qData = questions[cat][i];
75
+ const cell = document.createElement("button");
76
+ cell.className = "bg-yellow-300 font-bold p-4 rounded hover:bg-yellow-400";
77
+ cell.innerText = `$${qData.points}`;
78
+ cell.onclick = () => {
79
+ alert(`${qData.q}\n\nAnswer: ${qData.a}`);
80
+ cell.disabled = true;
81
+ cell.className = "bg-gray-300 font-bold p-4 rounded";
82
+ };
83
+ board.appendChild(cell);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
 
86
  </script>
87
  </body>
88
  </html>
89
+