chore: import upstream snapshot with attribution
This commit is contained in:
+149
File diff suppressed because one or more lines are too long
+120
@@ -0,0 +1,120 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Math behind LinearExplainer with correlation feature perturbation\n",
|
||||
"\n",
|
||||
"When we use `LinearExplainer(model, prior, feature_perturbation=\"correlation_dependent\")` we do not use $E[f(x) \\mid do(X_S = x_S)]$ to measure the impact of a set $S$ of features, but rather use $E[f(x) \\mid X_S = x_s]$ under the assumption that the random variable $X$ (representing the input features) follows a multivariate guassian distribution. To compute SHAP values this way we need to compute conditional expectations under the multivariate guassian distribution for all subset of features. This would be a lot of matrix match for an exponential number of terms, and it hence intractable for models with more than just a few features.\n",
|
||||
"\n",
|
||||
"This document briefly outlines the math we have used to precompute all of the required linear algebra using a sampling procedure that can be done just once, and then applied to as many samples as we like. This drastically speed up the computation compared to a brute force approach. Note that all these calculations depend on the fact that we are explaining a linear model $f(x) = \\beta x$."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The permutation definition of SHAP values in the interventional form used by most explainers is\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\phi_i = \\frac{1}{M!} \\sum_R E[f(X) \\mid do(X_{S_i^R \\cup i} = x_{S_i^R \\cup i})] - E[f(X) \\mid do(X_{S_i^R} = x_{S_i^R})]\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"but here we will use the non-interventional conditional expectation form (where we have simplified the notation by dropping the explicit reference to the random variable $X$).\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\phi_i = \\frac{1}{M!} \\sum_R E[f(x) \\mid x_{S_i^R \\cup i}] - E[f(x) \\mid x_{S_i^R}]\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"where $f(x) = \\beta x + b$ with $\\beta$ a row vector and $b$ a scalar."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If we replace f(x) with the linear function definition we get:\n",
|
||||
"\n",
|
||||
"\\begin{align}\n",
|
||||
"\\phi_i = \\frac{1}{M!} \\sum_R E[\\beta x + b \\mid x_{S_i^R \\cup i}] - E[\\beta x + b \\mid x_{S_i^R}] \\\\\n",
|
||||
" = \\beta \\frac{1}{M!} \\sum_R E[x \\mid x_{S_i^R \\cup i}] - E[x \\mid x_{S_i^R}]\n",
|
||||
"\\end{align}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Assume the inputs $x$ follow a multivariate normal distribution with mean $\\mu$ and covariance $\\Sigma$. Denote the projection matrix that selects a set $S$ as $P_S$, then we get:\n",
|
||||
"\n",
|
||||
"\\begin{align}\n",
|
||||
"E[x \\mid x_S] = [P_{\\bar S} \\mu + P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} ( P_S x - P_S \\mu)] P_{\\bar S} + x P_S^T P_S \\\\\n",
|
||||
"= [P_{\\bar S} \\mu + P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S (x - \\mu)] P_{\\bar S} + x P_S^T P_S \\\\\n",
|
||||
"= [\\mu + \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S (x - \\mu)] P_{\\bar S}^T P_{\\bar S} + x P_S^T P_S \\\\\n",
|
||||
"= P_{\\bar S}^T P_{\\bar S} [\\mu + \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S (x - \\mu)] + P_S^T P_S x \\\\\n",
|
||||
"= P_{\\bar S}^T P_{\\bar S} \\mu + P_{\\bar S}^T P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S x - P_{\\bar S}^T P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S \\mu + P_S^T P_S x \\\\\n",
|
||||
"= [P_{\\bar S}^T P_{\\bar S} - P_{\\bar S}^T P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S] \\mu + [P_S^T P_S + P_{\\bar S}^T P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S] x\n",
|
||||
"\\end{align}\n",
|
||||
"\n",
|
||||
"if we let $R_S = P_{\\bar S}^T P_{\\bar S} \\Sigma P_S^T (P_S \\Sigma P_S^T)^{-1} P_S$ and $Q_S = P_S^T P_S$ then we can write\n",
|
||||
"\n",
|
||||
"\\begin{align}\n",
|
||||
"E[x \\mid x_S] = [Q_{\\bar S} - R_S] \\mu + [Q_S + R_S] x\n",
|
||||
"\\end{align}\n",
|
||||
"\n",
|
||||
"or\n",
|
||||
"\n",
|
||||
"\\begin{align}\n",
|
||||
"E[x \\mid x_{S_i^R \\cup i}] = [Q_{\\bar{S_i^R \\cup i}} - R_{S_i^R \\cup i}] \\mu + [Q_{S_i^R \\cup i} + R_{S_i^R \\cup i}] x\n",
|
||||
"\\end{align}\n",
|
||||
"\n",
|
||||
"leading to the Shapley equation of\n",
|
||||
"\n",
|
||||
"\\begin{align}\n",
|
||||
"\\phi_i = \\beta \\frac{1}{M!} \\sum_R [Q_{\\bar{S_i^R \\cup i}} - R_{S_i^R \\cup i}] \\mu + [Q_{S_i^R \\cup i} + R_{S_i^R \\cup i}] x - [Q_{\\bar{S_i^R}} - R_{S_i^R}] \\mu - [Q_{S_i^R} + R_{S_i^R}] x \\\\\n",
|
||||
"= \\beta \\frac{1}{M!} \\sum_R ([Q_{\\bar{S_i^R \\cup i}} - R_{S_i^R \\cup i}] - [Q_{\\bar{S_i^R}} - R_{S_i^R}]) \\mu + ([Q_{S_i^R \\cup i} + R_{S_i^R \\cup i}] - [Q_{S_i^R} + R_{S_i^R}]) x \\\\\n",
|
||||
"= \\beta \\left [ \\frac{1}{M!} \\sum_R ([Q_{\\bar{S_i^R \\cup i}} - R_{S_i^R \\cup i}] - [Q_{\\bar{S_i^R}} - R_{S_i^R}]) \\right ] \\mu + \\beta \\left [ \\frac{1}{M!} \\sum_R ([Q_{S_i^R \\cup i} + R_{S_i^R \\cup i}] - [Q_{S_i^R} + R_{S_i^R}]) \\right ] x\n",
|
||||
"\\end{align}\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"$$\n",
|
||||
"\\phi = \\beta T x\n",
|
||||
"$$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This means that we can precompute the transform matrix $T$ by drawing random permutations $R$ many times and averaging our results. Once we have computed $T$ we can explain any number of samples (or models for that matter) by just using matrix multiplication."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
+320
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user