Data_Labelling / index.html
eaglelandsonce's picture
Update index.html
777489b verified
Raw
History Blame Contribute Delete
15.3 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Data Labeling Tic Tac Toe</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gradient-to-br from-indigo-50 via-sky-50 to-teal-100 min-h-screen flex items-center justify-center p-4">
<div class="max-w-6xl w-full bg-white rounded-2xl shadow-xl p-6">
<h1 class="text-3xl font-extrabold mb-3 text-center text-indigo-800">Data Labeling Tic Tac Toe</h1>
<p class="text-center mb-2 text-sm text-gray-600">
Reference: <a href="https://www.linkedin.com/pulse/data-labelling-michael-lively-ofhle/" class="text-indigo-600 hover:underline" target="_blank" rel="noopener noreferrer">Data Labelling: The Ghost in the Machine</a>
</p>
<p class="text-center mb-4 text-sm text-gray-500">
Answer correctly to claim a square. Miss the question, and your turn passes.
</p>
<div id="banner" class="hidden bg-indigo-100 border border-indigo-300 text-indigo-800 font-bold text-center py-2 rounded mb-4"></div>
<div class="flex flex-col lg:flex-row items-center lg:items-start justify-center gap-5">
<!-- Game Board -->
<div id="board" class="grid grid-cols-3 gap-2 border-4 border-indigo-300 rounded-xl p-3 bg-indigo-50"></div>
<!-- Question Panel -->
<div id="questionPanel" class="w-full lg:w-1/2 bg-gray-50 rounded-xl shadow p-5 min-h-80">
<h2 id="panelQuestion" class="text-xl font-semibold text-gray-800">Select a square to view the question</h2>
<ul id="panelChoices" class="mt-4 space-y-2"></ul>
<p id="panelHint" class="mt-3 text-sm text-gray-600 hidden"></p>
<button id="hintBtn" class="mt-4 px-3 py-1 bg-gray-200 text-gray-700 rounded hover:bg-gray-300">Show Hint</button>
</div>
</div>
<div class="flex flex-col sm:flex-row justify-between items-center gap-3 mt-6">
<p id="status" class="text-lg font-medium text-gray-800"></p>
<button id="restartBtn" class="px-4 py-2 bg-indigo-600 text-white rounded hover:bg-indigo-700">Restart</button>
</div>
</div>
<script>
const questions = [
{
question: 'What is the main purpose of data labeling in supervised machine learning?',
choices: [
'To compress datasets before training',
'To give models labeled examples they can learn from',
'To remove all categorical data from a dataset',
'To increase the number of model parameters'
],
answer: 2,
hint: 'Labels provide the ground truth used during training.'
},
{
question: 'Which type of image labeling assigns a single class to an entire image?',
choices: [
'Image classification',
'Object detection',
'Semantic segmentation',
'Speaker identification'
],
answer: 1,
hint: 'The whole image receives one label.'
},
{
question: 'Which image labeling method uses bounding boxes around objects?',
choices: [
'Image classification',
'Object detection',
'Sentiment analysis',
'Label encoding'
],
answer: 2,
hint: 'The model must learn both what the object is and where it is.'
},
{
question: 'Semantic segmentation labels what part of an image?',
choices: [
'Only the image filename',
'Only the largest object',
'Every pixel with a class',
'Only the image metadata'
],
answer: 3,
hint: 'This is more detailed than a bounding box.'
},
{
question: 'Named Entity Recognition is used to label which kind of information?',
choices: [
'Names, dates, organizations, and locations in text',
'Pixels in an image',
'Temperature values in a spreadsheet',
'Audio volume levels'
],
answer: 1,
hint: 'NER is a text labeling task.'
},
{
question: 'What does Inter-Annotator Agreement measure?',
choices: [
'How fast a model trains',
'How much different annotators agree on labels',
'How many GPUs are used',
'How large a dataset is after compression'
],
answer: 2,
hint: 'It checks consistency between human labelers.'
},
{
question: 'Why is high Inter-Annotator Agreement important?',
choices: [
'It means the labels are likely more consistent and dependable',
'It guarantees the model will never fail',
'It removes the need for preprocessing',
'It makes numerical scaling unnecessary'
],
answer: 1,
hint: 'Models learn better from consistent labels.'
},
{
question: 'Which agreement metric is especially useful because it can handle missing labels and different numbers of annotators?',
choices: [
'Percent agreement',
'Krippendorff\'s Alpha',
'Min-max scaling',
'One-hot encoding'
],
answer: 2,
hint: 'It is one of the most robust agreement measures.'
},
{
question: 'Why can percent agreement be misleading as a labeling quality metric?',
choices: [
'It ignores agreement that may happen by chance',
'It only works on image files',
'It requires ratio data',
'It removes missing labels automatically'
],
answer: 1,
hint: 'Some annotators can agree randomly.'
},
{
question: 'Which data type has ordered values but no true zero point?',
choices: [
'Nominal data',
'Interval data',
'Binary data',
'Object data'
],
answer: 2,
hint: 'Temperature in Celsius is a common example.'
},
{
question: 'Which data type has a meaningful zero and supports meaningful ratios?',
choices: [
'Ratio data',
'Nominal data',
'Ordinal data',
'Interval data'
],
answer: 1,
hint: 'Height, weight, and revenue are examples.'
},
{
question: 'Movie ratings such as poor, fair, good, and excellent are examples of what data type?',
choices: [
'Nominal data',
'Ordinal data',
'Ratio data',
'Continuous data'
],
answer: 2,
hint: 'The categories have a meaningful order.'
},
{
question: 'One-hot encoding converts categorical data into what format?',
choices: [
'A binary vector',
'A text paragraph',
'A bounding box',
'A continuous audio signal'
],
answer: 1,
hint: 'Each category becomes a separate 0/1 indicator.'
},
{
question: 'Why is scaling numerical data important before modeling?',
choices: [
'It prevents large-range features from dominating the model',
'It removes all labels from the dataset',
'It changes text into images',
'It guarantees perfect accuracy'
],
answer: 1,
hint: 'Think about a feature ranging from 0 to 1 versus one ranging from 0 to 1000.'
},
{
question: 'Standardization usually transforms numerical data to have what?',
choices: [
'A mean of 0 and standard deviation of 1',
'Only values of true and false',
'Only text labels',
'A maximum value of exactly 100'
],
answer: 1,
hint: 'This is a common scaling technique.'
},
{
question: 'Which human factor can directly reduce labeling consistency over time?',
choices: [
'Fatigue and boredom',
'Higher screen resolution',
'More storage space',
'Faster network speed'
],
answer: 1,
hint: 'Human attention is limited.'
},
{
question: 'What is a major risk when labeling guidelines are unclear?',
choices: [
'Annotators may apply labels inconsistently',
'The dataset becomes too small to store',
'All labels become numerical automatically',
'The model trains without data'
],
answer: 1,
hint: 'Clear rules improve shared interpretation.'
},
{
question: 'What is the goal of training and calibration sessions for annotators?',
choices: [
'To align annotators on the same labeling standard',
'To increase file size',
'To remove quality control',
'To avoid checking disagreements'
],
answer: 1,
hint: 'Calibration improves consistency.'
},
{
question: 'What is the main tradeoff in the paradox of big data for labeling?',
choices: [
'More data can help generalization, but poor consistency can hurt precision',
'More data always guarantees better labels',
'Smaller data always removes bias',
'Bigger datasets do not need quality control'
],
answer: 1,
hint: 'Size does not automatically mean quality.'
},
{
question: 'Why do inconsistent labels confuse machine learning models?',
choices: [
'They give the model conflicting patterns to learn',
'They reduce monitor brightness',
'They make all features ratio data',
'They eliminate the need for testing'
],
answer: 1,
hint: 'The model learns from the labels it is given.'
}
];
let currentPlayer, boardState, cellQuestions, selectedCell;
const boardEl = document.getElementById('board');
const statusEl = document.getElementById('status');
const bannerEl = document.getElementById('banner');
const hintBtn = document.getElementById('hintBtn');
const panelQuestion = document.getElementById('panelQuestion');
const panelChoices = document.getElementById('panelChoices');
const panelHint = document.getElementById('panelHint');
const restartBtn = document.getElementById('restartBtn');
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
function buildBalancedPositions(nQuestions, kChoices) {
const base = Math.floor(nQuestions / kChoices);
const remainder = nQuestions % kChoices;
const slots = [];
for (let pos = 1; pos <= kChoices; pos++) {
for (let c = 0; c < base; c++) slots.push(pos);
}
const extra = shuffle(Array.from({ length: kChoices }, (_, i) => i + 1)).slice(0, remainder);
slots.push(...extra);
return shuffle(slots);
}
function initGame() {
currentPlayer = 'X';
boardState = Array(9).fill('');
selectedCell = null;
bannerEl.classList.add('hidden');
statusEl.innerText = '';
const shuffledQs = shuffle([...questions]).slice(0, 9);
const kChoices = 4;
const targetPositions = buildBalancedPositions(shuffledQs.length, kChoices);
cellQuestions = shuffledQs.map((q, idx) => {
const originalCorrectIdx0 = q.answer - 1;
const correctText = q.choices[originalCorrectIdx0];
const wrongs = q.choices.filter((_, i) => i !== originalCorrectIdx0);
shuffle(wrongs);
const targetPos1 = targetPositions[idx];
const targetPos0 = targetPos1 - 1;
const newChoices = Array(kChoices).fill(null);
newChoices[targetPos0] = correctText;
let w = 0;
for (let i = 0; i < kChoices; i++) {
if (newChoices[i] === null) newChoices[i] = wrongs[w++];
}
return {
question: q.question,
choices: newChoices,
answer: targetPos1,
hint: q.hint
};
});
panelQuestion.innerText = 'Select a square to view the question';
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
panelHint.innerText = '';
renderBoard();
}
function renderBoard() {
boardEl.innerHTML = '';
boardState.forEach((mark, idx) => {
const btn = document.createElement('button');
let cls = 'bg-white h-24 w-24 sm:h-28 sm:w-28 flex items-center justify-center text-4xl font-extrabold rounded-lg shadow hover:bg-indigo-100 transition';
if (mark === 'X') cls += ' text-blue-600';
if (mark === 'O') cls += ' text-red-600';
btn.className = cls;
btn.innerText = mark;
btn.disabled = mark !== '';
btn.addEventListener('click', () => openQuestion(idx));
boardEl.appendChild(btn);
});
statusEl.innerText = `Current: ${currentPlayer}`;
}
function openQuestion(idx) {
if (boardState[idx] !== '') return;
selectedCell = idx;
const q = cellQuestions[idx];
panelQuestion.innerText = q.question;
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
panelHint.innerText = q.hint;
q.choices.forEach((choiceText, i) => {
const li = document.createElement('li');
const btn = document.createElement('button');
btn.innerText = choiceText;
btn.className = 'w-full text-left px-4 py-2 bg-indigo-50 rounded hover:bg-indigo-100 border border-indigo-100';
btn.addEventListener('click', () => handleAnswer(i + 1));
li.appendChild(btn);
panelChoices.appendChild(li);
});
}
function handleAnswer(choice) {
if (selectedCell === null) return;
const q = cellQuestions[selectedCell];
if (choice === q.answer) {
boardState[selectedCell] = currentPlayer;
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
panelQuestion.innerText = 'Correct! Select another open square.';
renderBoard();
if (checkWin()) return endGame(`${currentPlayer} wins!`);
if (boardState.every(c => c)) return endGame('Stalemate!');
} else {
alert('Incorrect! Turn missed.');
}
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
statusEl.innerText = `Current: ${currentPlayer}`;
selectedCell = null;
}
function checkWin() {
const wins = [
[0,1,2], [3,4,5], [6,7,8],
[0,3,6], [1,4,7], [2,5,8],
[0,4,8], [2,4,6]
];
return wins.some(combo => combo.every(i => boardState[i] === currentPlayer));
}
function endGame(msg) {
bannerEl.innerText = `🎉 ${msg}`;
bannerEl.classList.remove('hidden');
document.querySelectorAll('#board button').forEach(b => b.disabled = true);
panelQuestion.innerText = msg;
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
}
hintBtn.addEventListener('click', () => {
if (selectedCell !== null) panelHint.classList.toggle('hidden');
});
restartBtn.addEventListener('click', initGame);
initGame();
</script>
</body>
</html>