Классификация по фиксированному правилу

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

После Великой паники директор понял: старая система слишком сложная и ошибается. Он собрал данные за целую неделю (не только тот понедельник):

Странные слова? Избегает общения? Пришёл до 9:00? Оказался нечистью?
1 Да Да Да ✅ Да
2 Да Да Нет ✅ Да
3 Да Нет Да ❌ Нет
4 Да Нет Нет ❌ Нет
5 Нет Да Да ❌ Нет
6 Нет Да Нет ✅ Да
7 Нет Нет Да ❌ Нет
8 Нет Нет Нет ❌ Нет

Всего: 3 нечисти, 5 людей


Директор заметил: «Бледное лицо» больше не работает — зимой все бледные! Нужны новые признаки.

Ты получил задачу: Построй дерево глубины 2 и предскажи для новенького.
 

Новенький — Гриша:

  • Странные слова: ДА (переехал из Германии, вставляет немецкие слова)
  • Избегает общения: ДА (стесняется, ещё никого не знает)
  • Пришёл до 9:00: ДА (родители привезли пораньше)

Что предскажет оптимальное дерево глубины 2?

    1. Человек
    1. Нечисть
    1. 50/50 — дерево не может определить
    1. Нужен третий уровень дерева

После карантина школа Ларево установила систему для определения зомби:

              [Бледное лицо?]
               /           \
             Да            Нет
             /               \
      [Странная походка?]   НЕ ЗОМБИ
         /          \
       Да           Нет
       /              \
[Издаёт стоны?]    НЕ ЗОМБИ
    /       \
  Да        Нет
  /           \
ЗОМБИ      НЕ ЗОМБИ

Понедельник, 8:00. Костя всю ночь писал код. Приходит в школу:

  • Лицо бледное (не видел солнце 3 дня)
  • Походка странная (врезался в две стены)
  • Издаёт стоны («уууу....стены...кофеее....коодд»)

Система сработала и вызвала охрану! Костя хочет доказать, что он не зомби. Какой ОДИН признак ему проще всего изменить прямо сейчас, чтобы система изменила решение?

    1. Бледное лицо — умыться холодной водой
    1. Странная походка — выпить кофе и взбодриться
    1. Издаёт стоны — просто замолчать
    1. Любой из трёх сработает одинаково

Дерево отбора на олимпиаду по программированию:

              [Средний балл > 4.5?]
                /              \
              Да               Нет
              /                  \
     [Победил в прошлом году?]  НЕ ПУСТЯТ
          /           \
        Да            Нет
        /               \
    ПУСТЯТ        [Рекомендация учителя?]
                      /            \
                    Да             Нет
                    /                \
                ПУСТЯТ          НЕ ПУСТЯТ

Костя Багов: средний балл 4.2, но он трижды побеждал на олимпиадах, написал школьный сайт и учитель информатики его боготворит.

Пустят на олимпиаду?

    1. Пустят — он же гений!
    1. Не пустят
    1. Пустят вне конкурса
    1. Создаст свою олимпиаду

Нейросеть школы Ларево предсказывает, проспит ли Тимоха урок:

        [Урок до 10:00?]
         /           \
       Да            Нет
       /               \
   ПРОСПИТ         НЕ ПРОСПИТ

Сейчас урок информатики, начало в 8:30. Что предскажет модель?

    1. Проспит
    1. Не проспит
    1. Зависит от предмета
    1. Нужно проверить, выпил ли он кофе

Добро пожаловать в школу Ларево — место, где ученики строят ML-модели, чтобы предсказать, кого вызовут к доске, а учителя используют нейросети для распознавания тех, кто не сделал домашку.


🌟 ГЕРОИ ШКОЛЫ ЛАРЕВО:

  • Тимофей «Тимоха» Лапшин — засыпает на любом уроке за 3 минуты
  • Алиса Кактусова — рисует мемы в тетради вместо конспектов
  • Данил «Данон» Йогуртов — всегда голодный, ест на уроках
  • Вика Вайфайная — не может жить без телефона больше 5 минут
  • Костя Багов — гений программирования, но забывает надеть разные носки
  • Маша Мемасова — знает все тренды, но не знает, кто такой Пушкин

Готовы к викторине?
1. Да
2. Нет



---
Все имена и события выдуманы. Любые совпадения случайны (честно)
За ответ на этот вопрос тоже дают балл :)

ИИ-система школы Ларево научилась распознавать котов на фото (для важных научных целей):

            [Есть усы?]
            /         \
          Да          Нет
          /             \
    [Говорит «мяу»?]   НЕ КОТ
       /        \
     Да         Нет
     /            \
   КОТ        [Ловит мышей?]
                /        \
              Да         Нет
              /            \
            КОТ        НЕ КОТ

Ситуация: На перемене Вика нарисовала Тимохе усы маркером пока он спал. Тимоха проснулся, увидел себя в камере телефона и от неожиданности издал звук «мяяяу?!». В этот момент школьная система распознавания сфоткала его для пропуска.

Что выдаст система?

    1. Кот 🐱
    1. Не кот 👦
    1. Ошибка распознавания
    1. Тимофей Лапшин, 10-Б класс

Данные о том, выйдет ли человек на пробежку:

Дождь? Температура Выходной? Бегал?
1 Нет Тепло Да
2 Нет Тепло Нет
3 Нет Холодно Да
4 Нет Холодно Нет
5 Да Тепло Да
6 Да Тепло Нет
7 Да Холодно Да
8 Да Холодно Нет

Новый человек — Саша: Дождь=Нет, Температура=Холодно, Выходной=Нет.

Что предскажет дерево с оптимальным корнем?
 

  1. Побежит (100% уверенность)
  2. Не побежит (100% уверенность)
  3. Побежит (но есть неопределённость)
  4. Не побежит (но есть неопределённость)

Данные: кто пойдёт на школьную дискотеку?

Есть пара? Друзья идут? Домашка сделана? Пошёл?
1 Да Да Да
2 Да Да Нет
3 Да Нет Да
4 Да Нет Нет
5 Нет Да Да
6 Нет Да Нет
7 Нет Нет Да
8 Нет Нет Нет

Какой признак лучше поставить в корень?

    1. Есть пара
    1. Друзья идут
    1. Домашка сделана
    1. Все одинаково хороши

В школе Ларево пятничная мафия — священная традиция. Дерево предсказывает участие:

              [Пятница?]
              /        \
            Да          Нет
            /             \
     [Домашки много?]   НЕ ПРИДЁТ
        /        \
      Да         Нет
      /            \
[Мафия или домашка?] ПРИДЁТ
    /        \
 Мафия     Домашка
   /          \
ПРИДЁТ    НЕ ПРИДЁТ

Пять учеников в пятницу:

Ученик Много домашки? Выбор
Тимоха Да Мафия
Алиса Нет
Данон Да Домашка
Вика Да Мафия
Костя Нет

Сколько придут на мафию?

    1. 2
    1. 3
    1. 4
    1. 5

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

Начальная энтропия: 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]
Поделиться
Класснуть