Зачем понадобилось прогнозировать остановки экструдера
Начнём с постановки задачи. Экструдер — это такая большая промышленная мясорубка, которая нагревает и размягчает полипропилен, перемешивает его с разными добавками, прессует, проталкивает через фильеру (решётку), и нарезает на маленькие гранулы. Потом эти гранулы засыпаются в биг бэги и продаются потребителю полипропилена, который делает из него что-нибудь полезное — например, те же биг бэги. Но это если всё идёт хорошо. А бывает, что на фильере нарастает корочка из полипропиленовых агломератов — его крупных кусков, которые мешают нормально нарезать гранулы. В результате в лучшем случае производится некачественный продукт, а в худшем экструдер приходиться останавливать, разбирать и прочищать — получается дорогостоящий простой.
Впрочем, если такое засорение вовремя обнаружить, его можно предотвратить определёнными действиями. Постоянно в таком режиме работать нельзя — плохо отражается и на оборудовании, и на продукте. Отсюда и возникает задача прогнозирования: оператору, который следит за экструдером, необходимо сообщать о потенциальных проблемах, чтобы предотвратить те самые простои. Причём, чтобы предотвратить можно было эффективно, сообщать нужно сильно заранее. Проблема в том, что однозначного и простого признака, по которому можно определить приближающуюся деградацию процесса, нет. Именно поэтому здесь потенциально может помочь машинное обучение: надёжный сигнал о предстоящих проблемах можно попытаться сформировать на основе статистики и грубой силы.
О переобучении и прокрастинации
Статистический подход, однако, затрудняет маленький размер данных. Нам дали показатели 43 датчиков за полтора года с частотой в 10 секунд — 4 миллиона наблюдений, занимающие два гигабайта.
Бороться с проблемой переобучения можно по-разному: пойти добыть больше размеченных данных (не у кого), встроить в модель экспертные знания о процессе (у нас их не было), сильно ограничить гибкость модели (пробовали, не вариант). А ещё один способ избежать переобучения — это прокрастинация. Вместо того, чтобы предсказывать редкие остановки экструдера, можно пойти решать какую-нибудь совершенно другую задачу, более простую и приятную. И надеяться, что изначальная задача решится как-то сама собой. Удивительно, но это работает.
На поле боя вступают нейронки
Прокрастинация, на самом деле — это тоже искусство. Подробнее можно поискать по ключевым слова «transfer learning» или «обучение представлений». Ключевая идея в том, что в процессе решения посторонней задачи алгоритм машинного обучения может открыть для себя признаки и закономерности, полезные и для основной задачи.
В нашем случае основная задача — это предсказание вероятности проблем в ближайшем будущем, но проблемы размечены скудно. Можно решить вспомогательную задачу: научиться предсказывать значения каждого датчика — например, через 3, 10, 30, 60 и 120 минут. Это, во-первых, может быть полезно само по себе. Во-вторых, предсказания работы датчика удобно сравнивать с фактом, и тем самым убеждать заказчика, что модель вообще имеет предсказательную силу. А в-третьих, и это главное, если мы сможем найти относительно небольшое количество признаков (скажем, 256), которые позволяют прогнозировать значение любого датчика на разные горизонты, то и засорение фильеры они тоже, наверное, прогнозировать смогут.
Для предсказания значений всех датчиков мы решили использовать полносвязную нейронку, на вход которой подавались полторы тысячи уже слегка агрегированных и нормализованных признаков, а на выходе каждый из 43 датчиков должен предсказываться на 5 разных горизонтов. После небольшого числа экспериментов получилась такая пятислойная конструкция:
import keras
from keras.models import Model
from keras.layers import Input, Dense
l2_regul = keras.regularizers.l2(1e-6)
input_layer = Input(shape=(input_shape,))
enc1 = Dense(512, kernel_regularizer=l2_regul, activation='relu')(input_layer)
enc2 = Dense(256, kernel_regularizer=l2_regul, activation='relu')(enc1)
repr_layer = Dense(256, kernel_regularizer=l2_regul, activation='relu')(enc2)
dec1 = Dense(256, kernel_regularizer=l2_regul, activation='relu')(repr_layer)
dec2 = Dense(256, kernel_regularizer=l2_regul, activation='relu')(dec1)
last_layer = Dense(prediction_shape)(dec2)
model = Model(inputs=input_layer, outputs=last_layer)
encoder = Model(inputs=input_layer, outputs=repr_layer)
Полную модельку model мы поставили на полночи обучаться на всех полутора годах данных. Утром проверили качество на тестовой выборке: оказалось, что даже на двухчасовом горизонте средний по всем датчикам больше 98%. Что ж, датчики мы прогнозировать умеем. Теперь model можно выкидывать в помойку. Потому что для решения основной задачи нам нужен только encoder — подмодель, превращающая входную информацию с датчиков в 256 сильных признаков. На этих признаках можно обучить сильно зарегуляризованный xgboost, который уже будет предсказывать целевые события. Оказалось, что предсказывает довольно неплохо: ROC AUC порядка 96% на кросс-валидации. Без нейронки было заметно хуже.
Как сюда можно прикручивать физику
В рамках хакатона мы презентовали именно это решение, с предобученными нейронкой признаками. Но на реальном проекте мы бы попробовали более сложную конструкцию, которая более явно использует физические закономерности.
Преимущество физических формул в том, что они обычно очень простые, а следовательно, устойчивые и интерпретируемые. Недостаток — в том, что их надо знать. Нейронка пыталась предсказывать влияние каждого датчика на каждый — для этого, если не пользоваться скрытыми факторами, нужно обучить как минимум матрицу 43*43. В реальном мире зависимости гораздо более разреженные — большая часть датчиков не влияет друг на друга непосредственно. Это подсказывает нам просто здравый смысл. Но чтобы знать, какие именно зависимости всё же существуют и обоснованы физикой, нужно знание предметной области. Или тщательный и довольно мудрёный анализ данных. Мы ограничились простой его формой — для каждой пары датчиков измерили, насколько сильно и с каким временным лагом их показатели друг с другом коррелируют. Если отображать точками датчики, а стрелками — самые сильные корреляции между ними, получается примерно такая картинка:
Мы видим несколько групп взаимосвязанных датчиков. Зная устройство экструдера и точный физический смысл каждого показателя, группы можно скорректировать до более логичной картинки — например, осознать, что 7й цилиндр не влияет на 9й напрямую, а только через 8й. Ну а потом по каждой группе сильно взаимосвязанных датчиков можно ввести какой-то свой интерпретируемый индикатор её состояния. Такие индикаторы могут оказаться ещё более сильными признаками, чем то, что выучила нейронка. И главное, они могут быть полезны для оператора эструдера — с их помощью можно не только предвидеть проблемы, но и быстро понять, где эти проблемы локализованы.
Пользовательский опыт и замеры качества
Если бы мы не участвовали в хакатоне, а писали научную статью, тут можно было бы и остановиться: мы доказали, что у задачи прогнозирования неполадок есть решение. Но на самом деле настоящая работа здесь только начинается: теперь необходимо заставить созданную нами модель приносить пользу. Для этого она должна быть качественной минимум по трём метрикам:
- Доля предугаданных неполадок (наверное, порядка 80% — уже неплохо?)
- Частота ложны срабатываний (чаще, чем в среднем раз в смену — уже беспредел)
- Горизонт прогнозирования неполадок (на предотвращение остановки вроде как нужно от 5 до 30 минут)
В простейшем случае эти метрики настраиваются выбором порога, после которого модель «срабатывает» и кидает испуганные уведомления. Более сложное и правильное решение — делать прогнозы риска остановки на разные временные горизонты, сглаживать каждый из них каким-либо методом сглаживания временных рядов, и поднимать тревогу, если по одному или нескольким из них прогнозы зашкаливают. Но чтобы эту настройку осуществить, стоит наконец-таки пообщаться с потенциальными пользователями этой системы — выяснить, какие у них ожидания от неё, как осуществляется предотвращение остановок сейчас, и на какие действия они готовы в дальнейшем.
О чём я не рассказал
На самом деле, о многом. И о том, как мы потратили несколько часов, тупо долбясь в графики и пытаюсь разобраться в природе неполадок, пока не обнаружили, что даты остановок нашим алгоритмом были считаны в неверном формате, и обучались мы на неверных событиях. И как мы пытались сконтактировать со специалистами из Тобольска, чтобы они рассказали нам, что да как в экструдере устроено. Если бы не выходные, возможно, нам бы даже ответили… И о том, как мы в последние часы взялись за демонстрационный интерфейс нашей системы, и впиливали в него «машину времени» для просмотра истории прогнозов, я тоже не буду — всё-таки это статья про data science. Не особо богатый интерфейс — наверное, одна из причин, почему мы заняли только третье место. Впрочем, он работает, и это уже повод радоваться.
На сырую версию интерфейса можно посмотреть тут — она «проигрывает» в ускоренном режиме работу предсказательной модели в один из реальных вечеров этого года. Ссылка открывается на времени 20.45, а в 21.05 экструдер на самом деле остановился, это исторический факт. Впрочем, благодаря таким, как мы, в обозримом будущем этот экструдер придётся останавливать значительно реже.
Комментарии (9)
ximik13
30.05.2018 15:09Спасибо за статью. Вспомнил былое. Когда-то работал и оператором на экструдере и позже технологом на производстве с экструдерами. А теперь вот уже давно в IT :).
По простою экструдеров могу сказать, что основная боль это запуск и выход на качественную продукцию, который занимает до нескольких часов. А все это время сырье проходящее через экструдер идет на производство брака :(. Причем в зависимости от производственной мощности экструдера брак может измеряться и сотнями кг и тоннами. И это помимо непрямых потерь простоя производства.
ximik13
30.05.2018 15:11Себя же и поправлю. Правильнее называть не оператор, а машинист экструдера :). Звучит правда забавно.
lxl
30.05.2018 16:06Можно где-нибудь посмотреть на кусок кода, который строит кластеры с корреляциями?
cointegrated Автор
30.05.2018 16:09Код сырой и разбросанный. Но по сути он делает примитивную вещь: берёт все пары показателей, для каждой пары считает корреляцию с разными лагами по времени, выбирает тот лаг, на котором корреляция максимальна. На граф попадают пары показателей, у которых максимальная корреляция больше порога, направление стрелочки показывет знак лага. Граф отрисовывается с помощью
networkx
.
diamond_nsk
У меня почеу-то на 16:44: хх открывается… ЧЯДНТ?
cointegrated Автор
Живёшь в Новосибирске?
diamond_nsk
Мда, действительно… надо перебираться… «Видео» будет в правильное время открываться хоть))
neco
я вот тоже в новосибирске так у меня вообще не открывается… ;)
cointegrated Автор
Там тайм-аут большой, пока бесплатный аккаунт на heroku просыпается)