[МУЗЫКА] В этом видео мы обсудим, как можно понять для сложных моделей, вроде того же градиентного бустинга, какие признаки там важны и вообще, как получше разобраться в том, как эти модели устроены. Итак, есть большая тема в машинном обучении, которая называется интерпретацией моделей. Под интерпретацией может пониматься очень разное, но мы разберем только два вопроса, хотя, конечно, их может быть больше. Во-первых, мы с вами обсудим, как можно понять, какие признаки важны в целом для этой модели. То есть вообще на что она смотрит в первую очередь, какие признаки важны для этой задачи. И мы немного обсудим, как понять, какие признаки были важны для прогноза на конкретном объекте, то есть как объяснить прогноз модели на конкретном объекте. При этом, как я сказал, есть больше постановок задач в интепретации. Например, можно обсуждать, какие объекты в обучающей выборке дают самый большой вклад в качество модели и так далее и так далее, много чего. Начнем с того, как находить важные признаки в целом для модели. Тут есть разные подходы, я разберу тоже только некоторые из них, показательные. Есть большой класс методов, который называется одномерный набор признаков. В нем мы вообще забываем про модель и смотрим, какие признаки как-то коррелируют или как-то связаны с целевой переменной. Например, если мы решаем задачу регрессии, то что можно сделать? Можно взять и посчитать корреляцию конкретного, j-того признака, как на этой формуле, с целевой переменной. xij — это у меня значение j-того признака для i-того объекта, yi — это значение ответа целевой переменной для i-того объекта, xj с чертой и y с чертой — это средние значения j-того признака и целевой переменной соответственно. Это формула для корреляции, вы ее знаете. И вот по ней я считаю, насколько признак информативен. Если модуль корреляции близок к единице, значит, признак связан с целевой переменной. Если модуль близок к нулю, значит, скорее, не связан. В принципе, вот так можно посчитать важности признаков. При этом, конечно, у такого подхода куча проблем. В частности, корреляция плохо учитывает какие-то нелинейные связи между признаком и целевой переменной. Это значение будет высоким, только если я признак умножаю на какое-то число, прибавляю что-то, и из него получается хорошее приближение к целевой переменной. Есть еще одна проблема, которую я обсужу позже, но пока уже что-то такое есть не очень хорошее. Если мы решаем задачу бинарной классификации, можно посчитать вот такую величину, которая, если вы изучали статистику, должна вам напомнить критерий Стьюдента. Я беру признак, какой-то j-тый, считаю его среднее значение для одного класса и для другого: это μ1 и μ2. Да, я говорю про вариант этого метода только для бинарной классификации, для [НЕРАЗБОРЧИВО] класса есть обобщение некоторое, но не будем сейчас про него. Считаю разность этих средних значений признаков в классах и еще считаю дисперсии значений этого признака тоже в каждом классе. И вот по такой формуле считаю критерий. Чем больше его значение, тем более информативен признак, тем лучше по нему разделяются два класса. Но, опять же, у этого критерия, как и у предыдущего, у корреляции, есть такая проблема: они никак не учитывают комбинации признаков. Например, у меня может быть такая вот выборка, где есть два класса и четыре кучки объектов. Обратите внимание, что по отдельным признакам я не могу добиться хорошего качества классификации. Как, вот допустим, возьму первый признак, который по оси x, как бы я ни бил по этому признаку, у меня будет плохо, не будет какого-то нормального решения. По второму признаку то же самое. И если вы посчитаете для этой выборки какой-нибудь из критериев, которые были выше, они скажут, что оба признака отвратительные. Но при этом, если использовать признаки в комбинации, то получится идеально. Я разобью как бы крест-накрест мою выборку, и получится очень хорошее разбиение. Поэтому одномерные методы, скорее, могут быть хороши для какого-то очень предварительного отбора признаков, или если мне реально нужно найти какой-то один самый важный признак и я только его могу использовать, это может пригодиться, но в целом, понятно, что это не лучший вариант. Второй подход к поиску лучших признаков, к поиску важных признаков — это использование моделей. Например, мы с вами хорошо помним Lasso, модель, которая хорошо обучается с L1-регуляризацией, с штрафом на модуле весов. И наверное, вы помните, что такие модели позволяют отбирать признаки. Если я λ, коэффициент регуляризации, буду увеличивать, то у меня все больше весов будут зануляться, и в итоге я как бы стимулирую модель использовать только важные признаки. Таким образом, я могу, например, попробовать разные λ, посмотреть, какие признаки в любом случае остаются с ненулевыми весами, и наверное, это важные признаки. Вот я могу сказать, что именно на них модель смотрит в первую очередь. А как быть с деревьями? Вот с деревьями есть такой довольно понятный подход для измерения важности признаков. Как вы помните, когда мы строим дерево, мы выбираем лучший предикат в каждой вершине. Делаем это жадно. Чтобы выбрать лучший предикат, мы вводим некоторый критерий хаотичности, impurity criterion, для вершины, и я рассматриваю конкретный предикат с признаком j и порогом t и считаю эту хаотичность до разбиения и считаю хаотичности после разбиения. До разбиения у меня вершина m, после разбиения она бьется на вершину l и вершину r. Я считаю разность этих хаотичностей, и чем она больше, чем лучше мой предикат. Хорошо. Как этим воспользоваться? Например, следующим образом. Я могу взять конкретный j-тый признак и просуммировать эти изменения хаотичности по всем вершинам, где я использовал этот признак в предикате. И понятно, что чем больше будет эта сумма, тем сильнее этот признак позволил мне уменьшить хаотичность. Ну и тогда можно сказать, что если у меня есть дерево, то важность признака — это сумма в этих изменениях критерия хаотичности по всем вершинам, где использовался этот признак. Ну а если у меня композиция деревьев, то я могут просуммировать потом еще эти штуки по всем моим базовым моделям, по всем деревьям. И тоже получу важности признаков. Еще один способ изменения важности мы обсуждали, когда говорили про случайные леса. Давайте я кратко напомню, на самом деле этот метод применим для любых моделей. Он называется перестановочным методом и работает следующим образом. Я беру конкретный признак, беру тестовую выборку, беру матрицу объекты-признаки для нее и перемешиваю значения этого признака. То есть беру просто столбец, соответствующий j-тому признаку, и перемешиваю значение в нем. После этого мой j-тый признак становится бесполезным. Я применяю мою модель к этой испорченной тестовой выборке и смотрю, насколько там изменяется ее качество. Если качество модели падает сильно, значит, признак был важный: я его испортил, качество модели упало. Если же качество модели не меняется или, может, даже... Хотя улучшается вряд ли, вряд ли такое может быть, но если оно не изменяется или изменяется слабо, значит, моя модель не использовала этот признак, и он для нее неважен. Тоже есть вот такой подход. И наконец из таких методов поиска важных признаков есть, например, жадные методы отбора признаков. Начинаем со всей выборки и пробуем по одному выкинуть каждый признак. Смотрим, при выкидывании какого у меня получается наибольший прирост качества на тесте, или, может быть, при котором не изменяется, при выбрасывании которого не изменяется качество на тесте. Или, может быть, при выбрасывании которого качество незначительно уменьшается на тесте, нахожу лучший с этой точки зрения, выкидываю его. Дальше снова пробую все признаки выкидывать, смотрю, при выкидывании какого получается лучше всего. И вот так продолжаю, пока не будет выполнен некий критерий остановок. То есть я пытаюсь просто выкидывать признаки по одному и смотрю, как меняется качество моей модели, если она строится без этого признака. Проблема такого метода, конечно, в том, что мне придется очень много раз заново обучать мою модель. Хочу выкинуть какой-то признак, выкидываю, обучаю модель без него, считаю качество на тесте. Это очень долго, сложно, но, тем не менее, если есть время, то такой метод можно попробовать. Кстати, в нем еще можно начинать наброс пустого множества признаков и добавлять признаки по одному и вот смотреть тоже, какие признаки добавятся в первую очередь — наверное, это самые важные признаки. Окей. Это было про то, как считать важности признаков в целом для моделей и для выборки. А что если есть конкретный объект и я хочу понять именно для него, какие признаки были важны при построении прогноза? На этот случай тоже есть методы, и один из них называется LIME — Local Interpretable Model-Agnostic Explanations (прошу прощения за мой Runglish). Это метод, который позволяет понять, какие признаки сделали самый большой вклад в прогноз на данном конкретном объекте. И работает метод следующим образом. Есть объект x, и я хочу на нем объяснить прогноз моей модели a, хочу понять, как a(x) получился, из чего он сложен. Для этого, во-первых, я выбираю некоторое понятное интерпретируемое признаковое описание x с чертой для x. Если у меня признаки в целом объяснимы, например, в моем признаковом описании я ничего не делаю, x с чертой будет равен x. Но, например, если у меня x — это какая-то картинка, то там используются в качестве признаков описания некоторых частей картинки. Если x, например, — это какие-то десятки тысяч признаков не очень понятных, я могут взять из них только те, которые мне ясны, которые я смогу объяснить заказчику, например, что-то такое, и только их включу в x с чертой. Короче, в x с чертой должны быть только те признаки, которые мне понятны, вклад которых я смогу потом объяснить себе. Окей, построил такое понятное признаковое описание x с чертой. Дальше я генерирую похожие такие синтетические объекты. Например, я могу взять и случайным образом позанулять разными способами в x с чертой некоторые признаки. Если я знаю другие какие-то способы, как из x чертой сгенерировать похожие признаки, я это применяю. Например, может быть, немножко шум добавляю к каждому признаку или что-то еще. И в итоге получаю выборку x1 чертой, ..., xn с чертой объектов, которые находятся в окрестности x. Это локальная, небольшая окрестность объекта x с чертой, которая позволит мне обучить какую-то модель. Хорошо. У меня есть окрестность объекта x чертой — вот это x1, ..., xn, эти объекты. Я на них обучаю новую модель, которая интерпретируемая, например, линейная, чтобы она предсказывала выходы модели a. Я обучаю на этой выборке некоторую простую понятную модель, которая только в окрестности объекта x должна приближать мою сложную модель a. Получаю новую модель a с чертой, и поскольку я ее выбрал интерпретируемой, это, например, линейная модель, которая еще с L1-регуляризации была обучена, поэтому она от малого числа признаков будет зависеть, и я смотрю, от каких признаков она зависит сильнее. И поскольку я эту модель обучил только на окрестности некоторого объекта, она будет характеризовать важности признаков именно для этого объекта и для похожих на него. И именно так я понимаю, какие признаки оказались самыми важными. Итак, мы обсудили с вами, как интерпретировать модель, что есть разные подходы, мы поговорили, как можно вычислять важности признаков в целом для конкретной модели, в частности, для деревьев, поговорили о том, какие есть способы. И обсудили, что есть методы, которые позволяют интерпретировать прогноз модели для конкретного объекта. Я рассказал только один метод, их сильно больше. Ну просто вы теперь знаете, как в целом можно подойти к этой задаче. [МУЗЫКА]