October 26

Разбор задач отборочного тура НТО.Джуниор-2025: Технологии и Искусственный интеллект

Аналитика

Количество участников, с успешными решениями по двум попыткам

Задача №1. Что такое инференс?

Алгоритм определения Инференса

Первая попытка

Входные задачи:

  1. Определить площадь пожара в конкретном районе по спутниковым снимкам, которые модель уже видела.
  2. Смоделировать скорость распространения пожара при необычных погодных условиях, например, во время штормового ветра.
  3. Предсказать вероятность возгорания в новом районе, где данных почти нет, но есть похожие регионы.
  4. Отобразить  статистику по площади пожаров за прошлый год.

Решение:

1. Сначала отсеем задачу, где нейросеть не нужна.

Отобразить статистику по площади пожаров за прошлый год — это агрегирование уже имеющихся чисел (сумма, среднее, максимум). Не требует нейросети и инференса, это обычная аналитика.
Эту задачу НЕ включаем в рейтинг.

2. Инференс — применение уже обученной модели для предсказаний на новых данных (модель НЕ дообучаем). В нашем наборе остаются три задачи, где предполагается именно инференс.

3. Критерии сложности для нейросети.

  • Сходство данных с тем, на чём модель училась (чем ближе — тем проще).
  • Неопределённость/экстраполяция (новые регионы, экстремальная погода — сложнее).
  • Зависимость от внешних факторов (ветер, влажность, ландшафт и т. п.).
  • Цена ошибки и требуемая точность (косвенно отражают сложность).

4. Рейтинг задач (от самой простой к самой сложной) среди тех, что требуют инференса.

1) определить площадь пожара по спутниковым снимкам, которые модель уже видела. Почему проще: классическая сегментация изображений; распределение данных близко к тренировочному (модель «видела такие снимки»).

Риски: качество снимка, дым/облака, но в целом задача «в-домене» ( «в-домене» - в пределах распределения данных, на которых модель обучалась.

3) смоделировать скорость распространения пожара при штормовом ветре (необычные условия). Почему средняя сложность: модель сталкивается с редкими, но физически возможными событиями, где ее способность к экстраполяции ограничена риском недообучения на аномалиях.

Риски: модель, не видевшая достаточного количества примеров "штормового ветра", может давать физически нереалистичные прогнозы.

2) предсказать вероятность возгорания в новом районе, где данных почти нет, но есть похожие регионы. Почему самая сложная: нужно обобщать знания на близкий, но новый регион; перенос признаков по аналогии. Ей нужно догадаться, сравнивая с похожими регионами, и перенести знания из одних мест в другие. Это требует обобщения — умения понимать, что похоже, а что нет.

Риски:

  • Критическое несовпадение ключевых параметров нового района и обучающей выборки (тип почвы, влажность, уклон, антропогенные факторы).
  • Отсутствие подтвержденных данных о возгораниях именно в этом районе для валидации и тонкой настройки модели, что делает прогноз непроверяемым.

Задача №2. Фактчекинг текстов для постов

Первая попытка

Машинное обучение — это один из методов глубокого обучения.

Вердикт: ❌ Неверно.
Комментарий: Всё наоборот: глубокое обучение — это подмножество машинного обучения, а не наоборот.
Исправленный вариант: «Глубокое обучение — это один из методов машинного обучения».

Обучение с учителем — это когда у нас есть размеченные данные и правильные ответы для примеров.

Вердикт: ✅ Верно.
Комментарий: Определение точное и корректное.

Кластеризация — это метод обучения с учителем, потому что она делит объекты на группы.

Вердикт: ❌ Неверно.
Комментарий: Кластеризация относится к обучению без учителя, так как у нас нет заранее размеченных данных.
Исправленный вариант: «Кластеризация — это метод обучения без учителя, который группирует объекты по их сходству».

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

Вердикт: ✅ Верно.
Комментарий: Определение правильное, отражает суть обучения с подкреплением.

Глубокое обучение всегда использует только один скрытый слой в нейросети.

Вердикт: ❌ Неверно.
Комментарий: Глубокое обучение характеризуется множеством скрытых слоёв (обычно два и более), а не одним.
Исправленный вариант: «Глубокое обучение использует нейросети с несколькими скрытыми слоями».

Символьный искусственный интеллект опирается на базы правил и логику, а не на нейросети.

Вердикт: ✅ Верно.
Комментарий: Это правильное определение символьного ИИ.

Сильный искусственный интеллект — это система будущего, которая сможет решать абсолютно любые задачи так же эффективно, как человек.

Вердикт: ✅ Верно
Комментарий: Да, это правильное описание сильного ИИ, еще раз уточним, что на сегодняшний день такой ИИ ещё не создан.

Вторая попытка

1. Машинное обучение → (C) Совокупность алгоритмов, которые позволяют системе выявлять закономерности и делать прогнозы без явного программирования.

Почему: Машинное обучение (ML) — это семейство методов, которые позволяют системе извлекать закономерности из данных и делать предсказания/решения без жёсткого программирования правил.
Пример: модель прогнозирует спрос на электричество по истории потребления и погоде.

2. Обучение с учителем → (A) Обучение модели с помощью размеченных данных, где заранее известны правильные ответы.

Почему: В supervised learning у каждого обучающего примера есть метка (правильный ответ), по которой считается ошибка и настраиваются параметры модели.
Пример: классификация писем на «спам/не спам» по размеченной выборке.

3. Обучение без учителя → (G) Обучение моделей без заранее известных ответов, где цель — поиск закономерностей или группировка объектов.

Почему: В unsupervised learning нет заранее известных ответов; цель — открыть структуру данных: группы, факторы, аномалии.
Пример: кластеризация клиентов по поведению без меток «тип клиента».

4. Обучение с подкреплением → (B) Метод, в котором агент получает вознаграждения и штрафы, чтобы научиться действовать эффективнее.

Почему: В reinforcement learning агент взаимодействует со средой и получает вознаграждения/штрафы, максимизируя суммарную награду.
Пример: обучение робота ходить или алгоритма играть в игру по сигналу награды за успешные действия.

5. Глубокое обучение → (D) Использование нескольких скрытых слоёв в нейросетях для решения сложных задач.

Почему: Глубокое обучение — это модели (обычно нейросети) с несколькими скрытыми слоями, способные строить иерархические представления признаков.

Пример: свёрточная сеть с множеством скрытых слоёв для распознавания объектов на изображениях.

Важно: глубокое обучение — часть машинного обучения (ML ⊃ DL).

6. Символьный искусственный интеллект → (E) Подход, основанный на логике и наборах правил, без применения нейросетей.

Почему: Символьный искусственный интеллект опирается на логические выражения, правила, базы знаний, вывод; нейросети не обязательны.
Пример: экспертная система, выводящая диагноз по правилам «если–то».

7. Сильный искусственный интеллект → (F) Гипотетическая система, способная решать любые интеллектуальные задачи на уровне или выше уровня человека.

Почему: Сильный ИИ (strong AI/AGI) — гипотетическая система, решающая широкий класс интеллектуальных задач на уровне человека или выше; на практике пока не существует.
Пример: нет реальных систем; это целевой идеал в исследованиях.

Задача №3. Математика лесных пожаров: когда огонь становится опасным?

Первая попытка

Входные данные:

В течение первых 6 дней были зафиксированы следующие значения площади возгорания в га: 14,12,15,11,16,10

Задача:

  1. Предсказать площади пожаров на следующие 8 дней  (до 14-го дня).
  2. Вычислите прирост площади между соседними днями.
  3. Определите, когда пожар станет опасным. Пожар считается опасным, если прирост площади за один день превышает 6 га.

В ответе запишите значение площади пожаров в опасные дни за две недели

Решение:

Ответ: 17181920

Вторая попытка

Входные данные:

Задача:

  1. Восстановить пропущенные значения площадей на основе закономерности изменения данных.
  2. Вычислить прирост площади между соседними днями.
  3. Определить, в какие дни пожар становится опасным. Пожар считается опасным, если прирост площади за один день превышает 6 га.

В ответе запишите значения площади пожаров именно в те дни (за все две недели), когда наблюдается опасный рост.

Решение:

Ответ: 17181920

Задача №4. Сбор данных

Алгоритм решения:

  1. Определить набор и порядок колонок таблицы исходя из описания данных.
  2. Изучить веб-страницы с данными, определить количество страниц.
  3. Определить по каким полям (ключи) осуществляется соединение таблиц.
  4. Осуществить сбор данных по каждому сайту.
  5. Реализовать соединение таблиц по ключам.

Первая попытка

Пример рабочего промпта:

Дано 2 таблицы с сайтов: о пожарах - https://yupest2.pythonanywhere.com/fires_terrain/ (11 страниц) и об объектах инфраструктуры – https://yupest2.pythonanywhere.com/infrastructure_objects/ (3 страницы).

Нужно спарсить данные с этих сайтов из таблицы html, где названия колонок соответствуют названию заголовков таблицы.

Затем нужно добавить каждой записи о пожарах информацию об объектах инфраструктуры по полям LON_LAT и frname. Сделай простой код с базовым минимумом библиотек. Сохрани данные в 1 csv файл. В коде не обрабатывай исключения, код должен быть простым, кратким без лишних выводов.

Используем нейросеть, например DeepSeek для получения кода-парсера: https://chat.deepseek.com/share/kfologaq5k84ejd9zi

Тестируем данные и при необходимости, корректируем код.

Сбор данных: первая попытка
import requests
from bs4 import BeautifulSoup
import csv

# Функция для парсинга данных с пагинированных таблиц
def parse_table_data(url, pages):
    all_data = []
    
    for page in range(1, pages + 1):
        response = requests.get(f"{url}?page={page}")
        soup = BeautifulSoup(response.text, 'html.parser')
        table = soup.find('table')
        
        # Получаем заголовки
        if page == 1:
            headers = [th.text.strip() for th in table.find_all('th')]
        
        # Получаем данные
        for row in table.find_all('tr')[1:]:
            row_data = [td.text.strip() for td in row.find_all('td')]
            if row_data:
                all_data.append(row_data)
    
    return headers, all_data

# Парсим данные о пожарах (11 страниц)
fires_headers, fires_data = parse_table_data(
    "https://yupest2.pythonanywhere.com/fires_terrain/", 11
)
print('Данные о пожарах готовы')
# Парсим данные об объектах инфраструктуры (3 страницы)
infra_headers, infra_data = parse_table_data(
    "https://yupest2.pythonanywhere.com/infrastructure_objects/", 3
)
print('Данные об объектах готовы')
# Создаем словарь для быстрого поиска объектов инфраструктуры по LON_LAT и frname
infra_dict = {}
for row in infra_data:
    lon_lat = row[infra_headers.index('LON_LAT')]
    frname = row[infra_headers.index('frname')]
    key = (lon_lat, frname)
    infra_dict[key] = row[2:]

print('Объединяем данные')
combined_data = []
for fire_row in fires_data:
    lon_lat = fire_row[fires_headers.index('LON_LAT')]
    frname = fire_row[fires_headers.index('frname')]
    key = (lon_lat, frname)
    
    # Добавляем информацию об объектах инфраструктуры
    if key in infra_dict:
        combined_row = fire_row + infra_dict[key]
    else:
        combined_row = fire_row + [''] * len(infra_headers[2:])
    
    combined_data.append(combined_row)

# Создаем объединенные заголовки
combined_headers = fires_headers + infra_headers[2:]

print('Сохраняем в CSV файл')
with open('combined_data.csv', 'w', newline='', encoding='utf-8') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(combined_headers)
    writer.writerows(combined_data)

Вторая попытка

Задача может быть решена с помощью классических методов программирования. Для работы с данными может быть использована библиотека pandas, которая позволяет считывать данные, формировать таблицы, объединять их и сохранять в формат CSV.

import requests
import pandas as pd

def parse_data(url, page_count):
  
  df_list = []
  for i in range (1, page_count):
      data = pd.read_html(url.format(page = i), encoding='utf8')[0]
      df_list.append(data)
  
  print('Данные собраны')
  data = pd.concat(df_list)
  return data

data1 = parse_data('https://yupest2.pythonanywhere.com/fires_settlements/?page={page}', 11)
data2 = parse_data('https://yupest2.pythonanywhere.com/weather_data/?page={page}', 10)

#Объединяем две таблицы по двум колонкам
all_data = pd.merge(data1, data2, on=['LON_LAT', 'year', 'month'], how='left')
all_data.to_csv('fires_2.csv', index = False)

Либо можно обратиться к вайб-кодингу: https://chat.deepseek.com/share/ulzf1hmcp3bxp6i9y3

import pandas as pd
import requests
from io import StringIO

def read_html_tables(url_template, page_count):
    """
    Читает данные из HTML таблиц по заданному URL шаблону
    
    Args:
        url_template (str): Шаблон URL с плейсхолдером для page
        page_count (int): Общее количество страниц
    
    Returns:
        pd.DataFrame: Объединенная таблица со всеми данными
    """
    all_data = []
    
    for page in range(1, page_count + 1):
        # Форматируем URL с текущим номером страницы
        url = url_template.format(page=page)
        
        try:
            # Используем requests для контроля над кодировкой
            response = requests.get(url)
            response.encoding = 'utf-8'  # Устанавливаем кодировку UTF-8
            
            # Если UTF-8 не работает, пробуем определить кодировку автоматически
            if response.encoding.lower() != 'utf-8':
                response.encoding = response.apparent_encoding
            
            # Читаем таблицы из HTML с указанием кодировки
            tables = pd.read_html(StringIO(response.text), encoding='utf-8')
            
            # Альтернативный вариант: пробуем разные кодировки
            if not tables:
                # Пробуем Windows-1251 (кириллица)
                response.encoding = 'windows-1251'
                tables = pd.read_html(StringIO(response.text), encoding='windows-1251')
            
            # Предполагаем, что нужная таблица - первая на странице
            if tables:
                df = tables[0]
                all_data.append(df)
                print(f"Успешно загружена страница {page}/{page_count}")
            else:
                print(f"На странице {page} не найдено таблиц")
                
        except Exception as e:
            print(f"Ошибка при загрузке страницы {page}: {e}")
    
    # Объединяем все данные в один DataFrame
    if all_data:
        return pd.concat(all_data, ignore_index=True)
    else:
        return pd.DataFrame()

# Основная часть программы
if __name__ == "__main__":
    # URL шаблоны для двух сайтов (без page_count)
    fires_url_template = "https://yupest2.pythonanywhere.com/fires_settlements/?page={page}"
    weather_url_template = "https://yupest2.pythonanywhere.com/weather_data/?page={page}"
    
    # Собираем данные с первого сайта (10 страниц)
    print("Загрузка данных о пожарах и поселениях...")
    fires_data = read_html_tables(fires_url_template, 10)
    
    # Собираем данные со второго сайта (9 страниц)
    print("\nЗагрузка погодных данных...")
    weather_data = read_html_tables(weather_url_template, 9)
    
    # Проверяем, что данные успешно загружены
    if fires_data.empty or weather_data.empty:
        print("Ошибка: не удалось загрузить данные с одного из сайтов")
    else:
        print(f"\nЗагружено записей о пожарах: {len(fires_data)}")
        print(f"Загружено погодных записей: {len(weather_data)}")
        
        # Объединяем таблицы по ключам LON_LAT, year, month
        print("\nОбъединение таблиц...")
        merged_data = pd.merge(
            fires_data, 
            weather_data, 
            on=['LON_LAT', 'year', 'month'], 
            how='inner'
        )
        
        # Определяем требуемый порядок столбцов
        required_columns = [
            'ID', 'LON_LAT', 'frname', 'year', 'month', 'month_str', 
            'area_sum', 'count_fires', 'count_settlements', 'MO_population', 
            'dist_to_rivers', 'dist_to_railway', 'dist_to_settlements', 
            'slope', 'aspect', 'veg_category', '7_days_SUM_APCP', 'n', 
            '7_days_AVG_SOILW', '7_days_AVG_SOILT', '7_days_AVG_WIND_SPEED'
        ]
        
        # Проверяем наличие всех требуемых столбцов
        missing_columns = [col for col in required_columns if col not in merged_data.columns]
        if missing_columns:
            print(f"Предупреждение: отсутствуют столбцы: {missing_columns}")
        
        # Выбираем только существующие столбцы в нужном порядке
        final_columns = [col for col in required_columns if col in merged_data.columns]
        final_data = merged_data[final_columns]
        
        # Сохраняем в CSV файл с указанием кодировки
        output_filename = "merged_data.csv"
        final_data.to_csv(output_filename, index=False, encoding='utf-8')
        
        print(f"\nДанные успешно сохранены в файл: {output_filename}")
        print(f"Итоговое количество записей: {len(final_data)}")
        print(f"Столбцы в итоговой таблице: {list(final_data.columns)}")
        
        # Выводим пример данных для проверки кодировки
        print("\nПример данных (первые 3 строки):")
        print(final_data.head(3))

Задача №5. Анализ природных пожаров Байкальского региона

Алгоритм решения

  1. Загрузить данные на платформу Датавиз-конструктор.
  2. Определить исходя из вопроса: группировку (поле категории), метрику (числовое поле), агрегацию (AGG) и формат ответа (MAXMIN - наибольшее или наименьшее).
  3. Построить визуализацию, по группировкам, метрикам с использованием агрегации.
  4. Найти значение и категорию наименьшего или наибольшего значения.

Первая попытка

🔗 Ссылка на данные

  1. В каком году в среднем наблюдается пик числа пожаров? – 2011
Рисунок №1 к решению Задачи №5 - среднее число пожаров по годам

2. В каком месяце для типа растительности VEG была зафиксирована AGG дистанция до дороги?

2.2. Какое значение?

Требуется для выбранного типа растительности VEG и корректной агрегации AGG, подобрать наибольшее или наименьшее значение и определить его месяц.

AGG - максимальная

Рисунок №2 к решению Задачи №5 - AGG - максимальная

AGG - минимальная

Рисунок №3 к решению Задачи №5 - AGG - минимальная

AGG - наибольшая средняя или наименьшая средняя

Рисунок №4 к решению Задачи №5 - AGG - наибольшая средняя или наименьшая средняя

3. Чему равно MAXMIN значение AGG2 высоты по районам?

3.2. В каком районе?

Требуется построить диаграмму по районам и высотам с определенным типом агрегации и подобрать наибольшее или наименьшее значение.

MAXMIN - наибольшее/наименьшее

AGG2 - средней

Рисунок №5 к решению Задачи №5

AGG2 - минимальной

Рисунок №6 к решению Задачи №5

AGG2 - максимальной

Рисунок №7 к решению Задачи №5

Вторая попытка

🔗Ссылка на данные

  1. В каком месяце суммарная площадь, пройденная огнем, наибольшая? – май
В каком месяце суммарная площадь, пройденная огнем, наибольшая? – май

2. В каком году в месяце - MONTH была зафиксирована AGG влажность почвы?
2.2 Какое значение?

AGG - максимальная

AGG - минимальная

AGG - наибольшая средняя / наименьшая средняя

3. Чему равно MAXMIN значение AGG2 за неделю суммы осадков по районам.
3.2. В каком районе?

MAXMIN - наибольшее / наименьшее

AGG2 - среднего

AGG2 - минимума

AGG2 - максимума

Задача №6. Корреляционный анализ

С помощью платформы Датавиз-конструктор оценим взаимосвязь признаков и отметим “ценные”. Для этого постройте матрицу корреляции методом Пирсона с помощью вида диаграммы “Цветная таблица” на данных, которые вы собрали.

Отбор ценных признаков происходит по следующему алгоритму, где X - каждый признак из географических факторов, а Y - целевая переменная count_fires:
  • Целевая переменная (Y): Поле count_fires — количество пожаров, которое мы будем прогнозировать.
  • Признаки-предикторы: Включают только географические факторы (X): метеорологические факторы (температура, влажность, ветер, осадки), антропогенные факторы (население, дороги), топографические (высота, экспозиция) и факторы растительности.

❗️К географическим факторам не относятся: ID, LON_LAT, frname, year, month, month_str, area_sum, count_fires

Степени связи:

Разбор на примере первой попытки

📌Какие признаки в большей степени оказывают влияние на целевую переменную - count_fires? Отметьте ценные признаки, которые необходимо включить в модель при обучении.

Ценные признаки – count_roads, MO_population, 7_days_SUM_APCP, kpo, 7_days_AVG_TMP, dist_to_railway, dist_to_roads, elevation.

В ответ запишите значение корреляции для поля col с фильтром по месяцу  month и укажите степень взаимосвязи.

В примере показаны настройки визуализации и определения значения для поля 7_days_AVG_RH по месяцу - июнь:

Степень связи - отсутствует или очень слабая.

Задача №7. Формирование обучающей и тестовой выборок

y_all - без фильтров, все колонки скрыты, кроме count_fires:

X_test - скрыты колонки: ID, LON_LAT, month_str, count_fires, для года установлен фильтр “2024”.

X_train - те же колонки, но фильтр year <2024.

y_test - колонки скрыты как у y_all, но перед скрытием поля year - устанавливается фильтр 2024.

y_train - колонки скрыты как у y_all, но перед скрытием поля year - устанавливается фильтр < 2024.

💡 Данные сохраняются через кнопку «Энкодер» для преобразования строковых значений в числовые.

Итоговые файлы:

Задача №8. Расчет метрик

Используя графический конструктор нейросетей, возьмите данные по количеству пожаров y_all (y_true) и предсказание модели сторонних экспертов (y_pred), и посчитайте метрику MAE и отправьте нам точностью 3 знака после запятой.

Предсказанные значения сторонних экспертов и ответ:

Задача №9. Проектирование модели

  1. Используйте данные по количеству пожаров для проектирования сети - X_train - данные, на которых модель будет обучаться
  2. Постройте 3-ёх слойную полносвязную нейросеть, мы считаем, что она лучшим образом справиться с решением. В слоях должно быть 35, 10 и 1 нейрон соответственно, а функции активации используйте relu, relu и linear.
  3. Скомпилируйте модель.
  4. Сохраните и отправьте файл с описанием архитектуры в виде JSON.

Задача №10. Обучение модели

  1. Спроектированная модель содержит блоки: загрузки данных X_train, 3 слоя, блок компиляции.
  2. Далее требуется обучить модель - для этого используется блок Fit model с данными y_train.
  3. Для оценки точности полученной модели потребуются данные test.
  4. Сделайте предсказание на X_test с помощью блока Predict.
  5. Затем получите метрику точности MAE на основе предсказанных данных и y_test.
  6. Результат полученного решения должен быть меньше ответа к задаче №8. Если он больше, то потребуется экспериментировать с параметрами модели, слоев.
  7. Также потребуется получить предсказание на основе X_val - которые прикреплены к заданию. Для этого потребуется еще один блок Predict.