File size: 23,277 Bytes
2bd6c65
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
2bd6c65
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
3dd786e
2bd6c65
 
3dd786e
 
2bd6c65
 
 
3dd786e
2bd6c65
 
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
 
3dd786e
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ad38c8
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
4ad38c8
2bd6c65
 
 
 
 
 
 
 
3dd786e
2bd6c65
 
3dd786e
2bd6c65
 
 
3dd786e
2bd6c65
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ad38c8
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
4ad38c8
2bd6c65
 
 
 
 
 
 
 
 
 
 
4ad38c8
3dd786e
2bd6c65
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
4ad38c8
3dd786e
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ad38c8
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
 
2bd6c65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dd786e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
// Дані про робочий процес науки про дані
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' });
  }
}