Думаю, осталось не так уж много людей, которые не слышали о хакатонах и конкурсах по Data Science. Я услышал о них полгода назад. Приняв участие во всем, что я видел (и даже что-то выиграл), я не смог пройти мимо АгроКода 2020, организованного Россельхозбанком.
Мне удалось попасть в топ лучших участников по нескольким направлениям и даже занять призовое место по одному.
Благодаря этим достижениям я стал специалистом по Data Science в Центре развития финансовых технологий Россельхозбанка.
А как это получилось у меня – читайте ниже.
Основная сельскохозяйственная кодировка страны
Для начала скажу несколько слов о самом мероприятии.AgroCode 2020 собрал множество людей, увлеченных новыми технологиями в сельском хозяйстве.
Оно состояло из нескольких мероприятий:
- Соревнования по анализу данных Agro Data Science Cup с 2 заданиями:
- идентификация сельскохозяйственной культуры на основе суточных значений нормированного вегетационного индекса
- Определение дефектов плодов лимона по фотографиям.
- Хакатон Agro Hack с 6 кейсами из аграрной отрасли:
- создание рекомендательного сервиса по размещению культур на сельскохозяйственных полях
- выбор оптимального поставщика удобрений
- выявление водно-болотных угодий и заболоченных участков сельскохозяйственных угодий
- создание нейросети для выявления болезней листьев яблони по фотографиям
- разработка полетного задания группы сельскохозяйственных дронов
- разработка приложения для увеличения урожайности космической клубники.
Для участия в хакатоне подавшие заявки команды должны были пройти отбор.
В итоге за призовые места боролись по 10 команд по каждому делу.
- Конкурс «Агроидеи», который должен помочь решить проблемы фермеров и аграрной отрасли.
Участие в хакатоне не принесло нам никаких призов, хотя, как мне кажется, решение оказалось интересным.
Об этом я кратко расскажу в конце статьи.
Конкурс DS оказался гораздо успешнее.
В задаче с лимонами нам удалось попасть в топ-10, а в задаче с индексом растительности мы заняли 2 место!
Проблема индекса растительности
Эта задача требовала идентификации культуры на основе суточных значений нормированного вегетационного индекса.Данные для него были собраны из 17 регионов РФ, преимущественно европейской части России.
Какие данные?
Данные выглядели чрезвычайно просто и понятно: год, идентификатор поля, площадь поля, название культуры (закодированное в числовом представлении) и данные индекса вегетации за каждый из 365 дней.
Датасет для задачи про индекс растительности
Метрики
Для оценки качества прогноза организаторы конкурса выбрали из библиотеки sklearn взвешенную F1-показатель (с параметром Average="weighted").Этот показатель важен для понимания того, как добиться максимальной скорости.
Для этой задачи я сделал вывод: нужно допускать как можно меньше ошибок в наиболее распространенных классах, так как они сильно влияют на метрику.
Это следует учитывать на этапе создания модели.
Индекс растительности? Что это?
Индекс растительности или, как говорят умные люди, NDVI – это довольно простой коэффициент.Для его расчета нам нужны спутниковые снимки, содержащие 4 канала: классический RGB и канал инфракрасного спектра.
Соответственно, в формуле RED — красный канал, а NIR — инфракрасный спектр.
Изображение поля с рассчитанным ndvi
Какие особенности я увидел в этих данных?
- Во-первых, наблюдается волатильность в начале года примерно до 45-го дня и отсутствие значений индекса, начиная с 279-го дня.
Это можно объяснить довольно просто: в начале года большая часть полей покрыта снегом и из-за при этом индекс принимает аномальные значения; в конце года (предположительно) данные собираются не так активно, так как период сбора урожая уже закончился.
- Во-вторых, в течение года индекс может испытывать чрезмерные колебания, возникающие из-за высокой облачности (хорошая идея для аналитиков этой отрасли — учитывать облачность при расчете индекса).
Я справился с этой проблемой путем сглаживания временных рядов и эвристических констант, но эти методы только ухудшили модель.
- В-третьих, классы крайне несбалансированы.
Очевидно, что пшеницы сажают гораздо больше, чем овса.
Эту проблему я решил уже на этапе создания и обучения модели.
Создание новых функций
Вполне логичное решение для получения лучших значений метрик — создание функций.Тогда я вспомнил об одном из моих любимых, который часто помогает в решении задач, связанных с физическими или химическими процессами.
Эта скорость является одной из важнейших характеристик процесса, которую легко получить, вычитая значение предыдущего дня из значения текущего дня.
Для значений индекса по дням и скорости изменения индекса я добавил значения среднего, суммы и квантиля.
Но это еще не все.
Раз уж мы говорим об индексе вегетации, то можно придумать и особенности, имеющие непосредственное отношение к растениям.
Так появляется количество дней и сумма значений индекса, в которых индекс превышал каждый из квантилей.
То же самое со скоростями.
Я также пытался удалить или оставить идентификатор, площадь поля и год. В результате эффективным был только атрибут области.
И на последок я взял значения индекса и скорости с определённым периодом.
Я протестировал параметры периода в цикле и посмотрел на метрику для проверки.
Лучшими оказались два варианта: брать ежедневные значения индекса и значения скорости с периодом 2 и 4 дня.
А как насчет дисбаланса?
Распределение культур в обучающих данных В данных есть классы, которые различаются количеством выборок на порядки.
По этой причине обычный KFold или StratifiedKFold не подойдет, так как некоторые сэмплы все равно будут потеряны.
Поэтому я написал довольно простую функцию выборки.
Для каждой цели случайным образом создается набор данных, которые объединяются.
Данные, которые не были включены в обучающий набор, проходят проверку.
Таким образом, я гарантировал, что все культуры присутствовали на каждой итерации перекрестной проверки.
А дальше дело за настройкой и обучением модели.
Модель
Как и положено для таких соревнований, я использовал градиентное повышение, взяв классификатор из моей любимой библиотеки CatBoost. И, естественно, обычным поиском я подобрал оптимальные параметры, остановившись на следующем варианте:Важными настройками модели были веса для классов с параметром «Сбалансированный» и функцией потерь «MultiClassOneVsAll».params = { 'iterations': 2000, 'depth': 6, 'early_stopping_rounds': 500, 'l2_leaf_reg': 5, 'bagging_temperature': 1, 'random_seed': 17, 'class_names': classes, 'auto_class_weights': 'Balanced', 'eval_metric': 'TotalF1', 'loss_function': 'MultiClassOneVsAll', 'task_type': 'GPU', 'devices': '0:1', 'verbose': 2000 }
Эти настройки обеспечивают дополнительную поддержку в борьбе с дисбалансом данных.
Остается только тренироваться и получать прогнозы.
Сначала запускается цикл, в котором я меняю параметры набора данных, затем цикл, в котором изменяется random_seed для получения разных выборок набора данных.
Далее идет обучение и получение предиктора.
Прогнозы брались только из тех моделей, которые при валидации показали высокую скорость, затем суммировались и нормировались.
Если вы посмотрите на распределение культур для предсказаний, то увидите, что в предсказаниях присутствуют почти все культуры.
Прогнозируемое распределение сельскохозяйственных культур в тестовых данных
Результат
Результатом работы алгоритма стало 18-е место в публичной таблице лидеров.Было довольно грустно наблюдать за этой картиной несколько дней, зная, что валидация набирает адекватную скорость.
Но когда появились результаты тестирования по приватной части, я вдруг переместился с 18-го на 2-е место.
Отставание от первого места крайне незначительное, а вот от третьего места существенное.
Именно поэтому валидация – чуть ли не самое главное в таких соревнованиях.
Итоговая таблица лидеров первого задания
Проблема с лимонами
Второе задание было гораздо сложнее: организаторы решили не раздавать призы просто так и ввели некоторые технические ограничения для задания.К тому же мне немного не хватало опыта работы с изображениями.
Однако, собрав все возможные статьи с Хабра, Kaggle и Medium, я решил попробовать решить эту проблему.
Основной темой были вот такие лимоны (как на картинке).
Целью было определить вероятность присутствия на изображении того или иного дефекта.
Какой лимон вы выберете?
Немного о данных
Данные представляют собой набор изображений и аннотаций к ним.Изображения представляют собой цветные изображения лимонов размером 1056 x 1056 пикселей в формате .
jpg. Лимоны на картинках показаны с разных ракурсов и в разных условиях освещения.
Аннотации содержат названия категорий, категории дефектов для каждого изображения, полигоны участков с дефектами и т. д. Аннотации доступны только для обучающей выборки.
А вот ссылка на набор данных: https://www.kaggle.com/maciejadamiak/lemons-quality-controldataset
Метрики
В этой задаче метрикой является стандартная ROC-AUC. Для расчета используется следующий код: def score(y_true, y_preds):
table = y_true.merge(y_preds, left_on='image_id', right_on='image_id')
m = keras.metrics.AUC(curve='ROC')
m.update_state(table.iloc[:, 1:10], table.iloc[:, 10:])
return m.result().
numpy()
Сложности
Организаторы довольно усложнили задачу в два этапа.Это не был конкурс CSV-файлов.
Нужно было отправить только .
py-файл с кодом, который работает в Docker-контейнере.
В этом случае пришлось выполнять не только прогнозирование ответов, но и обучение модели.
Более того, в контейнере нет интернета, что порождает запрет на использование предварительно обученных весов для моделей.
Но на этом организаторы не остановились и установили ограничение на время выполнения присылаемого кода всего в 20 минут. Теперь помните, что вам нужно обучать модель в контейнере.
Ты боишься? Я почувствовал это.
Исходя из ограничений, стало понятно, что тяжелую модель, тренирувшуюся несколько часов, использовать нельзя.
К тому же, после долгого решения первой задачи конкурса, времени на эту осталось совсем мало.
Решив не изобретать велосипед, я использовал исходные данные, предоставленные организаторами, и переписал процессы предварительной обработки, модели, обучения и прогнозирования.
Предварительная обработка данных
Самым классическим решением предварительной обработки изображений является аугментация.Я использовал изменения яркости, различные вращения и сдвиги.
aug = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.1,
height_shift_range=0.1,
brightness_range=[0.5, 1],
shear_range=0.2,
channel_shift_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
vertical_flip=True,
fill_mode="nearest"
)
Что за нейрон?
Я собрал достаточно классическую модель, которая всегда дает хорошие результаты.
За основу был взят VGG16, за ним последовали AveragePooling, полносвязный слой (Dense) и Dropout. model = VGG16(weights=None, include_top=False, input_shape=[image_size, image_size, 3])
x = AveragePooling2D(pool_size=(2, 2))(model.output)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
output = Dense(9, activation='sigmoid')(x)
Конечно, модель можно улучшать и улучшать, изменяя и добавляя слои или пробуя разные магистрали.
Для обучения я использовал перекрестную проверку KFold. Для меня это спорное решение, так как на обучение модели уходит больше времени, а проверить больше вариантов у меня просто не было времени.
Результат
Несмотря на относительно простое решение и отсутствие времени на его усовершенствование, мне удалось завершить соревнование на 9-м месте, что я считаю еще одним небольшим достижением.
Итоговая таблица лидеров для второго задания
А теперь о хакатоне
Сразу после окончания соревнований по анализу данных начался хакатон.Наша команда называется «Московские зайцы» и нас часто можно встретить на других подобных мероприятиях.
Задание выбиралось исходя из того, что могло получиться и на что у нас уже были идеи.
Так мы пришли к проблеме оптимизации выращивания марсианской клубники.
Фото с нашей презентации
О задаче
Перед задачей организаторы поставили следующие цели:- Нам необходимо создать прототип приложения, которое поможет более эффективно выращивать марсианскую клубнику, используя собранные данные.
- Приложение должно помочь реагировать на аномалии данных — неблагоприятные условия роста и сбои датчиков.
- На основе предоставленных данных необходимо найти оптимальные режимы выращивания марсианской клубники (режимы полива, температуры, влажности, освещения и т. д.).
Нам были предоставлены данные за 3 года по каждой из теплиц.
За каждый год урожайность дается в условных единицах.
Датасет с показаниями датчиков Датасет с показателями урожайности
Набор данных с показаниями датчиков
Набор данных со значениями доходности
Наше решение
Мы сразу разделили задачу на две части: анализ данных и создание веб-приложения.Для решения первой задачи я проанализировал все показатели теплицы, чтобы выявить оптимальные, и сравнил их с тем, что советуют садоводы в Интернете.
Если вы планируете выращивать клубнику, возможно, вам стоит принять к сведению мои выводы:
- Наибольший урожай достигался, если температура в большинстве случаев составляла от 19 до 30 градусов, а средняя температура колебалась от 23 до 25 градусов.
Эти данные соответствуют общепринятым температурам выращивания клубники.
- Наибольшая урожайность была достигнута также при пониженной влажности почвы.
Это снова согласуется с практикой выращивания клубники, которая сокращает полив во время созревания, чтобы получить лучший урожай.
- Клубника – светолюбивое растение.
Неудивительно, что высокие урожаи были достигнуты в сочетании с большим количеством света.
- Среднее значение кислотности почвы во всех случаях составляло около 7.
Эта модель скорректировала текущий курс выращивания до оптимального.
О результатах работы алгоритма судить сложно, так как данных было предоставлено мало и времени на реальный эксперимент нам не дали.
Эта модель выдала следующую картину:
Температурный режим в теплице На графике: красный - режим одного случая из набора данных, зеленый - прогнозируемый для этого случая уровень, желтый - рекомендуемый уровень (сглаженный прогнозируемый уровень).
Что мы придумали в качестве веб-приложения? Навыки голосового помощника.
Логика заключалась в том, что условия на Марсе достаточно сложные и требуют специального оборудования и постоянной занятости.
Поэтому интерфейс необходимо упростить, а самый простой интерфейс взаимодействия — это голосовой помощник.
Посмотреть, как это работает, можно в этом видео:
Почему не победа?
Поверьте, я не раз задавал себе этот вопрос после объявления результатов, но предполагаю, что судьи выбрали наиболее подходящий проект. Однако нет повода отчаиваться, это явно не последний АгроХак :) (открою вам секрет, что высока вероятность ежегодного агрокодирования).
Интернатура
А теперь угадайте, что я сделал после объявления результатов? Правильный ответ: я написал организаторам с вопросом о стажировке быстрее, чем они мне об этом написали! Меня выбрали на основании тестового задания и собеседования, которое я успешно прошел.Сейчас я уже познакомился со своими коллегами, исследую применимость моделей для маркетинговых задач и даже получил свою первую зарплату! Итак, если вы раздумываете, куда податься во время или после учебы или вообще сменить работу, то знайте, что в Центре развития финансовых технологий, который, кстати, курирует лично глава Россельхозбанка Борис Листов, Вы найдете отличных коллег и займетесь разработкой интересных и новых для России продуктов.
Теги: #Машинное обучение #Карьера в IT-индустрии #хакатон #Хакатоны #искусственный интеллект #стажировка #наука о данных #конкурс #начало карьеры #агротех #Россельхозбанк #агрокод
-
Mediatek Mt6595: Впечатления От... Чипсета
19 Oct, 24 -
Xlget — Новое Слово В Продаже Контента
19 Oct, 24 -
Кое-Что Об Опере
19 Oct, 24 -
О Преимуществах Валидации
19 Oct, 24 -
Бодо Шефер И Кофе
19 Oct, 24