Update index.html
Browse files- 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 |
-
<
|
6 |
-
<
|
7 |
-
|
8 |
</head>
|
9 |
-
<body>
|
10 |
-
<
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
<div id="
|
17 |
-
|
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 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 |
-
|
47 |
-
|
48 |
-
|
49 |
-
[
|
50 |
-
{ q: "
|
51 |
-
|
52 |
-
|
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 |
-
|
67 |
-
|
68 |
-
{ q: "
|
69 |
-
|
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 |
-
|
85 |
-
|
86 |
-
{ q: "
|
87 |
-
|
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 |
-
|
103 |
-
|
104 |
-
{ q: "
|
105 |
-
|
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 |
-
|
121 |
-
|
122 |
-
{ q: "
|
123 |
-
|
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 |
-
|
141 |
-
const
|
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 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
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 |
+
|