Skip to content

Commit

Permalink
normalizing numerical data before inputting to network; update defaul…
Browse files Browse the repository at this point in the history
…t hyperparameters
  • Loading branch information
Zebin Yang committed Mar 31, 2022
1 parent d6a0092 commit 93b3019
Show file tree
Hide file tree
Showing 14 changed files with 44,268 additions and 572 deletions.
367 changes: 174 additions & 193 deletions examples/FicoHeloc.ipynb

Large diffs are not rendered by default.

331 changes: 167 additions & 164 deletions examples/GAMINet-bike-share.ipynb

Large diffs are not rendered by default.

420 changes: 254 additions & 166 deletions examples/GAMINet-demo.ipynb

Large diffs are not rendered by default.

43,590 changes: 43,590 additions & 0 deletions examples/results/demo.eps

Large diffs are not rendered by default.

Binary file added examples/results/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/results/s1_feature.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/results/s1_local.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/results/s1_regu_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/results/s1_traj_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/simu_dict.pickle
Binary file not shown.
Binary file added examples/simu_model.pickle
Binary file not shown.
37 changes: 19 additions & 18 deletions gaminet/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
from sklearn.base import RegressorMixin, ClassifierMixin, BaseEstimator

from pygam.terms import TermList
from pygam import LinearGAM, LogisticGAM, f, s, te
from pygam import LinearGAM, LogisticGAM, s, te

from .base import GAMINet


class GAMINetRegressor(GAMINet, RegressorMixin):

def __init__(self, meta_info=None, interact_num=20,
subnet_size_main_effect=[40] * 5, subnet_size_interaction=[40] * 5, activation_func=torch.nn.ReLU(),
max_epochs=[1000, 1000, 100], learning_rates=[1e-3, 1e-3, 1e-3], early_stop_thres=["auto", "auto", "auto"],
def __init__(self, meta_info=None, interact_num=10,
subnet_size_main_effect=[100], subnet_size_interaction=[200], activation_func=torch.nn.ReLU(),
max_epochs=[1000, 1000, 1000], learning_rates=[1e-3, 1e-3, 1e-3], early_stop_thres=["auto", "auto", "auto"],
batch_size=200, batch_size_inference=10000, max_iter_per_epoch=100, val_ratio=0.2, max_val_size=10000,
warm_start=True, gam_sample_size=5000, mlp_sample_size=1000,
heredity=True, reg_clarity=0.1, loss_threshold=0.0,
reg_mono=0.1, mono_increasing_list=None, mono_decreasing_list=None, mono_sample_size=200,
boundary_clip=True, verbose=False, device="cpu", random_state=0):
boundary_clip=True, normalize=True, verbose=False, device="cpu", random_state=0):

super(GAMINetRegressor, self).__init__(loss_fn=torch.nn.MSELoss(reduction="none"),
meta_info=meta_info,
Expand All @@ -47,6 +47,7 @@ def __init__(self, meta_info=None, interact_num=20,
mono_increasing_list=mono_increasing_list,
mono_decreasing_list=mono_decreasing_list,
boundary_clip=boundary_clip,
normalize=normalize,
verbose=verbose,
device=device,
random_state=random_state)
Expand All @@ -61,17 +62,16 @@ def build_teacher_main_effect(self):

termlist = TermList()
for idx, (key, item) in enumerate(self.meta_info.items()):
if item["type"] == "continuous":
if (item["type"] == "continuous") or (item["type"] == "categorical"):
termlist += s(idx, n_splines=10, spline_order=1, lam=0.6)
elif item["type"] == "categorical":
termlist += f(idx)
else:
continue

gam = LinearGAM(termlist)
allx = torch.vstack([self.tr_x, self.val_x])
ally = torch.vstack([self.tr_y, self.val_y])

allx = (allx - self.mu_list) / self.std_list if self.normalize else allx

suffleidx = np.arange(allx.shape[0])
np.random.shuffle(suffleidx)
subx = allx[suffleidx][:self.gam_sample_size]
Expand All @@ -95,13 +95,13 @@ def build_teacher_interaction(self):
gam = LinearGAM(termlist)
allx = torch.vstack([self.tr_x, self.val_x])
ally = torch.vstack([self.tr_y, self.val_y])

suffleidx = np.arange(allx.shape[0])
np.random.shuffle(suffleidx)
subx = allx[suffleidx][:self.gam_sample_size]
suby = ally[suffleidx][:self.gam_sample_size]
residual = (suby - self.decision_function(subx, main_effect=True, interaction=False))
gam.fit(subx.detach().cpu().numpy(), residual.detach().cpu().numpy())
gam.fit(((subx - self.mu_list) / self.std_list if self.normalize else subx).detach().cpu().numpy(), residual.detach().cpu().numpy())

def margial_effect(i):
return lambda x: gam.partial_dependence(i, x)
Expand Down Expand Up @@ -144,14 +144,14 @@ def predict(self, x, main_effect=True, interaction=True):

class GAMINetClassifier(GAMINet, ClassifierMixin):

def __init__(self, meta_info=None, interact_num=20,
subnet_size_main_effect=[40] * 5, subnet_size_interaction=[40] * 5, activation_func=torch.nn.ReLU(),
def __init__(self, meta_info=None, interact_num=10,
subnet_size_main_effect=[100], subnet_size_interaction=[200], activation_func=torch.nn.ReLU(),
max_epochs=[1000, 1000, 100], learning_rates=[1e-3, 1e-3, 1e-3], early_stop_thres=["auto", "auto", "auto"],
batch_size=200, batch_size_inference=10000, max_iter_per_epoch=100, val_ratio=0.2, max_val_size=10000,
warm_start=True, gam_sample_size=5000, mlp_sample_size=1000,
heredity=True, reg_clarity=0.1, loss_threshold=0.0,
reg_mono=0.1, mono_increasing_list=None, mono_decreasing_list=None, mono_sample_size=200,
boundary_clip=True, verbose=False, device="cpu", random_state=0):
boundary_clip=True, normalize=True, verbose=False, device="cpu", random_state=0):

super(GAMINetClassifier, self).__init__(loss_fn=torch.nn.BCEWithLogitsLoss(reduction="none"),
meta_info=meta_info,
Expand All @@ -178,6 +178,7 @@ def __init__(self, meta_info=None, interact_num=20,
mono_increasing_list=mono_increasing_list,
mono_decreasing_list=mono_decreasing_list,
boundary_clip=boundary_clip,
normalize=normalize,
verbose=verbose,
device=device,
random_state=random_state)
Expand All @@ -200,16 +201,15 @@ def build_teacher_main_effect(self):

termlist = TermList()
for idx, (key, item) in enumerate(self.meta_info.items()):
if item["type"] == "continuous":
if (item["type"] == "continuous") or (item["type"] == "categorical"):
termlist += s(idx, n_splines=10, spline_order=1, lam=0.6)
elif item["type"] == "categorical":
termlist += f(idx)
else:
continue

gam = LinearGAM(termlist)
allx = torch.vstack([self.tr_x, self.val_x])
ally = torch.vstack([self.tr_y, self.val_y]) * 4 - 2
allx = (allx - self.mu_list) / self.std_list if self.normalize else allx

suffleidx = np.arange(allx.shape[0])
np.random.shuffle(suffleidx)
Expand All @@ -234,12 +234,13 @@ def build_teacher_interaction(self):
gam = LinearGAM(termlist)
allx = torch.vstack([self.tr_x, self.val_x])
ally = torch.vstack([self.tr_y, self.val_y])

suffleidx = np.arange(allx.shape[0])
np.random.shuffle(suffleidx)
subx = allx[suffleidx][:self.gam_sample_size]
suby = ally[suffleidx][:self.gam_sample_size]
residual = (suby - self.predict_proba(subx, main_effect=True, interaction=False)[:, [1]])
gam.fit(subx.detach().cpu().numpy(), residual.detach().cpu().numpy())
gam.fit(((subx - self.mu_list) / self.std_list if self.normalize else subx).detach().cpu().numpy(), residual.detach().cpu().numpy())

def margial_effect(i):
return lambda x: gam.partial_dependence(i, x)
Expand Down
Loading

0 comments on commit 93b3019

Please sign in to comment.