Машинное обучение

139 задачвместе с подтемами
Число у задачи — рейтинг сложности, слово рядом — насколько она трудна по сравнению с другими задачами такого же типа. Шкалы задач с ответом и задач с кодом между собой не сравниваются. Рядом — счётчики попыток: успешные, неуспешные.

Предсказываем, кто забудет сменку.

Начальная энтропия: 1.0 (половина забывает, половина нет)

Разделяем по признаку «Понедельник»:

  • Понедельник (8 человек): энтропия 0.0 (все забыли!)
  • Другой день (12 человек): энтропия 0.65

Чему равна информационная выгода?

    1. 0.21
    1. 0.39
    1. 0.61
    1. 1.0

Данные: кто нарисовал усы на портрете Пушкина?

Был на перемене в кабинете? Имеет маркер? Смеялся громче всех? Виновен?
1 Да Да Да
2 Да Да Нет
3 Да Нет Да
4 Да Нет Нет
5 Нет Да Да
6 Нет Да Нет
7 Нет Нет Да
8 Нет Нет Нет

Какой признак лучше всего разделяет виновных?

    1. Был в кабинете
    1. Имеет маркер
    1. Смеялся громче всех
    1. Нужны все три вместе

(вопрос с подвохом) 

Дерево учителя информатики:

                [Телефон на парте?]
                 /              \
               Да               Нет
               /                  \
      [Вика смотрит в него?]   НЕ КОНФИСКУЮТ
          /           \
        Да            Нет
        /               \
  КОНФИСКУЮТ     [Звук включён?]
                    /        \
                  Да         Нет
                  /            \
            КОНФИСКУЮТ    НЕ КОНФИСКУЮТ

Ситуация: телефон на парте, Вика смотрит в окно, но телефон вдруг играет «Never Gonna Give You Up».

Что случится?

    1. Не конфискуют — она же не смотрит!
    1. Конфискуют
    1. Учитель посмеётся и простит
    1. Рикролл защитит телефон

Дерево решает, будет ли Данон есть на уроке:

           [Прошло больше часа с завтрака?]
                  /                \
                Да                 Нет
                /                    \
        [Учитель строгий?]       НЕ БУДЕТ ЕСТЬ
           /          \
         Да           Нет
         /              \
    БУДЕТ ЕСТЬ      БУДЕТ ЕСТЬ
    (тихо)          (громко хрустя)

Что является ЛИСТОМ дерева?

    1. «Прошло больше часа с завтрака?»
    1. «Учитель строгий?»
    1. «БУДЕТ ЕСТЬ (тихо)»
    1. «Да» и «Нет»

У вас есть дерево для предсказания, понравится ли фильм:

                [Жанр = Ужасы?]
                /            \
              Да              Нет
              /                \
        НЕ ПОНРАВИТСЯ     [Есть супергерои?]
                            /           \
                          Да            Нет
                          /              \
                   ПОНРАВИТСЯ      [Длительность > 2ч?]
                                      /          \
                                    Да           Нет
                                    /             \
                              НЕ ПОНРАВИТСЯ   ПОНРАВИТСЯ

Маша идёт на фильм: комедия, без супергероев, длится 1.5 часа. Что предскажет дерево?

  1. Понравится
  2. Не понравится
  3. Невозможно определить
  4. Нужно больше данных

В деревьях решений для работы с непрерывными признаками нужно найти  оптимальный порог разделения.

Порог — это число, которое делит данные  на две части: значения ≤ порога идут влево, значения > порога — вправо.

 

Пример:

Значения:  [1, 3, 5, 7, 9]
Метки:     [0, 0, 1, 1, 1]

Если выбрать порог = 4:
- Левая часть (≤ 4): значения [1, 3], метки [0, 0]
- Правая часть (> 4): значения [5, 7, 9], метки [1, 1, 1]

Это хорошее разделение! Левая часть чистая, правая чистая.


Алгоритм поиска лучшего порога:

1. Отсортируй уникальные значения признака
2. Для каждой пары соседних уникальных значений:
   - Порог = среднее этих двух значений
   - Раздели данные по порогу
   - Посчитай информационную выгоду
3. Верни порог с максимальной выгодой

Реализуйте алгоритм поиска лучшего порога.


Формат входных данных
- Первая строка: N — количество элементов
- Вторая строка: N вещественных чисел — значения признака
- Третья строка: N целых чисел (0 или 1) — метки классов

Формат выходных данных
- Первая строка: оптимальный порог (вещественное число, 4 знака после запятой)
- Вторая строка: информационная выгода (вещественное число, 4 знака после запятой)

Теперь соберём все части вместе и создадим полноценное дерево решений!

Дерево решений — это алгоритм машинного обучения, который:
1. Находит лучший признак для разделения данных (по информационной выгоде)
2. Рекурсивно строит поддеревья для каждой части
3. Останавливается, когда данные "чистые" или достигнута максимальная глубина

Пример работы на данных OR (логическое ИЛИ):
X = [[0,0], [0,1], [1,0], [1,1]]
y = [0, 1, 1, 1]

Дерево может выглядеть так:
            [feature 0]
             /       \
        x[0]=0      x[0]=1
           /           \
      [feature 1]    лист(1)
       /      \
   лист(0)  лист(1)

Задача

Используйте класс TreeNode, реализованный в предыдущем задании.
Реализуйте класс DecisionTree с методами:

0.  __init__(self, max_depth=10)`
   Инициализирует дерево решений.
   
   Параметры:
   - max_depth: максимальная глубина дерева (по умолчанию 10)
   Что нужно сделать:
   - Сохранить max_depth как атрибут объекта
   - Создать атрибут self.root и установить его в None (корень дерева будет создан позже при вызове fit)

1. entropy(self, labels)
   Считает энтропию списка меток.
   H = -p₀·log₂(p₀) - p₁·log₂(p₁)
   Если список пустой, возвращает 0.
   Если p=0, соответствующее слагаемое = 0.

2. find_best_split(self, X, y)
   Находит лучший признак для разделения.
   - Для каждого признака считает информационную выгоду
   - Возвращает кортеж: (индекс_лучшего_признака, информационная_выгода)
   - Если все признаки дают нулевую выгоду, возвращает (0, 0)

3. build_tree(self, X, y, depth=0)
   Рекурсивно строит дерево. Возвращает TreeNode.
   
   Условия остановки (создать лист):
   - Все метки одинаковые → лист с этой меткой
   - Достигнута max_depth → лист с самым частым классом
   - Нет признаков (X пустой или X[0] пустой) → лист с самым частым классом
   - Лучшее разделение даёт нулевую выгоду → лист с самым частым классом
   
   Иначе:
   - Найти лучший признак
   - Разделить данные: левая часть где x[feature]=0, правая где x[feature]=1
   - Рекурсивно построить поддеревья
   - Вернуть TreeNode с feature_index и поддеревьями

4. fit(self, X, y) - берёт данные (примеры X и ответы y) и строит из них дерево решений, которое потом будет делать предсказания.

5. predict(self, X) - берёт новые данные и для каждого примера спрашивает у дерева: "Какой ответ?"
 

Класс TreeNode уже реализован в предыдущем задании. Скопируйте его здесь.
Примеры
Пример 1
X = [[0,0], [0,1], [1,0], [1,1]]
y = [0, 1, 1, 1]
tree = DecisionTree(max_depth=3)
tree.fit(X, y)
tree.predict(X)  # [0, 1, 1, 1]
Пример 2
X = [[0,0], [0,1], [1,0], [1,1]]
y = [0, 0, 0, 1]
tree = DecisionTree(max_depth=3)
tree.fit(X, y)
tree.predict(X)  # [0, 0, 0, 1]
Пример 3
X = [[0,0], [0,1], [1,0], [1,1]]
y = [1, 1, 1, 0]
tree = DecisionTree(max_depth=3)
tree.fit(X, y)
tree.predict(X)  # [1, 1, 1, 0]
Дан список меток (0 и 1) до разделения и два списка после разделения 
на левую и правую части. Вычисли информационную выгоду.

Формат входных данных
- Первая строка: N — количество элементов до разделения
- Вторая строка: N чисел (0 или 1) — метки до разделения
- Третья строка: L — количество элементов в левой части
- Четвёртая строка: L чисел (0 или 1) — метки левой части
- Пятая строка: R — количество элементов в правой части
- Шестая строка: R чисел (0 или 1) — метки правой части

Гарантируется, что L + R = N и L, R > 0.

Формат выходных данных
Одно число — информационная выгода, округлённое до 4 знаков после запятой.
На какой вопрос отвечает метрика Precision?
  1. Сколько положительных объектов мы нашли из всех?  
  2. Когда модель говорит "да", как часто она права?  
  3. Сколько всего правильных ответов?  
  4. Сколько ошибок первого рода мы допустили?
Что измеряет метрика Accuracy?
  1. Процент правильных предсказаний класса 1  
  2. Процент правильных предсказаний от всех предсказаний  
  3. Процент найденных положительных объектов  
  4. Точность положительных предсказаний
Поделиться
Класснуть