Skip to content

Commit 83b690f

Browse files
authored
Merge pull request #1 from Leo02016/SIF_develop
Sif develop
2 parents b2dc3b9 + 35fd6ac commit 83b690f

File tree

6 files changed

+88
-57
lines changed

6 files changed

+88
-57
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ python:
66
install:
77
- pip3 install --upgrade setuptools==41.0.0
88
- pip3 install .
9-
#- pip3 install -r requirements.txt
9+
# - pip3 install -r requirements.txt
1010

1111
# commands to run tes
1212
# before_script: redis-cli ping
@@ -23,6 +23,7 @@ script:
2323
- python3.6 ./tests/lime/test_lime.py
2424
- python3.6 ./tests/shap/test_shap.py
2525
- python3.6 ./tests/sif/test_SIF.py
26+
- python3.6 ./tests/sif/test_SIF.py
2627
after_success:
2728
# - codecov
2829

aix360/algorithms/sif/SIF.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
from abc import ABC, abstractmethod
1818
from aix360.datasets.SIF_dataset import DataSet
1919
from scipy.stats import linregress
20+
from aix360.algorithms.lbbe import LocalBBExplainer
2021

2122

22-
class SIF_NeuralNet(ABC):
23+
class SIFExplainer(LocalBBExplainer):
2324
def __init__(self, **kwargs):
2425
'''
2526
Initialize the SIF neural network
@@ -175,6 +176,20 @@ def __init__(self, **kwargs):
175176
self.non_nan_y_cont_idx = []
176177
super().__init__()
177178

179+
def set_params(self, **kwargs):
180+
"""
181+
Optionally, set parameters for the explainer.
182+
"""
183+
pass
184+
185+
def explain_instance(self, y_contaminate, index, patchy_k, gammas=None, expectation_rep_time=10, verbose=True,
186+
is_ar=False, short_memo=True):
187+
"""
188+
Explain one or more input instances.
189+
"""
190+
sif = self.get_sif(y_contaminate, index, patchy_k, gammas, expectation_rep_time, verbose, is_ar, short_memo)
191+
return sif
192+
178193
def update_configure(self, y_contaminate, gammas):
179194
'''
180195
y_contaminate: the contaminating process

aix360/algorithms/sif/SIF_NN.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
from __future__ import absolute_import
44
from __future__ import unicode_literals
55
import tensorflow as tf
6-
from aix360.algorithms.sif.SIF import SIF_NeuralNet
6+
from aix360.algorithms.sif.SIF import SIFExplainer
77
from aix360.datasets.SIF_dataset import DataSet
88

99

10-
class AllAR(SIF_NeuralNet):
10+
class AllAR(SIFExplainer):
1111
def __init__(self, x_dim, y_dim, time_steps, share_param, **kwargs):
1212
self.time_steps = time_steps
1313
self.x_dim = x_dim
@@ -58,9 +58,9 @@ def inference(self, input_x, labels_placeholder=None, keep_probs_placeholder=Non
5858
def predictions(self, logits):
5959
preds = logits
6060
return preds
61+
6162

62-
63-
class AllLSTM(SIF_NeuralNet):
63+
class AllLSTM(SIFExplainer):
6464
def __init__(self, x_dim, y_dim, time_steps, num_units, share_param, **kwargs):
6565
self.time_steps = time_steps
6666
self.x_dim = x_dim
@@ -126,8 +126,7 @@ def predictions(self, logits):
126126
return preds
127127

128128

129-
130-
class AllRNN(SIF_NeuralNet):
129+
class AllRNN(SIFExplainer):
131130
def __init__(self, x_dim, y_dim, time_steps, num_units, share_param, **kwargs):
132131
self.time_steps = time_steps
133132
self.x_dim = x_dim

examples/sif/SIF.ipynb

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
{
22
"cells": [
33
{
4-
"cell_type": "code",
5-
"execution_count": 10,
6-
"outputs": [],
4+
"cell_type": "markdown",
75
"source": [
8-
"import numpy as np\n",
9-
"import statsmodels.tsa.api as smt\n",
10-
"import matplotlib.pyplot as plt\n",
11-
"from aix360.datasets.SIF_dataset import DataSetTS\n",
12-
"from aix360.algorithms.sif.SIF_NN import AllRNN, AllLSTM, AllAR\n",
13-
"from aix360.algorithms.sif.SIF_utils import get_contaminate_series\n",
14-
"import os\n",
15-
"import pickle"
6+
"# SIF Explainer Tutorial\n",
7+
"#### This tutorial illustrates the use of SIF algorithm, a comprehensive single-valued metric, to measure outlier impacts on future predictions. It provides a quantitative measure regarding the outlier impacts, which can be used in a variety of scenarios, such as the evaluation of outlier detection methods, the creation of more harmful outliers, etc. This is a demonstration for AAAI-2021 paper [Outlier Impact Characterization for Time Series Data](https://ojs.aaai.org/index.php/AAAI/article/view/17379).\n",
8+
"#### SIF algorithm mainly tackles the challenge of outlier interpretation in time series data via [contamination processes](https://www.jstor.org/stable/pdf/3035535.pdf). It assumes that the observed input time series is obtained from separate processes for both the core input and the recurring outliers, i.e., the core process and the contaminating process. At each time stamp, with a certain (small) probability, the observed value of the contaminated process comes from the contaminating process, which corresponds to the outliers. The SIF algorithm focuses on the generic patchy outliers where the outlying patterns can be present over consecutive time stamps, and aims to study the impact of the contaminating process on both parameter estimation and future value prediction.\n",
9+
"#### The tutorial is organized as folows:\n",
10+
"#### 1. [Train a Model Inherited from SIFExplainer](https://github.com/Leo02016/AIX360/blob/dc0efab88b90f225427347b080897a3e19792403/examples/sif/SIF.ipynb#L12)\n",
11+
"#### 2. [Initialize the Required Parameters and Synthesize the Dataset](https://github.com/Leo02016/AIX360/blob/dc0efab88b90f225427347b080897a3e19792403/examples/sif/SIF.ipynb#L61)\n",
12+
"#### 3. [Interpret the Model by SIF Value](https://github.com/Leo02016/AIX360/blob/dc0efab88b90f225427347b080897a3e19792403/examples/sif/SIF.ipynb#L139)"
1613
],
1714
"metadata": {
18-
"collapsed": false,
19-
"pycharm": {
20-
"name": "#%%\n",
21-
"is_executing": false
22-
}
15+
"collapsed": false
2316
}
2417
},
2518
{
2619
"cell_type": "markdown",
2720
"source": [
28-
"#### model below can be changed to AllLSTM or AllRNN model defined in SIF_NN.py"
21+
"## 1. Train a Model Inherited from SIFExplainer\n",
22+
"#### First, we define a function that trains a AR2 model inherited from SIFExplainer and this model (AR2) is what we are going to interpret. Notice that the AR2 model below can be changed to AllLSTM or AllRNN model defined in SIF_NN.py file. AllRNN, AllLSTM, AllAR are also inherited from SIFExplainer Model defined in SIF.py file."
2923
],
3024
"metadata": {
3125
"collapsed": false,
@@ -36,9 +30,26 @@
3630
},
3731
{
3832
"cell_type": "code",
39-
"execution_count": 11,
40-
"outputs": [],
33+
"execution_count": 1,
34+
"outputs": [
35+
{
36+
"name": "stderr",
37+
"text": [
38+
"Using TensorFlow backend.\n"
39+
],
40+
"output_type": "stream"
41+
}
42+
],
4143
"source": [
44+
"import numpy as np\n",
45+
"import statsmodels.tsa.api as smt\n",
46+
"import matplotlib.pyplot as plt\n",
47+
"from aix360.datasets.SIF_dataset import DataSetTS\n",
48+
"from aix360.algorithms.sif.SIF_NN import AllRNN, AllLSTM, AllAR\n",
49+
"from aix360.algorithms.sif.SIF_utils import get_contaminate_series\n",
50+
"import os\n",
51+
"import pickle\n",
52+
"\n",
4253
"# arma2 model\n",
4354
"def get_model_train_ar2(data_sets, series, timesteps, w=None, gammas=None, num_train_steps=20000,\n",
4455
" model_dir=None):\n",
@@ -85,7 +96,9 @@
8596
{
8697
"cell_type": "markdown",
8798
"source": [
88-
"#### In default, we use the fast mode to accelerate the computation.\n"
99+
"## 2. Initialize the Required Parameters and Synthesize the Dataset\n",
100+
"#### In the second step, we initialize the parameters for SIFExplainer. \n",
101+
"#### By default, we use the fast mode to accelerate the computation. In the fast mode, we load the pre-trained AR2 model and dataset to skip training stage. If the user plans to retrain the AR2 model, please set the parameter [fast_mode](https://github.com/Leo02016/AIX360/blob/dc0efab88b90f225427347b080897a3e19792403/examples/sif/SIF.ipynb#L65) to be False. Then, the algorithm will generate a new synthetic dataset and train AR2 model from scratch.\n"
89102
],
90103
"metadata": {
91104
"collapsed": false,
@@ -96,7 +109,7 @@
96109
},
97110
{
98111
"cell_type": "code",
99-
"execution_count": 14,
112+
"execution_count": 2,
100113
"outputs": [],
101114
"source": [
102115
"fast_mode = True\n",
@@ -130,7 +143,7 @@
130143
},
131144
{
132145
"cell_type": "code",
133-
"execution_count": 15,
146+
"execution_count": 3,
134147
"outputs": [],
135148
"source": [
136149
"data_dir = '../../aix360/data/sif_data/data.pkl'\n",
@@ -155,24 +168,24 @@
155168
},
156169
{
157170
"cell_type": "code",
158-
"execution_count": 16,
171+
"execution_count": 4,
159172
"outputs": [
160173
{
161174
"name": "stdout",
162175
"text": [
163-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF_NN.py:18: The name tf.random_normal is deprecated. Please use tf.random.normal instead.\n\n",
164-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:28: The name tf.set_random_seed is deprecated. Please use tf.compat.v1.set_random_seed instead.\n\n",
165-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF_NN.py:38: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n\n",
166-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:634: The name tf.squared_difference is deprecated. Please use tf.math.squared_difference instead.\n\n",
167-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:639: The name tf.is_nan is deprecated. Please use tf.math.is_nan instead.\n\n",
176+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF_NN.py:18: The name tf.random_normal is deprecated. Please use tf.random.normal instead.\n\n",
177+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:29: The name tf.set_random_seed is deprecated. Please use tf.compat.v1.set_random_seed instead.\n\n",
178+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF_NN.py:38: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n\n",
179+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:649: The name tf.squared_difference is deprecated. Please use tf.math.squared_difference instead.\n\n",
180+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:654: The name tf.is_nan is deprecated. Please use tf.math.is_nan instead.\n\n",
168181
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Anaconda3\\envs\\tf_115\\lib\\site-packages\\tensorflow_core\\python\\ops\\array_ops.py:1475: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\nInstructions for updating:\nUse tf.where in 2.0, which has the same broadcast rule as np.where\n",
169-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:642: The name tf.add_to_collection is deprecated. Please use tf.compat.v1.add_to_collection instead.\n\n",
170-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:644: The name tf.get_collection is deprecated. Please use tf.compat.v1.get_collection instead.\n\n",
171-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:95: The name tf.assign is deprecated. Please use tf.compat.v1.assign instead.\n\n",
172-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:599: The name tf.train.AdamOptimizer is deprecated. Please use tf.compat.v1.train.AdamOptimizer instead.\n\n",
173-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:610: The name tf.train.GradientDescentOptimizer is deprecated. Please use tf.compat.v1.train.GradientDescentOptimizer instead.\n\n",
174-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:103: The name tf.train.Saver is deprecated. Please use tf.compat.v1.train.Saver instead.\n\n",
175-
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Desktop\\SIF\\aix360\\algorithms\\sif\\SIF.py:160: The name tf.global_variables_initializer is deprecated. Please use tf.compat.v1.global_variables_initializer instead.\n\n",
182+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:657: The name tf.add_to_collection is deprecated. Please use tf.compat.v1.add_to_collection instead.\n\n",
183+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:659: The name tf.get_collection is deprecated. Please use tf.compat.v1.get_collection instead.\n\n",
184+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:96: The name tf.assign is deprecated. Please use tf.compat.v1.assign instead.\n\n",
185+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:614: The name tf.train.AdamOptimizer is deprecated. Please use tf.compat.v1.train.AdamOptimizer instead.\n\n",
186+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:625: The name tf.train.GradientDescentOptimizer is deprecated. Please use tf.compat.v1.train.GradientDescentOptimizer instead.\n\n",
187+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:104: The name tf.train.Saver is deprecated. Please use tf.compat.v1.train.Saver instead.\n\n",
188+
"WARNING:tensorflow:From C:\\Users\\lecheng4\\Documents\\GitHub\\AIX360\\aix360\\algorithms\\sif\\SIF.py:161: The name tf.global_variables_initializer is deprecated. Please use tf.compat.v1.global_variables_initializer instead.\n\n",
176189
"Total number of parameters: 2\nLoading pre-trained model......\nINFO:tensorflow:Restoring parameters from ../../aix360/models/sif/ar2\n"
177190
],
178191
"output_type": "stream"
@@ -221,10 +234,11 @@
221234
},
222235
{
223236
"cell_type": "code",
224-
"execution_count": 17,
237+
"execution_count": 5,
225238
"outputs": [],
226239
"source": [
227-
"y_contaminate = np.random.randn(n_sample)"
240+
"y_contaminate = np.random.randn(n_sample)\n",
241+
"model.update_configure(y_contaminate, gammas)"
228242
],
229243
"metadata": {
230244
"collapsed": false,
@@ -248,15 +262,14 @@
248262
},
249263
{
250264
"cell_type": "code",
251-
"execution_count": 18,
265+
"execution_count": 9,
252266
"outputs": [],
253267
"source": [
254268
"contaminated_series = get_contaminate_series(series, y_contaminate, data_sets.train.labels)\n",
255-
"\n",
256269
"# plot contaminated series\n",
257-
"plt.plot(contaminated_series)\n",
258-
"plt.savefig('arma')\n",
259-
"plt.close()\n"
270+
"# plt.plot(contaminated_series)\n",
271+
"# plt.show()\n",
272+
"# plt.close()\n"
260273
],
261274
"metadata": {
262275
"collapsed": false,
@@ -269,28 +282,28 @@
269282
{
270283
"cell_type": "markdown",
271284
"source": [
272-
"#### compute SIF value"
285+
"## 3. Interpret the Model by SIF Value\n",
286+
"#### In the last step, we compute SIF value. Notice that the model is inherited from SIFExplainer and the user could simply call model.explain_instance() function to get the SIF value."
273287
],
274288
"metadata": {
275289
"collapsed": false
276290
}
277291
},
278292
{
279293
"cell_type": "code",
280-
"execution_count": 19,
294+
"execution_count": 8,
281295
"outputs": [
282296
{
283297
"name": "stdout",
284298
"text": [
285-
"Regression R-squared: 0.270422\nRegression R-squared: 0.149079\n54.085068464279175 s to compute if_v\n0.0359044075012207 s to compute patchy pred gamma\n0.06781840324401855 s to compute psi_y\nSIF = 166.51340947947648\n"
299+
"Regression R-squared: 0.179848\n162.92198777198792 s to compute if_v\n0.03913569450378418 s to compute patchy pred gamma\n0.0718080997467041 s to compute psi_y\nSIF = -119.54141353277345\n"
286300
],
287301
"output_type": "stream"
288302
}
289303
],
290304
"source": [
291305
"# compute SIF value\n",
292-
"model.update_configure(y_contaminate, gammas)\n",
293-
"sif = model.get_sif(y_contaminate, timesteps, 1, None, 30, verbose=False)\n",
306+
"sif = model.explain_instance(y_contaminate, timesteps, 1, None, 30, verbose=False)\n",
294307
"print('SIF = {}'.format(sif))\n"
295308
],
296309
"metadata": {
@@ -332,4 +345,4 @@
332345
},
333346
"nbformat": 4,
334347
"nbformat_minor": 2
335-
}
348+
}

requirement.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
statsmodels==0.11.1
2+
matplotlib==3.3.1

tests/sif/test_SIF.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ def test_SIF(self):
9898

9999
# compute SIF value
100100
model.update_configure(y_contaminate, gammas)
101-
sif = model.get_sif(y_contaminate, timesteps, 1, None, 30, verbose=False)
101+
# sif = model.get_sif(y_contaminate, timesteps, 1, None, 30, verbose=False)
102+
sif = model.explain_instance(y_contaminate, timesteps, 1, None, 30, verbose=False)
102103
print('SIF = {}'.format(sif))
103104

104105

0 commit comments

Comments
 (0)