ML: Интерпретируемость моделей


Введение

Интерпретируемость или объяснение моделей является важным этапом машинного обучения. Он состоит из двух частей. Во-первых - это анализ того, какие признаки и части модели важны для её работы. Во-вторых - это объяснение результата работы модели для конкретного примера (что и как на результат повлияло).

Первая часть важна при работе над совершенствованием модели. В частности, иногда малозначимые признаки создают шум, усложняющий обучение, поэтому их ликвидация может оказаться полезной. Анализ работы различных частей (например веток дерева принятия решения или различных слоёв в свёрточной нейронной сети), может подсказать путь к улучшению структуры модели.

Интерпретация поведения модели для конкретного примера важна в продакшене, когда пользователь модели должен получить внятные объяснения, почему модель поступила именно так. Это повышает доверие к её работе, делая чёрный ящик с машинным обучением не таким чёрным. Люди боятся того, чего не понимают :).


Линейная модель

Линейная модель (регрессия или логиcтическая регрессия) является, самой простой моделью в машинном обучении с учителем. Пусть есть $n$ вещественных признаков $\mathcal{X}=\{x_1,...,x_n\}$ и один или несколько целевых значений $y$, которые требуется предсказать. Предполагается, что есть $N$ обучающих примеров $\{(\hat{\mathbf{x}},\hat{y})^{(1)},...,(\hat{\mathbf{x}},\hat{y})^{(N)}\}$. При помощи, например, sklearn несложно найти параметры $\beta_i$ модели: $$ y = \beta_0 + \beta_1\,x_1+...+\beta_n\,x_n. $$ Эти параметры содержат информацию о вкладе каждого признака. Однако, так признаки, в общем случае, могут иметь различные масштабы, сами по себе $\beta_i$ пока ни о чём не говорят. Запишем уравнение регрессии в нормализованном виде: $$ \frac{y-\bar{y}}{\sigma_y} = \tilde{\beta}_1\frac{x_1-\bar{x}_1}{\sigma_i}+...+\tilde{\beta}_n\frac{x_n-\bar{x}_n}{\sigma_n}, $$ где средние значения $\bar{y}$, $\bar{x}_i$ и стандартные отклонения $\sigma_y=\sqrt{\langle(y-\bar{y})^2\rangle}$, $\sigma_i=\sqrt{\langle(x_i-\bar{x}_i)^2\rangle}$ оцениваются по обучающим данным: $\langle A \rangle=\sum^N_{k=1} A^{(k)}/N$. Средние значения правой и левой части этого уравнения равны нулю, поэтому смещение $\tilde{\beta}_0$ отсутствует. Если все величины $y$, $x_i$ имеют нормальное распределение или хотя-бы унимодулярное (с одним максимумом), то абсолютные значения параметров $\tilde{\beta_i}$ уже можно интерпретировать как степень важности данного признака. Несложно видеть, что: $$ \tilde{\beta}_i = \beta_i\,\frac{\sigma_i}{\sigma_y},~~~~~~~~~~~~~\beta_0=\bar{y} - (\beta_1\bar{x}_1+...+\beta_n\bar{x}_n). $$ Поэтому, получив $\beta_i$ при помощи sklearn, следует вычислить стандартные отклонения $\sigma_y$ и $\sigma_i$ и оценивать важность признаков уже по параметрам $\tilde{\beta}_i$ (можно и лучше, конечно, нормализацию данных проводить до построения модели).

Следует помнить, что для не унимодулярных (несколько максимумов) или сильно несимметричных распределений среднее значение $\bar{x}_i$ уже не характеризует "типичного" значения $i$-того признака, а стандартное отклонение $\sigma_i$ может уже не быть "возможным" отклонением от среднего. Поэтому важным этапом является предварительный анализ обучающих данных: гистограммы признаков и целевых величин, вычисление статистик, корреляционная матрица, анализ и возможное исключение выбросов и т.п. В противном случае интерпретационные разговоры будут злостным обманом.


Корреляция признаков

Просто исключать признаки с малыми $\tilde{\beta}_i$ в общем случае неверно. Может быть ситуация, когда есть несколько сильно скоррелированных признаков с небольшими $\tilde{\beta}_i$, которые в сумме дают значимый вклад в целевое значение.

Отметим ещё один важный момент при анализе регрессионной модели. Может оказаться, что данные на самом деле "лежат" не на $n$-мерной плоскости, а на плоскости меньшей размерности. При этомвсе признаки могут участвовать в её формировании. Простым свидетельством этого являются малые собственные значения ковариационной матрицы (см. метод PCA). Рассмотрим простой пример. Создадим датасет из $N$ примеров и построим регрессию, в которой "выключим" один признак:

import numpy as np
from sklearn.linear_model import LinearRegression

N, n = 10000, 4                                # примеров, признаков
Xp = np.random.normal( size=(N,n) )   
beta = np.array([1,1,1,0])                     # отключаем 4-й признак
Y  = (beta*Xp).sum(axis=1)                     # целевые значения
Теперь создадим случайную матрицу при помощи которой перемешаем признаки:
R = np.random.normal(0, 3, size=(n,n) )        # матрица перемешивания
R = R @ R.T                                    # делаем её симметричной
X = Xp @ R.T                                   # перемешанные признаки
Применим к получившимся данным линейную регрессию:
reg = LinearRegression().fit(X,Y)              # регрессия
print("beta: ", reg.coef_.T)                   #  [ 1.23 -0.42  2.41 -1.82]
print("beta0:", reg.intercept_)                #  0.

meanX, stdX = X.mean(axis=0), X.std(axis=0)    # статистики
meanY, stdY = Y.mean(axis=0), Y.std(axis=0)
print( reg.coef_.T * stdX/stdY )               # [ 48. -11. 25. -25.]

np.corrcoef(X.T)                               # корреляции

[[ 1.     0.048 -0.969  0.91 ]
 [ 0.048  1.     0.078 -0.318]
 [-0.969  0.078  1.    -0.884]
 [ 0.91  -0.318 -0.884  1.   ]]
Нормированные коэффициенты модели показывают, что второй признак на самом деле достаточно значим (вместо -0.42 мы теперь получаем -11).

Однако сами по себе параметры не говорят о "скрытой закономерности", заложенной в данные. Вычислим собственные значения ковариационной матрицы:

cov = np.cov(X.T)
w, v = np.linalg.eig(cov)
print("eig:", w)                               # [5246. 2330.  0.08   36.]
Теперь видно, что одно собственное значение существенно меньше остальных.


Значение Шепли

Пусть есть модель зависящая от $n$ признаков (переменных): $y=f(x_1,...,x_n)$. Мы хотим выяснить значимость признака $x_i$ в множестве $\mathcal{X}=\{x_1,...,x_n\}$, т.е. важность его вклада в результат работы модели. Для этого исключим его множества признаков $\mathcal{X}\setminus x_i$ и возьмём все возможные подмножества получившегося множества, Вычислим значение модели $$ v(x_i) = \sum_{S\,\subseteq\, \mathcal{X}\setminus x_i} \frac{y\bigr(S\cup \{x_i\}\bigr)-y\bigr(S\bigr)}{ {n \choose 1,\,~ |S|,\,~ n - |S| - 1}} $$ Мультиномиальный коэффициент для трёх нижних индексов $$ {n \choose k_1, k_2, k_3}=\frac{n!}{k_1!\,k_2!\,k_3!},~~~~~~~~(x_1+x_2+x_3)^n = \sum_{k_1+k_2+k_3=n} {n \choose k_1, k_2, k_3} x^{k_1}_1\,x^{k_2}_2\,x^{k_2}_2 $$ имеет смысл числа возможных способов размещения $n$ объектов по трём ячейкам. При этом $k_1$ предметов находится в первой ячейке, $k_2$ во второй и т.д. Например, пусть есть четыре признака: $\mathcal{X}=\{x_1,x_2,x_3,x_4\}$. Исключим из него первый признак: $\mathcal{X}\setminus x_1= \{x_2,x_3,x_4\}$. Соответственно возможно $8=2^3$ подмножеств $\mathcal{X}\setminus x_1$ (включая пустое): $$ S:~~~~\{\},~~~~~~\{x_2\},~~~~\{x_3\},~~~~\{x_4\},~~~~~\{x_2,x_3\},~~~~~\{x_2,x_4\},~~~~~\{x_3,x_4\},~~~~~\{x_2,x_3,x_4\} $$ В результате, значение ценности $x_1$ равно: $$ v(x_1) = \begin{array}{l} \frac{y(x_1)-y()}{4}+\frac{y(x_1,x_2)-y(x_2)}{12}+\frac{y(x_1,x_3)-y(x_3)}{12}+\frac{y(x_1,x_4)-y(x_4)}{12}+\\ \frac{y(x_1,x_2,x_3)-y(x_2,x_3)}{12}+\frac{y(x_1,x_2,x_4)-y(x_2,x_4)}{12}+\frac{y(x_1,x_3,x_4)-y(x_3,x_4)}{12}+\frac{y(x_1,x_2,x_3,x_4)-y(x_2,x_3,x_4)}{4} \end{array} $$
$$ \varepsilon_i\sim\mathcal{N}(0,1),~~~\mathbf{x}=\{\varepsilon_1,...,\varepsilon_n\}~~~~~~~~\mathbf{x}^2 = \langle \varepsilon^2_1 + ... + \varepsilon^2_n \rangle = 1 + ... + 1 = n,~~~~~~~~~\sqrt{1024} = 32 $$ $$ d^2 = (\mathbf{x}_q - \mathbf{x}_i)^2 $$ $$ y_i = \sum^{1024}_{j=1} W_{ij} x_j ~~+~~ b_i,~~~~~~~~~~~x:(1024,),~~y:(64,),~~~W:(64,1024) $$ $$ \mathbf{x} = \{x_1,\,x_2,\,x_3,\,x_4,\,x_5,\,x_6\},~~~~~~~~~\mathbf{y}=\{x_1+x_2+x_3,\, x_4+x_5+x_6\} $$ $$ \mathbf{y}^2 = x^2_1+x^2_2+x^2_3 + x^2_4+x^2_5+x^2_6 + 2\,(x_1x_2+x_1x_3+x_2x_3)+ 2\,(x_4x_5+x_4x_6+x_5x_6) $$