Skip to content

Commit

Permalink
Minor in Readme
Browse files Browse the repository at this point in the history
  • Loading branch information
JHoelli committed Aug 8, 2023
1 parent e16c8cb commit 7773ea2
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 69 deletions.
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ pip install https://github.com/fzi-forschungszentrum-informatik/TSInterpret/arch
```


Due to the <a href='https://github.com/scikit-learn/sklearn-pypi-package'>sklearn brownout</a> `pip install sklearn` is no longer available in third party dependencies. As the current release of <a href='https://github.com/gkhayes/mlrose'>mlrose</a> still relies on sklearn, we eliminated the dependency. If you still want to use COMTE (with dependecy to mlrose), it can be installed via :
```shell
pip install https://github.com/gkhayes/mlrose/archive/refs/heads/master.zip
```


## 🍫 Quickstart
The following example creates a simple Neural Network based on tensorflow and interprets the Classfier with Integrated Gradients and Temporal Saliency Rescaling [1].
Expand Down
2 changes: 1 addition & 1 deletion TSInterpret/InterpretabilityModels/counterfactual/CF.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def plot_in_one(
"""
if self.mode == "time":
item = item.reshape(item.shape[-1], item.shape[-2])
exp = exp.reshape( exp.shape[-1], exp.shape[-2])
exp = exp.reshape(exp.shape[-1], exp.shape[-2])
else:
item = item.reshape(item.shape[-2], item.shape[-1])
exp = exp.reshape(item.shape[-2], item.shape[-1])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import logging
import multiprocessing
import numbers
Expand All @@ -9,12 +8,18 @@
import six
from sklearn.neighbors import KDTree
from skopt import gbrt_minimize, gp_minimize
from TSInterpret.InterpretabilityModels.counterfactual.COMTE.Problem import LossDiscreteState, Problem
from TSInterpret.InterpretabilityModels.counterfactual.COMTE.Optmization_helpers import random_hill_climb
from TSInterpret.InterpretabilityModels.counterfactual.COMTE.Problem import (
LossDiscreteState,
Problem,
)
from TSInterpret.InterpretabilityModels.counterfactual.COMTE.Optmization_helpers import (
random_hill_climb,
)

# sys.modules["sklearn.externals.six"] = six

#sys.modules["sklearn.externals.six"] = six
# import mlrose

#import mlrose

class BaseExplanation:
def __init__(
Expand Down Expand Up @@ -239,9 +244,6 @@ def _eval_one(tup):
] # CLASSIFIER.predict_proba(x_test)[0][label_idx]





class BruteForceSearch(BaseExplanation):
def _find_best(self, x_test, distractor, label_idx):
global CLASSIFIER
Expand Down Expand Up @@ -328,9 +330,6 @@ def explain(self, x_test, to_maximize=None, num_features=10):
return other, target





class OptimizedSearch(BaseExplanation):
def __init__(
self,
Expand Down Expand Up @@ -361,7 +360,7 @@ def opt_Discrete(self, to_maximize, x_test, dist, columns, init, num_features=No
max_features=num_features,
maximize=False,
)
problem = Problem( length=len(columns), loss=fitness_fn, max_val=2)
problem = Problem(length=len(columns), loss=fitness_fn, max_val=2)
best_state, best_fitness = random_hill_climb(
problem,
max_attempts=self.max_attemps,
Expand Down Expand Up @@ -436,8 +435,8 @@ def _get_explanation(self, x_test, to_maximize, num_features):
distractors = self._get_distractors(
x_test, to_maximize, n_distractors=self.num_distractors
)
#print('distracotr shape',np.array(distractors).shape)
#print('distracotr classification',np.argmax(self.clf(np.array(distractors).reshape(2,6,100)), axis=1))
# print('distracotr shape',np.array(distractors).shape)
# print('distracotr classification',np.argmax(self.clf(np.array(distractors).reshape(2,6,100)), axis=1))

# Avoid constructing KDtrees twice
self.backup.per_class_trees = self.per_class_trees
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import numpy as np
def random_hill_climb(problem, max_attempts=10, max_iters=np.inf, restarts=0,
init_state=None, curve=False, random_state=None):


def random_hill_climb(
problem,
max_attempts=10,
max_iters=np.inf,
restarts=0,
init_state=None,
curve=False,
random_state=None,
):
# Set random seed
if isinstance(random_state, int) and random_state > 0:
np.random.seed(random_state)
Expand Down Expand Up @@ -40,16 +48,15 @@ def random_hill_climb(problem, max_attempts=10, max_iters=np.inf, restarts=0,
fitness_values.append(problem.get_fitness())

# Update best state and best fitness
#print('best_fitness',best_fitness)
# print('best_fitness',best_fitness)
if problem.get_fitness() < best_fitness:
best_fitness = problem.get_fitness()
best_state = problem.get_state()
#print('bestfitness after', best_fitness)


# print('bestfitness after', best_fitness)

if curve:
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt

plt.plot(np.asarray(fitness_values))
plt.show()

Expand Down
63 changes: 30 additions & 33 deletions TSInterpret/InterpretabilityModels/counterfactual/COMTE/Problem.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@

import numpy as np

class Problem :
def __init__(self,length,loss, max_val):

class Problem:
def __init__(self, length, loss, max_val):
self.loss = loss
self.max_val= max_val
self.length=length
#self.maximize=maximize
self.max_val = max_val
self.length = length
# self.maximize=maximize
self.fitness = np.inf
self.state = np.array([0]*self.length)

self.state = np.array([0] * self.length)

def random_neighbor(self):
neighbor = np.copy(self.state)
Expand All @@ -21,40 +20,39 @@ def random_neighbor(self):
else:
vals = list(np.arange(self.max_val))
vals.remove(neighbor[i])
neighbor[i] = vals[np.random.randint(0, self.max_val-1)]
neighbor[i] = vals[np.random.randint(0, self.max_val - 1)]

return neighbor

def get_fitness(self):
return self.fitness

def eval_fitness(self, state):
fitness =self.loss.evaluate(state)
fitness = self.loss.evaluate(state)
return fitness

def random(self):
state = np.random.randint(0, self.max_val, self.length)
return state

def reset(self):

def reset(self):
self.state = self.random()
self.fitness = self.eval_fitness(self.state)

def set_state(self, new_state):

self.state = new_state
self.fitness = self.eval_fitness(self.state)

def get_state(self):
return self.state
#def get_maximize(self):

# def get_maximize(self):
# return self.maximize



class LossDiscreteState:
'''Loss Function'''
"""Loss Function"""

def __init__(
self,
label_idx,
Expand Down Expand Up @@ -87,33 +85,32 @@ def evaluate(self, feature_matrix):

for col_replace, a in zip(self.cols_swap, feature_matrix):
if a == 1:
#print(self.distractor.shape)
# print(self.distractor.shape)
new_case[0][col_replace] = self.distractor[0][col_replace]

replaced_feature_count = np.sum(feature_matrix)
#print('replaced_Feature', replaced_feature_count)
#print('NEW CASE', new_case)
#print('self xtest', self.x_test)
#print('NEW CASE', new_case.shape)
#print('self xtest', self.x_test.shape)
#print('DIFF', np.where((self.x_test.reshape(-1)-new_case.reshape(-1)) != 0) )
# print('replaced_Feature', replaced_feature_count)

# print('NEW CASE', new_case)
# print('self xtest', self.x_test)
# print('NEW CASE', new_case.shape)
# print('self xtest', self.x_test.shape)
# print('DIFF', np.where((self.x_test.reshape(-1)-new_case.reshape(-1)) != 0) )

input_ = new_case.reshape(1, self.channels, self.window_size)
result_org = self.clf(input_)
result=result_org[0][self.target]
#print('RESULT',result)
result = result_org[0][self.target]
# print('RESULT',result)
feature_loss = self.reg * np.maximum(
0, replaced_feature_count - self.max_features
)

#print('FEATURE LOSS',feature_loss)
# print('FEATURE LOSS',feature_loss)
loss_pred = np.square(np.maximum(0, 0.95 - result))
#print('losspred ',loss_pred)
#if np.argmax(result_org[0]) != self.target:
# print('losspred ',loss_pred)
# if np.argmax(result_org[0]) != self.target:
# loss_pred=np.inf

loss_pred = loss_pred + feature_loss

return loss_pred

Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from . import Optimization, Problem, Optmization_helpers

__all__ = ["Optimization", "Problem","Optimization_helpers"]
__all__ = ["Optimization", "Problem", "Optimization_helpers"]
11 changes: 4 additions & 7 deletions TSInterpret/InterpretabilityModels/counterfactual/COMTECF.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
from TSInterpret.InterpretabilityModels.counterfactual.COMTE.Problem import *




class COMTECF(CF):
"""Calculates and Visualizes Counterfactuals for Multivariate Time Series in accordance to the paper [1].
Expand Down Expand Up @@ -69,7 +67,7 @@ def __init__(

elif backend == "SK":
self.predict = SklearnModel(model, change).predict

self.referenceset = (test_x, test_y)
self.method = method
self.silent = silent
Expand All @@ -90,7 +88,7 @@ def explain(
([np.array], int): Tuple of Counterfactual and Label. Shape of CF : `mode = time` -> `(time, feat)` or `mode = time` -> `(feat, time)`
"""
org_shape=x.shape
org_shape = x.shape
if self.mode != "feat":
x = x.reshape(-1, x.shape[-1], x.shape[-2])
train_x, train_y = self.referenceset
Expand All @@ -107,9 +105,8 @@ def explain(
max_attempts=self.max_attemps,
maxiter=self.max_iter,
)
exp,label= opt.explain(x, to_maximize=target)
exp, label = opt.explain(x, to_maximize=target)
elif self.method == "brute":
opt = BruteForceSearch(self.predict, train_x, train_y, threads=1)
exp,label= opt.explain(x, to_maximize=target)
exp, label = opt.explain(x, to_maximize=target)
return exp.reshape(org_shape), label

Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from . import CF, COMTE, NativeGuideCF, TSEvo, TSEvoCF, COMTECF

__all__ = ["CF", "COMTE", "NativeGuideCF", "TSEvoCF", "TSEvo","COMTECF"]
__all__ = ["CF", "COMTE", "NativeGuideCF", "TSEvoCF", "TSEvo", "COMTECF"]

0 comments on commit 7773ea2

Please sign in to comment.