// Дані про робочий процес науки про дані const workflowData = { "title": "Робочий процес науки про дані", "introduction": "Кожен проект з науки про дані включає кілька важливих етапів. Ця інтерактивна панель допоможе вам зрозуміти кожен етап робочого процесу та його важливість.", "steps": [ { "id": 1, "title": "Формулювання проблеми", "shortTitle": "Проблема", "description": "Кожен проект з науки про дані починається з визначення проблеми. Незалежно від того, чи це прогнозування результатів пацієнтів або оптимізація бізнес-операцій, переклад реальної проблеми у питання, що базується на даних, є вирішальним.", "keyPoints": [ "Визначення конкретної проблеми, яку потрібно вирішити", "Формулювання питань, на які потрібно відповісти за допомогою даних", "Вибір підходу до вирішення (машинне навчання, статистичний аналіз тощо)" ], "example": "У галузі охорони здоров'я, прогнозування часу відновлення пацієнта на основі медичної історії. Формулювання проблеми: лікарям потрібен інструмент для прогнозування тривалості відновлення пацієнта після лікування.", "tips": [ "Завжди консультуйтеся з експертами в предметній області", "Переконайтеся, що проблема може бути вирішена за допомогою даних", "Визначте чіткі критерії успіху" ], "quiz": [ { "question": "Що є першим кроком у проекті науки про дані?", "options": [ "Збір даних", "Визначення проблеми", "Побудова моделі", "Оцінка результатів" ], "answer": 1 } ] }, { "id": 2, "title": "Збір даних", "shortTitle": "Дані", "description": "Наступним кроком є збір відповідних даних з надійних джерел. Це може включати бази даних, публічні набори даних або дані, зібрані через сенсори та додатки.", "keyPoints": [ "Визначення потрібних даних для вирішення проблеми", "Ідентифікація джерел даних", "Розуміння регуляторних вимог та етичних міркувань" ], "example": "Збір клінічних записів з баз даних охорони здоров'я для аналізу часу відновлення пацієнтів.", "tips": [ "Переконайтеся, що ви маєте дозвіл на використання даних", "Перевірте якість та надійність джерел даних", "Зберігайте дані безпечно та відповідно до норм" ], "quiz": [ { "question": "Що Ендрю Нг назвав 'їжею для ШІ'?", "options": [ "Алгоритми", "Дані", "Обчислювальні потужності", "Програмний код" ], "answer": 1 } ] }, { "id": 3, "title": "Підготовка даних", "shortTitle": "Підготовка", "description": "Сирі дані часто містять невідповідності, відсутні значення або викиди. Підготовка даних забезпечує, що дані чисті та стандартизовані.", "keyPoints": [ "Очищення даних від невідповідностей", "Обробка відсутніх значень", "Нормалізація та стандартизація даних" ], "example": "Очищення клінічних даних для забезпечення послідовності в аналізі.", "tips": [ "Документуйте всі зміни, внесені до вихідних даних", "Використовуйте автоматизовані інструменти для очищення великих наборів даних", "Перевірте дані після очищення, щоб переконатися, що вони все ще відображають реальність" ], "quiz": [ { "question": "Які проблеми вирішує етап підготовки даних?", "options": [ "Невідповідності, відсутні значення, викиди", "Формулювання проблеми та вибір алгоритму", "Вибір метрик оцінки", "Розгортання моделі в виробництво" ], "answer": 0 } ] }, { "id": 4, "title": "Моделювання", "shortTitle": "Модель", "description": "Вибір правильного алгоритму є критичним. В залежності від проблеми, ми можемо використовувати регресію, класифікацію або кластеризацію, тощо.", "keyPoints": [ "Вибір алгоритму на основі типу проблеми", "Оцінка доступних даних (кількість та якість)", "Врахування обчислювальних ресурсів та часу навчання" ], "example": "Вибір алгоритму машинного навчання для прогнозування часу відновлення пацієнта на основі історичних даних.", "tips": [ "Почніть з простих моделей перед переходом до складніших", "Розділіть дані на тренувальні та тестові набори", "Експериментуйте з різними алгоритмами для порівняння результатів" ], "quiz": [ { "question": "Які фактори слід враховувати при виборі алгоритму?", "options": [ "Тільки тип проблеми", "Тільки обчислювальні ресурси", "Тип проблеми, доступні дані та обчислювальні ресурси", "Тільки розмір набору даних" ], "answer": 2 } ] }, { "id": 5, "title": "Оцінювання", "shortTitle": "Оцінка", "description": "Після навчання, оцінка моделі є важливою для забезпечення точності та надійності.", "keyPoints": [ "Вибір відповідних метрик для оцінки моделі", "Порівняння результатів з бізнес-цілями", "Виявлення областей для покращення" ], "example": "Оцінка моделі для виявлення ранніх симптомів захворювання за допомогою метрик точності, чутливості та специфічності.", "tips": [ "Використовуйте метрики, що відповідають бізнес-цілям", "Проведіть крос-валідацію для надійності оцінки", "Порівняйте результати з базовими моделями" ], "quiz": [ { "question": "Які метрики можуть використовуватися для оцінки моделі?", "options": [ "Тільки точність (accuracy)", "Точність, повнота, F1-оцінка та інші", "Тільки час навчання", "Тільки розмір моделі" ], "answer": 1 } ] }, { "id": 6, "title": "Розгортання", "shortTitle": "Розгортання", "description": "Розгортання — це процес інтеграції навченої моделі в виробниче середовище, роблячи її доступною для реального використання. Цей крок є вирішальним для забезпечення того, щоб прогнози моделі були постійно доступні та надійні для кінцевих користувачів або автоматизованих систем.", "keyPoints": [ "Контейнеризація моделі для портативності", "Створення API для доступу до моделі", "Налаштування безперервної інтеграції та доставки (CI/CD)", "Забезпечення масштабованості та доступності" ], "example": "Розгортання моделі прогнозування часу відновлення пацієнта в хмарній платформі (AWS, Azure) та інтеграція з системою електронних медичних карт через API.", "tips": [ "Тестуйте модель в середовищі, подібному до виробничого", "Впровадіть моніторинг для відстеження продуктивності", "Плануйте для масштабування від початку" ], "quiz": [ { "question": "Що таке контейнеризація в контексті розгортання моделі?", "options": [ "Упаковка моделі в фізичний контейнер для транспортування", "Упаковка моделі, залежностей і середовища в програмний контейнер (як Docker)", "Обмеження доступу до моделі", "Зменшення розміру моделі" ], "answer": 1 } ] }, { "id": 7, "title": "Моніторинг та підтримка", "shortTitle": "Моніторинг", "description": "Моделі потребують постійного моніторингу, щоб залишатися точними та ефективними. Зміни в розподілі даних можуть погіршити продуктивність з часом.", "keyPoints": [ "Відстеження продуктивності моделі в реальному часі", "Виявлення зміщення даних (data drift)", "Регулярне перенавчання моделі з новими даними", "Автоматизація розгортання оновлених моделей" ], "example": "Використання інструментів моніторингу, таких як Prometheus і Grafana, для відстеження точності моделі прогнозування часу відновлення пацієнта та виявлення будь-яких змін у розподілі даних.", "tips": [ "Встановіть сповіщення для виявлення зниження продуктивності", "Плануйте регулярні огляди моделі", "Документуйте всі зміни та оновлення" ], "quiz": [ { "question": "Чому важливий моніторинг моделі після розгортання?", "options": [ "Він не важливий, якщо модель добре навчена", "Тільки для задоволення регуляторних вимог", "Для виявлення зміщення даних та підтримки продуктивності моделі", "Тільки для економії обчислювальних ресурсів" ], "answer": 2 } ] } ] }; // Глобальні змінні стану let currentStepId = null; let visitedSteps = new Set(); let selectedQuizOption = null; let quizAnswered = false; // Іконки для етапів const stepIcons = { 1: '❓', 2: '📊', 3: '🔧', 4: '🤖', 5: '📈', 6: '🚀', 7: '👁️' }; // Ініціалізація додатка document.addEventListener('DOMContentLoaded', function() { initializeApp(); setupEventListeners(); }); function initializeApp() { // Встановлення заголовку та вступу document.getElementById('introText').textContent = workflowData.introduction; // Рендер бічної панелі renderSidebar(); // Рендер візуалізації робочого процесу renderWorkflowDiagram(); // Оновлення прогресу updateProgress(); // Приховати деталі етапу спочатку document.getElementById('stepDetailsSection').classList.remove('active'); } function setupEventListeners() { // Кнопки навігації document.getElementById('nextStepBtn').addEventListener('click', () => navigateStep(1)); document.getElementById('prevStepBtn').addEventListener('click', () => navigateStep(-1)); // Кнопка скидання прогресу document.getElementById('resetProgressBtn').addEventListener('click', resetProgress); // Кнопка перевірки відповіді document.getElementById('checkAnswerBtn').addEventListener('click', checkQuizAnswer); } function renderSidebar() { const sidebarList = document.getElementById('sidebarStepsList'); sidebarList.innerHTML = ''; workflowData.steps.forEach(step => { const listItem = document.createElement('li'); const link = document.createElement('a'); link.href = '#'; link.className = 'step-link'; link.dataset.stepId = step.id; const stepNumber = document.createElement('span'); stepNumber.className = 'step-number'; stepNumber.textContent = step.id; const stepTitle = document.createElement('span'); stepTitle.textContent = step.shortTitle; link.appendChild(stepNumber); link.appendChild(stepTitle); link.addEventListener('click', (e) => { e.preventDefault(); showStepDetails(step.id); }); listItem.appendChild(link); sidebarList.appendChild(listItem); }); } function renderWorkflowDiagram() { const diagram = document.getElementById('workflowDiagram'); diagram.innerHTML = ''; workflowData.steps.forEach(step => { const stepElement = document.createElement('div'); stepElement.className = 'workflow-step'; stepElement.dataset.stepId = step.id; const icon = document.createElement('div'); icon.className = 'step-icon'; icon.textContent = stepIcons[step.id] || '⚡'; const title = document.createElement('h3'); title.textContent = step.shortTitle; stepElement.appendChild(icon); stepElement.appendChild(title); stepElement.addEventListener('click', () => { showStepDetails(step.id); }); diagram.appendChild(stepElement); }); } function showStepDetails(stepId) { const step = workflowData.steps.find(s => s.id === stepId); if (!step) return; currentStepId = stepId; visitedSteps.add(stepId); // Оновити активний стан updateActiveStates(); // Заповнити деталі етапу document.getElementById('stepTitle').textContent = step.title; document.getElementById('stepDescription').textContent = step.description; // Ключові моменти const keyPointsList = document.getElementById('stepKeyPoints'); keyPointsList.innerHTML = ''; step.keyPoints.forEach(point => { const li = document.createElement('li'); li.textContent = point; keyPointsList.appendChild(li); }); // Приклад document.getElementById('stepExample').textContent = step.example; // Поради const tipsList = document.getElementById('stepTips'); tipsList.innerHTML = ''; step.tips.forEach(tip => { const li = document.createElement('li'); li.textContent = tip; tipsList.appendChild(li); }); // Вікторина setupQuiz(step.quiz[0]); // Показати панель деталей document.getElementById('introSection').style.display = 'none'; document.getElementById('stepDetailsSection').classList.add('active'); // Оновити кнопки навігації updateNavigationButtons(); // Оновити прогрес updateProgress(); // Прокрутити до верху document.getElementById('stepDetailsSection').scrollIntoView({ behavior: 'smooth' }); } function updateActiveStates() { // Оновити бічну панель document.querySelectorAll('.step-link').forEach(link => { const stepId = parseInt(link.dataset.stepId); link.classList.remove('active'); if (visitedSteps.has(stepId)) { link.classList.add('visited'); } if (stepId === currentStepId) { link.classList.add('active'); } }); // Оновити діаграму document.querySelectorAll('.workflow-step').forEach(step => { const stepId = parseInt(step.dataset.stepId); step.classList.remove('active'); if (visitedSteps.has(stepId)) { step.classList.add('visited'); } if (stepId === currentStepId) { step.classList.add('active'); } }); } function setupQuiz(quiz) { document.getElementById('quizQuestion').textContent = quiz.question; const optionsContainer = document.getElementById('quizOptions'); optionsContainer.innerHTML = ''; quiz.options.forEach((option, index) => { const optionElement = document.createElement('div'); optionElement.className = 'quiz-option'; optionElement.textContent = option; optionElement.dataset.index = index; optionElement.addEventListener('click', () => { if (quizAnswered) return; document.querySelectorAll('.quiz-option').forEach(opt => { opt.classList.remove('selected'); }); optionElement.classList.add('selected'); selectedQuizOption = index; }); optionsContainer.appendChild(optionElement); }); // Скинути стан вікторини selectedQuizOption = null; quizAnswered = false; document.getElementById('quizResult').classList.remove('show', 'correct', 'incorrect'); document.getElementById('checkAnswerBtn').style.display = 'block'; } function checkQuizAnswer() { if (selectedQuizOption === null) { alert('Будь ласка, оберіть відповідь'); return; } const step = workflowData.steps.find(s => s.id === currentStepId); const quiz = step.quiz[0]; const isCorrect = selectedQuizOption === quiz.answer; // Показати результат const resultElement = document.getElementById('quizResult'); resultElement.classList.add('show'); if (isCorrect) { resultElement.classList.add('correct'); resultElement.textContent = '✅ Правильно! Відмінна робота!'; } else { resultElement.classList.add('incorrect'); resultElement.textContent = `❌ Неправильно. Правильна відповідь: ${quiz.options[quiz.answer]}`; } // Підсвітити правильну та неправильну відповіді document.querySelectorAll('.quiz-option').forEach((option, index) => { if (index === quiz.answer) { option.classList.add('correct'); } else if (index === selectedQuizOption && !isCorrect) { option.classList.add('incorrect'); } }); quizAnswered = true; document.getElementById('checkAnswerBtn').style.display = 'none'; } function navigateStep(direction) { if (!currentStepId) return; const currentIndex = workflowData.steps.findIndex(s => s.id === currentStepId); const newIndex = currentIndex + direction; if (newIndex >= 0 && newIndex < workflowData.steps.length) { showStepDetails(workflowData.steps[newIndex].id); } } function updateNavigationButtons() { const currentIndex = workflowData.steps.findIndex(s => s.id === currentStepId); document.getElementById('prevStepBtn').disabled = currentIndex === 0; document.getElementById('nextStepBtn').disabled = currentIndex === workflowData.steps.length - 1; } function updateProgress() { const totalSteps = workflowData.steps.length; const completedSteps = visitedSteps.size; const percentage = (completedSteps / totalSteps) * 100; document.getElementById('progressFill').style.width = `${percentage}%`; document.getElementById('progressText').textContent = `${completedSteps}/${totalSteps} етапів вивчено`; } function resetProgress() { if (confirm('Ви впевнені, що хочете скинути свій прогрес?')) { visitedSteps.clear(); currentStepId = null; // Приховати деталі етапу та показати вступ document.getElementById('stepDetailsSection').classList.remove('active'); document.getElementById('introSection').style.display = 'block'; // Оновити стани updateActiveStates(); updateProgress(); // Прокрутити до верху window.scrollTo({ top: 0, behavior: 'smooth' }); } }