Note
Click here to download the full example code
06. Basic example
Out:
Shapes:
i: (100, 2)
y: (10,)
x: (10, 10, 5)
Data ((10, 10, 5)):
[[[23 41 81 17 63]
[ 2 14 27 4 31]
[88 88 47 88 57]
[80 81 98 28 5]
[94 57 44 96 35]
[34 3 23 47 63]
[97 7 66 23 85]
[75 9 88 67 59]
[30 58 39 91 19]
[64 14 8 66 86]]
[[13 38 20 42 14]
[57 83 7 29 31]
[83 75 11 3 32]
[10 54 80 1 75]
[19 80 57 99 58]
[38 62 20 14 9]
[90 83 23 48 32]
[49 52 71 92 18]
[82 10 16 55 50]
[ 0 13 88 31 43]]
[[26 91 3 1 83]
[80 19 79 55 34]
[84 54 51 9 30]
[84 34 95 51 56]
[17 64 2 78 40]
[ 6 24 67 68 49]
[46 77 53 78 33]
[ 6 75 17 22 64]
[35 47 69 65 20]
[ 5 69 54 65 45]]
[[ 2 93 76 84 38]
[42 20 11 96 42]
[43 12 94 30 14]
[65 66 66 44 86]
[65 22 10 8 68]
[38 29 1 46 56]
[91 84 11 44 22]
[ 6 73 18 64 12]
[39 61 52 77 98]
[ 9 80 69 94 42]]
[[97 57 57 4 72]
[85 22 24 61 34]
[87 94 59 27 19]
[36 76 56 78 26]
[14 9 58 30 1]
[59 71 6 98 88]
[35 31 79 44 70]
[30 89 88 18 49]
[43 11 14 53 51]
[ 0 66 42 26 46]]
[[69 97 35 71 45]
[38 32 34 29 24]
[80 93 3 30 5]
[ 7 25 63 50 62]
[74 49 16 52 10]
[94 72 6 22 82]
[43 19 32 10 51]
[ 2 2 12 77 99]
[82 8 93 61 44]
[13 87 67 86 3]]
[[74 73 64 57 33]
[46 95 99 60 87]
[16 1 45 29 27]
[44 9 89 41 58]
[48 60 65 30 25]
[80 26 57 76 47]
[47 45 24 89 34]
[67 30 7 20 79]
[33 92 28 62 97]
[24 66 83 55 46]]
[[58 91 23 65 86]
[15 10 57 44 62]
[ 6 80 51 45 58]
[48 22 28 82 29]
[25 56 14 14 76]
[89 64 46 63 50]
[ 1 51 18 66 98]
[26 1 89 74 94]
[28 32 85 2 48]
[ 7 17 90 19 80]]
[[61 66 98 61 96]
[60 71 80 98 97]
[93 38 12 32 6]
[52 18 58 18 70]
[80 65 32 98 59]
[ 3 97 86 38 12]
[49 97 2 43 27]
[82 82 68 17 19]
[72 33 91 97 96]
[47 92 21 99 95]]
[[53 7 86 30 2]
[48 75 21 15 23]
[17 36 13 59 24]
[30 21 76 51 34]
[87 46 82 99 62]
[77 60 33 11 21]
[34 68 76 67 30]
[ 8 48 64 73 84]
[16 93 9 99 94]
[85 29 79 55 95]]]
DataFrame (2D)
id t f0 f1 f2 f3 f4
0 0 0 23 41 81 17 63
1 0 1 2 14 27 4 31
2 0 2 88 88 47 88 57
3 0 3 80 81 98 28 5
4 0 4 94 57 44 96 35
.. .. .. .. .. .. .. ..
95 9 5 77 60 33 11 21
96 9 6 34 68 76 67 30
97 9 7 8 48 64 73 84
98 9 8 16 93 9 99 94
99 9 9 85 29 79 55 95
[100 rows x 7 columns]
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm (LSTM) (None, 64) 17920
dense (Dense) (None, 64) 4160
dense_1 (Dense) (None, 1) 65
=================================================================
Total params: 22,145
Trainable params: 22,145
Non-trainable params: 0
_________________________________________________________________
None
Train on 10 samples
Epoch 1/16
10/10 [==============================] - ETA: 0s - loss: 0.7290 - acc: 0.3000
10/10 [==============================] - 0s 16ms/sample - loss: 0.7290 - acc: 0.3000
Epoch 2/16
10/10 [==============================] - ETA: 0s - loss: 0.6919 - acc: 0.4000
10/10 [==============================] - 0s 304us/sample - loss: 0.6919 - acc: 0.4000
Epoch 3/16
10/10 [==============================] - ETA: 0s - loss: 0.6580 - acc: 0.5000
10/10 [==============================] - 0s 256us/sample - loss: 0.6580 - acc: 0.5000
Epoch 4/16
10/10 [==============================] - ETA: 0s - loss: 0.6270 - acc: 0.6000
10/10 [==============================] - 0s 256us/sample - loss: 0.6270 - acc: 0.6000
Epoch 5/16
10/10 [==============================] - ETA: 0s - loss: 0.6002 - acc: 0.6000
10/10 [==============================] - 0s 262us/sample - loss: 0.6002 - acc: 0.6000
Epoch 6/16
10/10 [==============================] - ETA: 0s - loss: 0.5756 - acc: 0.6000
10/10 [==============================] - 0s 276us/sample - loss: 0.5756 - acc: 0.6000
Epoch 7/16
10/10 [==============================] - ETA: 0s - loss: 0.5517 - acc: 0.6000
10/10 [==============================] - 0s 274us/sample - loss: 0.5517 - acc: 0.6000
Epoch 8/16
10/10 [==============================] - ETA: 0s - loss: 0.5298 - acc: 0.6000
10/10 [==============================] - 0s 265us/sample - loss: 0.5298 - acc: 0.6000
Epoch 9/16
10/10 [==============================] - ETA: 0s - loss: 0.5094 - acc: 0.8000
10/10 [==============================] - 0s 281us/sample - loss: 0.5094 - acc: 0.8000
Epoch 10/16
10/10 [==============================] - ETA: 0s - loss: 0.4905 - acc: 0.8000
10/10 [==============================] - 0s 271us/sample - loss: 0.4905 - acc: 0.8000
Epoch 11/16
10/10 [==============================] - ETA: 0s - loss: 0.4724 - acc: 0.8000
10/10 [==============================] - 0s 261us/sample - loss: 0.4724 - acc: 0.8000
Epoch 12/16
10/10 [==============================] - ETA: 0s - loss: 0.4546 - acc: 0.8000
10/10 [==============================] - 0s 279us/sample - loss: 0.4546 - acc: 0.8000
Epoch 13/16
10/10 [==============================] - ETA: 0s - loss: 0.4367 - acc: 0.9000
10/10 [==============================] - 0s 271us/sample - loss: 0.4367 - acc: 0.9000
Epoch 14/16
10/10 [==============================] - ETA: 0s - loss: 0.4193 - acc: 0.9000
10/10 [==============================] - 0s 271us/sample - loss: 0.4193 - acc: 0.9000
Epoch 15/16
10/10 [==============================] - ETA: 0s - loss: 0.4028 - acc: 0.9000
10/10 [==============================] - 0s 265us/sample - loss: 0.4028 - acc: 0.9000
Epoch 16/16
10/10 [==============================] - ETA: 0s - loss: 0.3865 - acc: 0.9000
10/10 [==============================] - 0s 275us/sample - loss: 0.3865 - acc: 0.9000
<IPython.core.display.HTML object>
(10, 10, 5)
timestep 0 timestep 1 timestep 2 timestep 3 timestep 4 timestep 5 timestep 6 timestep 7 timestep 8 timestep 9
0 41 14 88 81 57 3 7 9 58 14
1 38 83 75 54 80 62 83 52 10 13
2 91 19 54 34 64 24 77 75 47 69
3 93 20 12 66 22 29 84 73 61 80
4 57 22 94 76 9 71 31 89 11 66
5 97 32 93 25 49 72 19 2 8 87
6 73 95 1 9 60 26 45 30 92 66
7 91 10 80 22 56 64 51 1 32 17
8 66 71 38 18 65 97 97 82 33 92
9 7 75 36 21 46 60 68 48 93 29
'\n#y_pred = model.predict(x[:3, :, :])\n#print(y_pred)\n\n#background = x[np.random.choice(x.shape[0], 10, replace=False)]\nmasker = shap.maskers.Independent(data=x)\n# Get generic explainer\n#explainer = shap.KernelExplainer(model, background)\nexplainer = shap.KernelExplainer(model.predict, x, masker=masker)\n\n# Show kernel type\nprint("\nKernel type: %s" % type(explainer))\n\n# Get shap values\nshap_values = explainer.shap_values(x)\n\nprint(shap_values)\n'
6 # Libraries
7 import shap
8 import numpy as np
9 import pandas as pd
10
11 import tensorflow as tf
12 tf.compat.v1.disable_eager_execution()
13 tf.compat.v1.disable_v2_behavior()
14
15 # --------------------------------------------
16 # Create data
17 # --------------------------------------------
18 # Constants
19 SAMPLES = 10
20 TIMESTEPS = 10
21 FEATURES = 5
22
23 # .. note: Either perform a pre-processing step such as
24 # normalization or generate the features within
25 # the appropriate interval.
26 # Create dataset
27 x = np.random.randint(low=0, high=100,
28 size=(SAMPLES, TIMESTEPS, FEATURES))
29 y = np.random.randint(low=0, high=2, size=SAMPLES).astype(float)
30 i = np.vstack(np.dstack(np.indices((SAMPLES, TIMESTEPS))))
31
32 # Create DataFrame
33 df = pd.DataFrame(
34 data=np.hstack((i, x.reshape((-1,FEATURES)))),
35 columns=['id', 't'] + ['f%s'%j for j in range(FEATURES)]
36 )
37
38 # Show
39 print("Shapes:")
40 print("i: %s" % str(i.shape))
41 print("y: %s" % str(y.shape))
42 print("x: %s" % str(x.shape))
43
44 print("\nData (%s):" % str(x.shape))
45 print(x)
46
47 print("\nDataFrame (2D)")
48 print(df)
49
50
51 # --------------------------------------------
52 # Model
53 # --------------------------------------------
54 # Libraries
55 from tensorflow.keras.layers import Input
56 from tensorflow.keras.layers import Dropout
57 from tensorflow.keras.models import Sequential
58 from tensorflow.keras.layers import Dense
59 from tensorflow.keras.layers import LSTM
60 from tensorflow.keras.layers import Embedding
61 from tensorflow.keras.preprocessing import sequence
62
63 # Create model
64 model = Sequential()
65 #model.add(Input(shape=(None, FEATURES)))
66 model.add(
67 LSTM(
68 units=64,
69 return_sequences=False,
70 input_shape=(TIMESTEPS, FEATURES)
71 ))
72 #model.add(Dropout(0.2))
73 model.add(Dense(64, activation='relu'))
74 model.add(Dense(1, activation='sigmoid'))
75 model.compile(
76 loss='binary_crossentropy',
77 optimizer='adam',
78 metrics=['accuracy']
79 )
80 model.run_eagerly = False
81
82 # Load pre-trained weights
83
84 # Display model summary
85 print(model.summary())
86
87 model.save('outputs/model.h5')
88
89 # Fit
90 model.fit(x, y, epochs=16, batch_size=64)
91
92
93
94 # --------------------------------------------
95 # Compute and display SHAP values
96 # --------------------------------------------
97 # https://github.com/slundberg/shap/blob/master/shap/plots/_beeswarm.py
98
99 # Use the training data for deep explainer => can use fewer instances
100 explainer = shap.DeepExplainer(model, x)
101 # explain the the testing instances (can use fewer instanaces)
102 # explaining each prediction requires 2 * background dataset size runs
103 shap_values = explainer.shap_values(x)
104 # init the JS visualization code
105 shap.initjs()
106
107 print(shap_values[0].shape)
108
109 #shap_values = explainer(x)
110
111 """
112 shap.plots.beeswarm(shap_values,
113 max_display=12, order=shap.Explanation.abs.mean(0))
114
115 import matplotlib.pyplot as plt
116 plt.show()
117
118
119
120
121 import sys
122 sys.exit()
123 """
124
125 shap_values_2D = shap_values[0].reshape(-1,x.shape[-1])
126 x_2D = pd.DataFrame(
127 data=x.reshape(-1,x.shape[-1]),
128 columns=['f%s'%j for j in range(x.shape[-1])]
129 )
130
131
132 ## SHAP for each time step
133 NUM_STEPS = x.shape[1]
134 NUM_FEATURES = x.shape[-1]
135 len_test_set = x_2D.shape[0]
136
137 """
138 # step = 0
139 for step in range(NUM_STEPS):
140 indice = [i for i in list(range(len_test_set)) if i%NUM_STEPS == step]
141 shap_values_2D_step = shap_values_2D[indice]
142 x_test_2d_step = x_2D.iloc[indice]
143 print("_______ time step {} ___________".format(step))
144 #shap.summary_plot(shap_values_2D_step, x_test_2d_step, plot_type="bar")
145 shap.summary_plot(shap_values_2D_step, x_test_2d_step)
146 print("\n")
147 """
148
149
150 shap_values_2D_step = shap_values_2D[:, 1].reshape(-1, x.shape[1])
151 x_test_2d_step = x_2D.iloc[:, 1].to_numpy().reshape(-1, x.shape[1])
152 x_test_2d_step = pd.DataFrame(
153 x_test_2d_step, columns=['timestep %s'%j for j in range(x.shape[1])]
154 )
155
156 print(x_test_2d_step)
157
158 shap.summary_plot(shap_values_2D_step, x_test_2d_step, sort=False)
159
160 """
161 for step in range(NUM_STEPS):
162 indice = [i for i in list(range(len_test_set)) if i%NUM_STEPS == step]
163 shap_values_2D_step = shap_values_2D[indice]
164 x_test_2d_step = x_2D.iloc[indice]
165 print("_______ time step {} ___________".format(step))
166 #shap.summary_plot(shap_values_2D_step, x_test_2d_step, plot_type="bar")
167 shap.summary_plot(shap_values_2D_step, x_test_2d_step)
168 print("\n")
169 """
170 import matplotlib.pyplot as plt
171 plt.show()
172
173 """
174 #y_pred = model.predict(x[:3, :, :])
175 #print(y_pred)
176
177 #background = x[np.random.choice(x.shape[0], 10, replace=False)]
178 masker = shap.maskers.Independent(data=x)
179 # Get generic explainer
180 #explainer = shap.KernelExplainer(model, background)
181 explainer = shap.KernelExplainer(model.predict, x, masker=masker)
182
183 # Show kernel type
184 print("\nKernel type: %s" % type(explainer))
185
186 # Get shap values
187 shap_values = explainer.shap_values(x)
188
189 print(shap_values)
190 """
Total running time of the script: ( 0 minutes 8.899 seconds)