Download app.js from alexdatamed/Lecture2_DataScienceWorkflow: direct link, hf CLI and curl.
- Browser
- Download file 23.3 kB
-
https://huggingface.co/spaces/alexdatamed/Lecture2_DataScienceWorkflow/resolve/main/app.js
- Command line
-
hf download hf://spaces/alexdatamed/Lecture2_DataScienceWorkflow/app.js
-
curl -L -o app.js https://huggingface.co/spaces/alexdatamed/Lecture2_DataScienceWorkflow/resolve/main/app.js
23.3 kB
| // Дані про робочий процес науки про дані | |
| 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' }); | |
| } | |
| } |