Валидация данных в проектах машинного обучения


slides-validation.pdf

Текстовая расшифровка, невычитанная:

Вы решаете, зачем. Он поговорит о валидации данных в проектах машинного обучения. И маленькое введение такое. Мы учим модели на чистых данных, а потом они отправляют туда всякое. Как валидировать входные данные, и почему PyDentic хорошо, но недостаточно. Слово Дмитрию. Презентация появилась. Спасибо. Часто получается, что данные, которые к нам приходят, это не те данные, о которых мы ждали. Собственно, их надо как-то валидировать. Это вообще всегда надо делать. Ну и вот мы и про это и поговорим. План такой. Сначала вспомним про жизненный цикл модели, как они вообще живут и умирают. Поговорим про валидацию при инференсе, то есть непосредственно на проде. Вспомним хорошие библиотеки PyDentic и FastAPI, которые решают прекрасно проблему валидации при инференсе. Вспомним, откуда берутся ошибочные входные данные, как с ними жить. Подумаем про валидацию при обучении. Рассмотрим Pandera, это хорошая библиотека для валидации Pandas DataFrames. Вспомним валидацию в мониторинге, которую мало кто делает, а должны делать все. И еще раз поговорим про жизненный цикл. Примерно вот так. С жизненным циклом модели он такой. Вообще про него можно говорить долго, он длинный, там есть анализ данных, выяснение бизнес-потребности. Но нас все это уже не очень интересует на момент, когда мы делаем модель, у нас есть данные, нам нужно ее обучить и выкатить на проду. Следовательно, нас интересует подготовка данных, то есть выкинуть оттуда мусор, сконвертировать как надо обучение модели, затем верификация модели, то есть проверка того, хорошо ли работает обученная нами модель. Непосредственно ее работа на проде, то есть Inference. Мониторинг, не сломалось ли что-нибудь в данных или в модели во время работы. Ну и повторить, когда к нам пришли новые данные, мы можем модель переобучить и сделать снова хорошо. На Inference, собственно, валидация данных на проде, это самое важное то, что все так или иначе делают. Мы раскатываем наши модели либо в виде REST API, к которому обращаются другие микросервисы или монолит заказчика, либо библиотечные функции. И вообще принято, что если вы раскатываете веб-интерфейс, то веб-интерфейс надо данные проверять, мало ли что вам пришлют туда. Но проверять надо данные и в библиотечных функциях. Почему это так? Потому что в больших проектах вы не контролируете все. То есть вам пообещали один формат данных, затем кто-то, кого вы совсем не знаете и с кем вы никогда не разговаривали, поменяет формат данных в базе, формат данных в API, и у вас все сломается, упадет. Проверять надо не только формат данных, что вам передали строку или целую, но и соответствие типа, попадание данных в диапазон, для категориальных данных выбор из списка возможных значений, ну и соблюдение различных условий. То есть, например, что вес больше нуля, что рост человека меньше трех метров, ну и так далее. Все это обязательно проверять при работе модели. Мы очень любим и используем Pydantic. Pydantic библиотека для верификации данных, строго говоря, она не для верификации, она для парсинга, о чем они в документации все время пишут, что реально это такой контракт на данные. Вы говорите, вот мне придут какие-то данные, неважно какие это, и Pydantic-модель, она либо выбросит исключение, либо вернет хорошие разобранные данные, на которые я уже могу полагаться. При этом Pydantic работает следующим образом. Вы объявляете некоторый класс BaseModel, наследники его, и говорите, какие в нем есть поля. И используется привычный синтаксис аннотаций и типов. Можно определять свои типы, полученные аннотации, понимать MyShare, понимать MyPy. Все это скомпилировано и работает очень быстро. То есть, Pydantic самый быстрый валидатор из всех, какие есть на рынке. Он легкий, он хорошо расширяется, ему быстро учиться, и, что немаловажно, он уже стоит под капотом любимой нашей библиотеки, которую мы используем, FastAPI, для развертывания моделей в виде микросервисов. В FastAPI вы просто определяете сигнатуру функции с помощью аннотации типов, и больше вам делать ничего не надо. Дальше FastAPI сам проверит, что пришедшие в запросе данные соответствуют этой аннотации, выбросит исключение, либо данные сконвертирует. Причем, поскольку Pydantic это парсер, строго говоря, не валидатор, поэтому там, где можно будет привести данные к формату, он приведет. То есть, если вам число будет передано в виде строки, и он сможет эту строку сконвертировать, вы ничего не заметите, вы просто получите ваше число. Вы можете расширять FastAPI, писать свои валидаторы, обрабатывать сами исключения, но в целом он из коробки работает отлично, и у него есть все, что нужно в Pydantic и FastAPI. Почему вообще приходится валидировать данные? Причина страдания в том, что данные берутся из внешних источников, над которыми вы не имеете контроля. Например, это могут быть запросы из пользовательского интерфейса. И, например, это живой случай из практики, дизайнеры в пользовательском интерфейсе сделали, по итогам, вероятно, АБ-тестов, пользовательский интерфейс удобнее, после чего пользователи начали, наконец, двигать ползунок, который указывает на запрошенную сумму кредита. И в результате у заказчика изменилась средняя запрошенная сумма кредита, и модель стала выдавать другие данные. И, в принципе, данные, как шли, соответствовали схеме, просто они стали по-другому распределены. Вы выгружаете данные, мы выгружаем данные из баз, и в этих базах данных тоже данные могут, во-первых, поменяться, а во-вторых, они могут храниться в странном типе. То есть хорошо, когда у вас нормализованная типизированная база. Если у вас какая-нибудь SQLite база или, не дай бог, 1С из которой вы берете данные, то у вас нет контракта на формат данных, вы его сами себе из головы выдумали, и те, кто поддерживает базу данных, могут его свободно поменять, вы об этом никогда не узнаете. Внешние источники, внешние API, бюро кредитных историй, Росреестр, любое внешнее API, которое вы можете придумать, однажды изменят свой формат данных и не всегда вам об этом скажут. И когда вы импортируете, полагаетесь на импорт данных из внешних источников, там все меняется просто потому, что это не ваши данные. И все это приводит к тому, что ваше предположение о том, что данные будут распределены так или иначе, неверно, и вы сталкиваетесь с интересной проблемой. Вот пришли неверные данные, что с ними сделать? По большому счету есть два варианта. Вы можете отбросить эти данные, но те, кто вызывает нашу модель, нарушили контракт на данные, мы возвращаем ошибку, пусть они сами разбираются. Либо вы можете заменить неправильные данные на дефолтные, хоть как-то отработать. Иногда нужно делать так, иногда это не ваше решение, не наше решение, это решение бизнеса. Иногда каждая заявка настолько важна, что ее желательно обработать любой ценой. А иногда не будет сделана какая-то рекомендация пользовательной веб-страницы, но сделана, потери будут небольшие. Мы не можем знать как лучше, это надо согласовывать с бизнесом. Иногда бывают странные обстоятельства, например, миграция на другого поставщика данных, когда из одного источника идут данные в одном формате, из другого в другом. Бывает, что идет миграция пользовательского интерфейса, и данные начинают переходить по-другому, бывает, что мигрируют схемы данных. Все меняется, особенно в наши коронавирусные времена, все меняется еще быстрее. Но если мы решили отбросить данные, тут, допустим, в случае фастаппи вообще делать ничего не нужно. То есть мы просто выбрасываем исключение, оно выбрасывается автоматически, если аннотация типов не совпала с нашим запросом. Пользователю прилетает 422 ошибка, мы пишем ошибку в центре, кто-нибудь когда-нибудь посмотрит это в центре и разберется, почему к нам идут неправильные данные. Иногда нужно обработать данные, несмотря ни на что. Ну и тут есть, это может быть хорошая причина, например, наша модель вполне может работать с пропущенными данными. Тут пришли какие-то непонятные данные, давайте мы предположим, что это просто данные были пропущены. Мы их заменим на средние, на дефолтные, просто передадим в модель как недоступные данные. Напишем в центре и будем дальше работать. Пусть наше решение будет худшего качества, но мы все-таки обработаем эту заявку, сделаем эту рекомендацию, выдадим этот микрокредит. В общем, чем мы там занимаемся, наш вкус. Для этого мы можем написать свой валидатор, то есть в PaidAntic мы можем использовать стандартный валидатор и можем переопределить валидатор, который делает что-нибудь странное. Например, он может обрабатывать ошибку внутри себя, если у него не получилось понять, что же такое нам передал пользователь. И возвращать хорошее значение, дефолтное, так, чтобы наша модель ничего не заметила и только в центре было сообщение об ошибке. Хороший антипаттерн, который часто встречается, это разные валидаторы при обучении и при инференсе. Как правило, валидация и обучение – это разные обучения и инференс непосредственно, работа на проде-модели – это разный код, иногда написанный разными людьми в разное время, и неудивительно, что люди валидируют данные по-разному. То есть кто-то чистил данные одним способом, полагался на одно распределение данных, кто-то потом на инференсе валидирует данные другим способом. Если эти проверки и приведения писали разные люди, может получиться так, что распределение данных при обучении и при работе модели не совпадает. Это тонкое различие, но оно может привести к тому, что, например, хорошие данные, которые мы использовали для обучения, у нас отбрасываются как неправильные, или, например, что распределение, на котором мы обучились, будет шире, чем то обучение, на котором мы предиктим. Соответственно, мы могли бы делать более точный предикт, если бы еще при обучении распределение также усекли. Идеально валидировать при обучении и при инференсе одним и тем же кодом. К сожалению, идеал не всегда достижим. Почему? Потому что недостаточно проверять при обучении и особенно при переобучении типы данных. Иногда у нас, например, есть такие явления, как сдвиг и дрейф модели. Сдвиг – это когда у нас, например, изменилась средняя зарплата, или средний чек в магазине, или среднее количество товаров в корзине. И, в принципе, наша модель что-то такое разумное выдает, но входящее распределение – совсем другое распределение признаков. И нам давно уже пора взять и переобучить нашу модель. А как мы об этом узнаем? Кто-то должен проверить и сказать, ребята, распределение изменилось. Мы, возможно, закладывались на то, что какие-то наши параметры лежат в каком-то диапазоне, а они перестали лежать в этом диапазоне. Иногда, например, данные идут, в принципе, хорошие, но у нас начинают идти повторяющиеся значения. Часто это сигнал низкого качества данных. Например, что изменили интерфейс пользователя, и там какая-то форма, какой-нибудь ползунок, который раньше пользователи замечали и двигали, а теперь перестали замечать и двигать. И нам идет не то значение, которое выбрал пользователь, а дефолтное значение из интерфейса. Или, например, мы много работаем с пространственными данными. Если идет большой поток одинаковых координат, то, скорее всего, кто-то из поставщиков данных перестал отдавать реальные координаты и стал отдавать координаты, полученные из геокодера. То есть человек ввел адрес, и по этому адресу Яндекс.Геокодером, например, определились координаты, нам эти координаты вернулись. То есть это не те координаты, которые были на самом деле. Это те координаты, которые какое-то API преобразовало, получило из адреса. То есть когда, допустим, половина координат в Новосибирске приходится на площадь Фрунзе, причем на одно конкретное место в площади Фрунзе. Ну, это вот проблемы качества данных. Вы не поймаете эти проблемы просто проверяя попадание в диапазон или совпадение типов. То есть вам нужно смотреть распределение входных данных при обучении. И вам нужно смотреть на ваш предикт. Например, если при обучении средняя рекомендованная, допустим, сумма сделки была, например, 20 тысяч рублей, а ваша модель давно, уже третий день подряд рекомендует 30 в среднем, то что-то изменилось в мире, чего ваша модель не учитывала. У вас ушел предикт, изменилось распределение. Я работал как-то с одними людьми, они просто постоянно каждый день смотрели глазом и сравнивали распределение предикта модели. Вообще-то можно считать какой-нибудь информационный критерий, того же Кульбаха-Лейбера или что-нибудь еще, и валидировать наши данные не построчно, а все целиком, что у нас что-то изменилось в принципе в природе, что у нас ушли данные, нам надо переобучать модель, надо идти к поставщикам смотреть, что у них изменилось. Но тут проблема, где мы возьмем эти гипотезы на данных. Гипотезы мы берем из идеи, если мы правильно сделали домашнее задание, хорошо изучили данные, у нас могут возникнуть идеи, какие данные надо проверять. А еще, если мы обучили модель, мы можем посмотреть, на что она обращает внимание, то есть, например, посчитать шеки вывес и посмотреть, какие признаки наиболее важны для модели. И именно важные признаки, дополнительно распределение на них проверять. Но еще можно спросить экспертов, что они думают по этому поводу. Как правило, у них есть тоже идеи, что нужно проверить. Вот настроили мы гипотезы, и чем же мы их будем проверять? Проверять в нашем случае мы будем Pandera. Pandera это библиотека, которая тоже проверяет тип, может валидировать схему данных и дополнительно она может проверять гипотезы на данных. То есть тут, например, на слайде пример проверяется гипотеза двухсторонняя о том, что средний рост у мужчин выше, чем средний рост у женщин на обучающей выборке. Когда такие вещи могут понадобиться? Например, когда вы делаете обучение модели, а потом вы берете и выполняете верификацию модели, то есть вы подаете ей тестовый набор, на котором она не училась, на котором вы хотите проверить качество модели. Хорошо бы перед тем, как проверять качество модели, проверить, что обучающий и тестовый набор лежат в одном распределении, изгенерированы из одного распределения. Потому что иначе у вас валидация будет некорректная. С Pandera все прекрасно. Она позволяет валидировать схему данных, она позволяет проверять гипотезы. Единственное, что получается, что она не встроена в FastAPI. В FastAPI так удобно работать с Pydantic, поэтому у нас возникает та самая нестыковочка. Мы напротив всегда используем Pydantic, а при обучении используем Pandera. Тут, конечно, кроется большое пространство для возможных ошибок, но у нас ничего лучшего мы пока не придумали. У Google на все есть ответ, есть и на это. В TensorFlow есть библиотека, часть TensorFlow Data Validation, которая проверяет статистики на данных, которая проверяет схему, которая проверяет данные при инференсе. Она визуализирует статистики, она детектирует аномалии в данных, она отслеживает сдвиг и дрейф. Она всем хороша, просто всем хороша. Кроме одного, она не работает под Python 3.8, на котором мы работаем. И на самом деле мы не очень используем TensorFlow, мы предпочитаем PyTorch, но я буквально жду не дождусь, когда у нас появятся случаи тоже ее поиспользовать. Пока мы ее в тестовых проектах смотрели, напротив у нас TensorFlow Validation нет. Но если посмотреть, что они делают здесь в документации, то прямо очень хочется все бросить и начать использовать TensorFlow Data Validation. Что, например, происходит здесь? Мы берем наши обучающие данные и инференсим схему, то есть мы не явно ее задаем, а говорим, вот те TensorFlow Data Validation данные, сама догадайся, хорошая, какие там ограничения на данные есть. И затем мы считаем базовые статистики на данных. После чего мы можем визуализировать разницу между обучающей и тестовыми выборками, например, выявить какие-то аномалии, показать эти аномалии. Мы можем сравнить наши схемы сохраненные. Мы можем выявить сдвиг и смещение данных. И, в общем, действительно, как все у Google, она хорошо проработанная, быстрая. Кстати, она не так завязана на сам весь TensorFlow, то есть ей можно пользоваться вне зависимости от самого TensorFlow. Ну, 3.8 битона она все-таки не поддерживает, поэтому у нас она пока пролетает. Но после того, как мы обучили модель, после того, как мы ее выложили на Prod, она на Prod работает, нам желательно мониторить качество ее работы. Самый правильный подход – это сохранять все запросы к модели и все наши ответы. Ну и желательно версии нашей модели, которой был сделан этот ответ. Это позволяет нам проверять распределение в запросах, то есть не изменилось ли что-то в окружающем мире, не изменились ли данные, которые к нам идут. И проверяем распределение ответов, то есть не начало ли наша модель выдавать неправильные или какие-нибудь завышенные, заниженные оценки. И если у нас что-то изменилось здесь, выдавать алерт, менять поставщиков данных, переобучать модели, вообще делать что-нибудь разумное, чтобы сохранить качество работы модели. Почему мониторинг важен, я думаю, всем уже не надо объяснять после того, как коронавирус случился. В конце марта, в начале апреля все маркетинговые модели слетели и перестали работать. Ну вот на самом деле они продолжают, перестают работать, перестают работать каждый месяц, обстоятельства меняются. Я не знаю, как это в Le Mode, нам, наверное, расскажет докладчик из Le Mode, но у нас в наших интернет-магазинах поведение потребителей меняется прямо вот как небо и земля до карантина и сейчас. И без мониторинга мы не заметим, что модель уже давно пора переобучить и сделать новую. Кроме описанных Pydantic и Pandera, есть, конечно, еще куча моделей, куча еще валидаторов. Что у них общее? Все они так или иначе умеют работать с форматом JSON-схема. Это формат, это описание данных, платформа независимая и можно использовать не только в Python, в Python можно использовать его в Java, можно использовать C Sharp, в PHP. И вот это вот питоновские библиотеки, которые решают проблемы в валидации, я думаю, что есть еще миллион таких же. Если вернуться к жизненному циклу приложения, то у нас есть этап подготовки данных и обучение модели. На этом этапе, я считаю, лучше это Pandera, верификация модели. Тоже Pandera, мы сравниваем распределение на тестовой и обучающей выборках. На inference хорошо использовать Pydantic, потому что он позволяет быстро валидировать сложные схемы данных. При мониторинге Pandera на всех этих этапах может быть использован TensorFlow Data Validation. Ну и при переобучении мы делаем то же самое, что и обучение данных, только еще мы сравниваем распределение на новых данных и старых данных просто для себя, чтобы понять, что может быть нам надо ждать каких-нибудь резких изменений в работе модели. Примерно так. Слайды лежат тут, я доступен тут. Вопросы? Включаю микрофон, читаю вопросы. Вопросов много. Пойду в хронологическом порядке. Владимир Козлов задает вопрос, можно ли в Pydantic не полностью парсить данные, а лишь доставать те, которые мне нужны? Да. Если кратко, в Pydantic можно все. В Pydantic есть еще такая замечательная вещь, например, кроме своих валидаторов, допустим, у него есть расширение Pydantic, которое прикидывается стандартными питоновскими датаклассами. То есть если вы используете датаклассы, вы можете вместо них использовать Pydantic датаклассы. Если вы используете датаклассы, вы в них можете добавить свой валидатор, который как-нибудь особенным, хитрым образом проверяет какой-то вот один параметр, или два, или три. В документации хорошие примеры есть. Какой самый экзотический тип данных вы используете в Pydantic? У нас есть библиографические данные в одном из проектов. Библиографические данные, где одни научные статьи ссылаются на другие научные статьи. И это настоящее будущее. Окей, похоже, хороший ответ. Какие предметные области критичны к валидации поступающих данных? По большому счету валидировать нужно любую модель, которая стоит всех своих денег. Во-первых, если вернуться к жизненным циклам, чем чревата невалидация на разных этапах? Если вы не валидируете данные на обучении, вы обучите модель плохо. То есть вам попадется какая-нибудь ошибка в данных, вы ее не заметили, модель обучилась, вы ее отдали, ребята на проде сделали все правильно, все свалидировали, но так как вы допустили ошибку при подготовке данных обучения, то их уже ничего не спасет, модель выдает плохой результат. Если вы не верифицируете то, что вам приходит в растапе, вы вообще сомневаетесь. Потому что в растапе вам обязательно придет китайский хакер и отправит вам какой-нибудь инвентарный запрос, который положен во все. Если вы не мониторите модель, вы не узнаете, что мир давно изменился, и ваша модель выдает неверные предсказания. Ну а вообще, чем больше вы полагаетесь на вашу модель в продажах, в финансах, я не знаю, медицины у вас сейчас нет, сейчас есть больше продажи, интернет-магазин, то есть чем больше для вас, значит, чем больше риск от неправильного прибития, тем плотнее надо мониторить модель. Мне кажется, финансы сильнее всего должны ее мониторить. Но именно в финансах я видел упоротые варианты, когда люди не мониторят, и это очевидно выше. Окей. Какие самые интересные гипотезы вам приходилось проверять? Интересные? Ну, я думаю, все интересные. Все интересные. Как инфраструктурно сделаны алерты по метрикам качества? То есть в модели обучилась, есть какая-то подозрительность? Как быстро, по каким каналам, чат, письмо, ваша команда об этом узнает? Смотрите, у нас есть… Про мониторинг. Был хороший доклад, на самом деле, про мониторинг Саши Родионовой из Благис. У них мониторинг показывается в Prometrics прямо в реальном времени. Мне очень понравилось. У нас это сделано не так. У нас есть некоторые инфраструктуры для проверки. Какие-то вещи проверяются раз в 5 минут, какие-то раз в час, какие-то раз в сутки. То есть у нас чекеры ходят и проверяют. Не исключено, если чего-нибудь страшного. Окей. Вопрос в догонку. Во время мониторинга с чем сравнивать ответы модели? Где взять истину? Смотрите, у вас есть обучающие данные, например, и у вас есть распределение предикта на этих обучающих данных. Допустим, средняя вероятность того, что этому клиенту надо рекомендовать сделку была у вас 10%. И внезапно вы сегодня отработали, у вас средняя вероятность того, что этому клиенту надо предлагать сделку была у вас 40%. Клиентов у вас, например, тысячи за день. То есть это статистически значимое изменение. О чем это говорит? О том, что клиент хороший пошел, маловероятность. Скорее всего, это что-то во входных данных изменилось, какой-то параметр, который раньше у вас шел по дефолту, теперь идет не по дефолту. Наоборот, вот так. То есть сравнивать день с днем, сравнивать инференс с обучением. Были ли у вас случаи, когда аномалии в данных на самом деле реальные данные? Да, аномалии в данных реальные данные. Проблема только в том, что модель может не уметь в эти аномалии. Рассматривали ли вы работу Savro вместо JSON-схемы? Мы не сохраняем нашу модель в JSON-схему. Мы смотрели, есть инфраструктура, которая покрывает весь жизненный цикл модели. Но у нас сейчас оно фрагментировано. То есть у нас сейчас есть Paidantic, у нас есть Peta ручные проверки, у нас есть Pandera. И нет пока единого языка. То есть мы находимся в активном поиске идеальной схемы валидации. Какой в итоге процесс модели пришлось пересмотреть из-за ситуации со злобным вирусом? Какие выводы вы сделали? Пришлось пересмотреть все модели. Какие выводы я сделал, что надо моделями повторить все данные? Мы же сантисты. Может, соберем плохие данные и сделаем в легкий классификатор хорошие и плохие данные? Это хороший вопрос своей преисполненности. Дело в том, что не бывает хороших и плохих данных. Есть данные, которые модель умеет, а данные, которые модель не умеет. Какова доля стоимости валидации от всего проекта работы с данными? Валидация на Prode делается бесплатно. Если вы используете FastAPI, мы его используем. То есть она просто встроена в фреймлок. Валидация на обучение. Вы так или иначе данные чистите. По-хорошему, если это делать правильно, это будет на 10% медленнее. И снизить количество ошибок ваших дистанций. Это стоит того в любом случае. Какие самые смешные гипотезы, которые вы проверяли? Это все обычно очень грустно. Вопросы из каналов у меня иссякают. Может быть они еще будут поступать. Может быть у кого-то из докладчиков есть какие-нибудь вопросы. Допустим, может быть Дарья из Ламоны. Она будет выступать следующая. Может быть у нее есть какой-то вопрос. Потому что вроде тема может быть чем-то схожа. Нет? Нет у тебя вопросов? Хорошо. Нет, это тогда. Но надо сначала сделать тут пару объявлений. Первое, это... Мне хотелось, конечно, задать вопрос, но я пока читал вопрос и забыл свой вопрос. Ладно. Нет, все-таки я его помню. И у Витас мне спать, если его не задам. Дима, скажи, это коронавирус вызвал у тебя такой интерес к этой теме? Или ты как-то всегда все-таки занимался вопросом, ну, как бы, валидацией этого? И потом, пока я тебя слушал, у меня было такое чувство, что большая часть того, что ты рассказывал, ну, хороший, вроде, сайентист, должен делать и так, да? Потому что то, что ты говоришь, там, уплыл куда-то там, например, Target, ну, явно, что как-то что-то не то с моделью, надо все время ее мониторить. То есть, что здесь действительно нового? Ну, понятно, что есть библиотеки, это как бы здорово, ты их осветил. Но вот как бы актуальность и актуальность этого вопроса. Расскажи. Когда ты последний раз сравнивал распределение предикта своей модели? В смысле, допустим, свежее и не то, что было? Вот у тебя модель идет и выдает какой-то предикт, вот. И как у тебя построено, как часто ты контролируешь, что распределение не ушло у тебя предикт модели? Я работал с ребятами... Ну, смотри, дай-ка я так. У нас по утру смотрел распределение раз в сутки, глазом. У вас по-другому? У нас по-другому, потому что, ты знаешь, конечно, распределение и как бы общее изменение ситуации вопрос интересный, но, конечно, интересно, насколько точно мы в конце концов предсказываем, насколько точно вся эта история работает. И как часто мы будем переобучаться. Поэтому нет. Я, честно говоря, не очень знаю. Человек, который задал первый вопрос, наверное, ответил бы на твой вопрос. Но занимаемся. Так все-таки вопрос к тебе. Насколько это из-за коронавируса ты занялся или ты всегда следишь, как раз делаешь то, о чем спрашиваешь? Нет, я на самом-то деле всегда это в легкую делал, но по полной ты, наверное, знаешь, что у меня был один интересный контракт зимой. И вот после работы с этими людьми я понял, что валидацией надо заниматься. Я не могу, наверное, сколько говорить об этом. Но там я прямо убедился, что валидации от коронавируса не хватает у людей. Поэтому решил рассказать. Но и коронавирус все еще сложный. Предположим, что ты предсказываешь сделку. Сделка реально случится через два месяца. Соответственно, у тебя данные о том, хороший был предикт или нет, могут быть отложены. Хорошо, если ты рекомендуешь подсказки в корзину, и у тебя немедленно человек либо положил в корзину, либо нет. Если ты микроклиби и у тебя данные о том, вернули или нет, будут через два месяца. Если ты рекомендуешь сделку по недвижимости, которая идет несколько месяцев. Единственный способ проверить, что у тебя модель уже два месяца подряд не выдает трубы, не разоряет своих заказчиков, это смотреть на то, как распределенный вид. Это хорошо, а что делать? Вот и узнал, что поплыл. Мы быстро переобучаем, да? Предположим, что ты делаешь сделки какие-то на основании рекомендаций. И у тебя модель предсказывает отожидание твоей успешности сделки, выручки. Ты смотришь, резко выросло положительное количество одобрений. Что ты делаешь? Бежишь в бизнес, и говоришь, ребята, у нас правда все так хорошо или у нас правда все так плохо? Если у нас так все хорошо, мы оставляем этот риск, который они приняли, бизнес принял этот риск. Если у нас все плохо, ты быстро порогами корректируешь так, чтобы количество одобрений было такое же, как и раньше. И идешь переобучать, наговаривая, что ты все сделаешь. Окей. Я, кажется, понял, наверное, что мы делаем. У нас достаточно жесткие стоят ручные где-то проверки. В том числе, сколько мы будем одобрять. Хорошо. Естественно, конечно, я бы еще, может быть, добавил, а, скорее всего, ты это подразумел, хорошо бы, конечно, вообще задуматься над этой всей темой и поставить какие-то ограничения с самого начала. Это, наверное, в твоем примере с ростом было. У нас тоже в моем первом проекте просто больше 5% мы не делали, не руководствовались этим. Мы работали с одними ребятами из Солнечной Калифорнии недавно, и у них просто валидация и обучение были из разных республик. Дело житийское. Ну, это не под ациентиски. Это действительно жизнь. Мне кажется, что это, конечно, достаточно грубая ошибка. И на Кагли все плачут из-за этого, что строили, строили, строили, а потом бах, и открыли что-то совсем не то. Поэтому здесь беда, за которую действительно не надо забывать. Отличный доклад. Действительно, тема очень животрепещущая. Мы в тайминг, похоже, Валя, уложились достаточно идеально. Или ты еще две минуты хочешь, чтобы мы рассказывали? Не хочешь. Хорошо. Тогда мы предлагаю уйти на перерыв. Перед этим, Дим, какой вопрос тебе понравился? Там человек предлагал сделать классификатор для классификации данных на хорошие и плохие. Мне это, знаешь, понравилось, как тот мем, который давай мы положим твой классификатор внутри своего классификатора, чтобы ты мог классифицировать свой классификатор. Клевый же вопрос. Да. Ну и действительно, так делаем иногда. Смотрим, насколько что поплыло. Круто!