Введение в робастную оптимизацию
Как определить, сколько людей нужно нанять на новый fulfillment, чем именно его заполнить и куда положить конкретный товар? Чем больше становится бизнес, тем выше неопределенность и тем дороже стоит ошибка. Победить хаос и выбрать оптимальное решение — одна из задач команды data science. А поскольку в основе анализа данных — математика, с нее и начнём.
В этом посте мы рассмотрим задачи оптимизации с неопределенностью в данных и их аппроксимацию детерминированными выпуклыми задачами. Это один из основных трюков в робастной оптимизации — технике, позволяющей справляться с задачами оптимизации, слишком чувствительными к изменению входных данных.
Вопрос чувствительности очень важен. Для задач, качество решения которых слабо зависит от изменения в данных, проще использовать привычную стохастическую оптимизацию. Однако в задачах с высокой чувствительностью этот подход будет давать плохой результат. При этом задач с высокой чувствительностью достаточно много в финансах, управлении поставками, проектировании и многих других областях.
И это пример поста, где сложность растет экспоненциально.
Что значит «решить» задачу оптимизации?
Давайте начнем с краткого напоминания.
Задача оптимизации в общем виде выглядит так:
Здесь называется целевой функцией, а — допустимым множеством.
Под решением задачи оптимизации подразумевают такую точку , для которой выполнено:
Это стандартный концепт решения задачи оптимизации без неопределенности.
Что такое задача оптимизации с неопределенностью?
Пришло время задаться вопросом о происхождении функции и ограничения .
Очень полезно разделять
- структурную логику задачи (проще говоря, какие функции используются),
- технические ограничения (не зависят от логики человека или данных),
- параметры, которые оцениваются из данных.
Вот, например, пришел к нам человек из бизнеса и показал задачу линейного программирования:
Вы видите эту задачу впервые. Человека тоже (может быть и нет, но в синих пиджаках все такие абстрактные!). Смысл переменных вы не знаете. Но даже сейчас можно с большой долей уверенности сказать, что:
- Скорее всего задача линейная, потому что кто-то так решил. Линейность — это структура, которую выбрал человек.
- Ограничения являются техническими. То есть они пришли из «физики», а не из данных (например, продажи не могут быть отрицательными).
- Конкретные значения коэффициентов в ограничении в нашем примере были оценены из данных. То есть сначала кто-то сказал, что переменная связана с переменной , потом было сказано, что связь — линейная, и, наконец, коэффициенты в уравнении связи были оценены из данных. То же самое верно и про коэффициенты в целевой функции.
Когда мы говорим о задачах с неопределенностью, мы таргетим именно неопределенность в параметрах, оцененных по данным. Мы не трогаем технические ограничения или исходный выбор структуры задачи.
Вернемся к нашей истории. У нас линейная задачка, коэффициенты в ней кто-то как-то оценил. Если мы были правы относительно природы коэффициентов в функции, то фактически нас попросили решить задачу для одного сценария развития событий (конкретного экземпляра задачи).
Иногда для нас этого достаточно, и мы ее просто решаем.
Однако иногда решать задачку для одного сценария — дурацкая идея (например, если решение очень чувствительно к вариации данных).
Что делать в этом случае, и как моделировать неопределенность в данных?
Сначала отметим, что неопределенность в данных всегда можно перенести из целевой функции в ограничения или наоборот. Как это сделать, смотрите под катом.
Перенос неопределенности из целевого функционала в ограничения
Для любой задачи оптимизации
можно построить эквивалентную без неопределенности в целевом функционале:
Решение эквивалентной задачи содержит решение исходной .
Перенос неопределенности из ограничений в целевой функционал
Формально для любой задачи оптимизации с ограничениями
можно построить эквивалентную задачу без ограничений
с помощью индикаторной функции
Понятно, что ни один алгоритм такую функцию не переварит, но это и не нужно. Следующий логический шаг — аппроксимировать индикаторную функцию чем-то удобоваримым. Чем именно — зависит от ситуации (про это чуть позже). Так строятся, например, методы внутренней точки (частный случай методов штрафных фунций) и многие другие.
Стохастическая, онлайн, робастная оптимизация и список продуктов
У нас может быть много сценариев возникновения неопределенности, а также вариантов того, что с ней делать. Проиллюстрируем несколько стандартных подходов простым примером.
Не знаю, как ситуация обстоит у уважаемого читателя, но вот я женат (удачно) и периодически хожу в магазин за продуктами. С листочком, конечно (дает неуязвимость от импульсивных покупок). Иногда не просто в магазин, а в условный «Ашан», где дешевле, но куда далеко ехать.
Вот эту ситуацию мы и смоделируем: мы пришли в «Ашан» с листочком в руках за покупками.
Внимание, первый вопрос: как моделировать?
Входные данные: информация о продуктах для покупки и требуемом количестве.
Для удобства можем думать о листочке как о некотором целочисленном неотрицательном векторе .
В качестве переменных возьмем, соответственно, целочисленный неотрицательный вектор — сколько и каких продуктов мы в итоге купим (наше решение).
Дело за малым — взять какую-то целевую функцию , которая говорит насколько сильно мы ошиблись с выбором продуктов.
В зависимости от контекста вид функции может меняться, но к ней есть некоторые базовые требования:
Таким образом получим задачу:
А теперь представим, что листочек остался дома…
Вот так, одной ремаркой мы и попали в мир задач с неопределенностью.
Итак, что делать, если в задаче нам неизвестен ?
Ответ, опять же, зависит от контекста.
Стохастическая оптимизация
Стохастическая оптимизация (обычно) предполагает
- Неопределенность в данных имеет именно стохастическую природу. Полное знание о вероятностном распределении значений недетерминированных параметров
- Ограничения, включающие неопределенность, являются мягкими
В нашем примере, если бы мы моделировали его с помощью стохастической оптимизации, мы бы сказали
- Окей, я не знаю, что было написано в листочке, но я же хожу с листочками уже 8 лет, и у меня есть достаточно хорошее знание о распределении вектора
- Даже если я ошибусь с выбором (то есть с ), вернувшись домой я узнаю настоящий и, если совсем припрет, спущусь в «Пятерочку» и дозакуплюсь там, пусть и дороже.
- Сейчас же я выберу такой , который будет минимизировать какой-то агрегат от исходной целевой функции и возможных «штрафов» за ошибку.
Это приведет нас к такой задаче:
Заметим, что в этой задаче у нас де-факто решения принимаются два раза: сначала основное решение о покупке в «Ашане», за которое отвечает , потом «исправление ошибок» с помощью .
Основные проблемы этого подхода:
- Информации о распределении параметров часто нет
- Ограничения могут быть жесткими (для задач с большим риском — смерть, разорение, ядерный или зомби-аппокалипсис и т.д.)
- Не всегда есть возможность «исправить ошибки» (решение принимается один раз) или наоборот, решения принимаются часто (в этом случае появится много вложенных интегралов, и считать будет очень тяжело).
Онлайн-оптимизация
Онлайн-оптимизация — это фреймворк, в котором изучается последовательное принятие решений. Одним из стандартных подходов к моделированию в данном фреймворке являются многорукие бандиты, о которых на Хабре уже неоднократно писалось.
В контексте нашего игрушечного примера, мы бы:
- вообще не имели (и никогда раньше не использовали) листочка
- и дома нас бы хвалили/ругали за те продукты, которые мы купили (при этом о желаемом наборе мы могли бы только догадываться)
- задача состояла бы в том, чтобы как можно быстрее научиться покупать продукты так же хорошо, как ее бывший, воображаемый принц ну или самый лучший из сыновей подруги ее мамы.
Робастная оптимизация
Робастная оптимизация — это логическое расширение идеи минимаксного решения.
В идеале мы прямо сейчас должны принять решение, которое будет оставаться допустимым всегда, вне зависимости от обстоятельств. Люди, которые проектировали кастрюли, утюги и холодильники в СССР делали это в канве робастной оптимизации: продукт должен работать даже если его 20 лет юзали в качестве основного инструмента истребления мутантов, появившихся после ядерной войны (ее тоже надо пережить).
Более того, хочется, чтобы задачку можно было запихнуть в обычный солвер —, а они не понимают ограничения «для любой реализации случайной величины» (если этих реализаций не конечное число).
В задачке с листочком решение должно приниматься здесь и сейчас и оставаться допустимым при любом стечении обстоятельств:
Понятно, что даже в этом игрушечном примере, если ничего не потребовать от , то никакого осмысленного решения не получится.
Так как же правильно работать с такими задачами?
Построение робастной версии задачи на примере задачи LP
Рассмотрим линейную задачу оптимизации с неопределенностью:
Параметры были получены из данных и включают неопределенность.
Предположение 1: Множество значений (реализаций) может быть параметризовано, т.е. существуют такие , что любая реализация данных лежит в множестве:
Здесь называются «номинальными» данными, а — «сдвигами».
Мини-пример
Мы уже знаем, что всю неопределенность в задаче можно убрать в ограничения. Сделаем это.
Получим задачу
Робастная версия задачи
Теперь настало время для одного из самых прикольных трюков в робастной оптимизации — как от бесконечного числа ограничений перейти к конечному набору хороших ограничений.
Для начала рассмотрим простой пример, когда
Все ограничения в системе
однотипны — это просто линейные неравенства. Научимся работать с одним — научимся работать со всеми.
Поэтому рассмотрим одно ограничение типа неравенства:
Поясню, что произошло.
Сначала мы перенесли все части с неопределенностью в левую часть неравенства, за неопределенность отвечает .
После этого мы посмотрели на худший случай (для каждого он свой).
В итоге у нас получилась следущая запись:
.
Следущий шаг — выписать явно функцию . Для этого достаточно решить задачу оптимизации по и подставить оптимальные :
что приводит к неравенству:
Заметим, что полученное неравенство выпукло и любой ему удовлетворяющий удовлетворяет и исходному для любой реализации …
Ограничение называется робастной версией ограничения .
Это одна из основных рабочих лошадок в робастной оптимизации — аппроксимация вероятностных ограничений конечным набором выпуклых ограничений.
Что делать с более сложными (нелинейными) ограничениями?
Построение робастных версий ограничений с помощью конической двойственности
Очень много стандартных нелинейных ограничений можно представить в коническом виде (то есть в виде , где является некоторым замкнутым выпуклым конусом):
- Неотрицательность
- Ограничения на нормы
- Ограничения на положительную определенность матрицы
Вернемся к робастным ограничениям.
Предположим, что задача оптимизации по удалось свести к конической форме
Построим для этой задачи двойственную.
Некоторое время назад я опубликовал пост про коническую двойственность ровно для того, чтобы в этом посте уделять самой технике чуть меньше внимания.
Теперь дело за малым — теоремой о слабой двойственности:
Следовательно, в качестве робастной аппроксимации исходного ограничения можно использовать ограничение
где такая же переменная, как и .
Так мы построили робастное ограничение для исходного неравенства.
Заключение
Мы рассмотрели технику аппроксимации плохих (стохастических) ограничений набором хороших выпуклых. Это может пригодиться, например, в случае если:
- Вы не хотите сами писать алгоритмы, но используемый солвер не умеет работать с вероятностными ограничениями.
- Есть задача со стохастическими параметрами, при этом оптимум очень чувствителен к флуктуациям в данных.
- Ну и, конечно, задачи с неопределенностью, где все ограничения жесткие (цена ошибки слишком высока)