<jupyter_start><jupyter_text>Import local packages, e.g., dice, spotlight, and contant variables setting<jupyter_code>import os
import sys

for p in ['../spotlight_ext', '../dice_ext']:
    module_path = os.path.abspath(os.path.join(p))
    if module_path not in sys.path:
        sys.path.append(module_path)
import numpy as np
import scipy.stats as st
from sklearn.model_selection import RandomizedSearchCV
from sklearn.metrics import make_scorer

import torch
models_path = '../models'<jupyter_output><empty_output><jupyter_text>Usage example for spotlight<jupyter_code>from spotlight.cross_validation import random_train_test_split
from spotlight.datasets.movielens import get_movielens_dataset
# from spotlight.evaluation import mrr_score
# from spotlight.factorization.implicit import ImplicitFactorizationModel
# dataset = get_movielens_dataset(variant='100K')

# train, test = random_train_test_split(dataset)

# model = ImplicitFactorizationModel(n_iter=3, loss='bpr')
# model.fit(train)

# mrr = mrr_score(model, test)<jupyter_output><empty_output><jupyter_text>**Sequential models** (candidate for our problem)<jupyter_code># from spotlight.cross_validation import user_based_train_test_split
# from spotlight.datasets.synthetic import generate_sequential


# dataset = generate_sequential(num_users=100,
#                               num_items=1000,
#                               num_interactions=10000,
#                               concentration_parameter=0.01,
#                               order=3)

# train, test = user_based_train_test_split(dataset)

dataset = get_movielens_dataset(variant='1M')
train, test = random_train_test_split(dataset, random_state=np.random.RandomState(2020))

max_sequence_length = 20
train = train.to_sequence(max_sequence_length=max_sequence_length)
test = test.to_sequence(max_sequence_length=max_sequence_length)<jupyter_output><empty_output><jupyter_text>train model<jupyter_code>from spotlight.sequence.implicit import ImplicitSequenceModel
from spotlight.evaluation import sequence_mrr_score

model = ImplicitSequenceModel(
    batch_size=256,
    embedding_dim=32,
    l2=0.0,
    learning_rate=0.05,
    n_iter=11,
    representation='lstm',
    loss='adaptive_hinge',
#     use_cuda=torch.cuda.is_available(),
    random_state=np.random.RandomState(2020)
)
model.fit(train)

mrr = sequence_mrr_score(model, test)<jupyter_output><empty_output><jupyter_text>save model<jupyter_code>ofile = 'entire_model_1m_20interactions.pt'
torch.save(model, os.path.join(models_path, ofile))<jupyter_output><empty_output><jupyter_text>or load a saved model<jupyter_code>ofile = 'entire_model_1m.pt'

model = torch.load(os.path.join(models_path, ofile))
items_interacted = test.sequences[test.user_ids==2][0]
predictions = -model.predict(items_interacted[:-1])
print(f'Item to predict: {items_interacted[-1]}')
next_item_pos = st.rankdata(predictions, method='ordinal')[items_interacted[-1]]
next_item_pos
sorted(enumerate(predictions), key=lambda x: x[1])[int(next_item_pos) - 1]
# param_grid = dict(
#     n_iter=st.randint(10, 20),
#     representation=['cnn', 'lstm', 'mixture'],
#     loss=['adaptive_hinge', 'hinge', 'bpr'],
#     embedding_dim=[32, 64, 128, 256],
#     batch_size=[32, 64, 128, 256],
#     learning_rate=st.expon(loc=0.0001, scale=0.1),
#     l2=st.expon(loc=0.0, scale=0.1)
# )
# score = make_scorer(sequence_mrr_score)
                    
# grid = RandomizedSearchCV(
#     estimator=ImplicitSequenceModel(), param_distributions=param_grid, n_jobs=4, cv=3,
#     scoring=score, verbose=1, n_iter=100
# )
# grid_result = grid.fit(train)<jupyter_output><empty_output><jupyter_text>Causal convolutions for sequence-based recommendations<jupyter_code>hyperparameters = {
    'embedding_dim': 128,
    'kernel_width': 5,
    'dilation': [1, 2, 4],
    'num_layers': 5,
    'nonlinearity': 'relu',
    'residual': True,
    'loss': 'adaptive_hinge',
    'batch_size': 128,
    'learning_rate': 0.01,
    'l2': 0,
    'n_iter': 50
}
import torch

from spotlight.sequence.implicit import ImplicitSequenceModel
from spotlight.sequence.representations import CNNNet
from spotlight.evaluation import sequence_mrr_score


net = CNNNet(train.num_items,
             embedding_dim=hyperparameters['embedding_dim'],
             kernel_width=hyperparameters['kernel_width'],
             dilation=hyperparameters['dilation'],
             num_layers=hyperparameters['num_layers'],
             nonlinearity=hyperparameters['nonlinearity'],
             residual_connections=hyperparameters['residual'])

model = ImplicitSequenceModel(loss=hyperparameters['loss'],
                              representation=net,
                              batch_size=hyperparameters['batch_size'],
                              learning_rate=hyperparameters['learning_rate'],
                              l2=hyperparameters['l2'],
                              n_iter=hyperparameters['n_iter'],
                              use_cuda=torch.cuda.is_available(),
#                               random_state=random_state
                             )

model.fit(train)

test_mrr = sequence_mrr_score(model, test)
# val_mrr = sequence_mrr_score(model, validation)
print(f'Test MRR {test_mrr}')<jupyter_output>Test MRR [0.01612903 0.0060241  0.00290698 0.00218818 0.05263158 0.00220751
 0.01052632 0.0052356  0.03333333 0.00108696 0.05       0.33333333
 0.00411523 0.00108696 0.00116009 0.01754386 0.00115875 0.00174216
 1.         0.00273224 0.00103199 0.01149425 0.01470588 0.00150376
 0.00115741 0.00134771 0.00526316 0.00189036 0.00181488 0.00409836
 0.00537634 0.00101833 0.01075269 0.00168067 1.         0.00232019
 0.00315457 0.01020408 0.00111235 0.00290698 0.125      0.00584795
 0.01149425 0.00970874 0.0013624  0.00161812 0.00175439 0.00308642
 0.00275482 1.         0.00137931 0.00423729 0.16666667 0.00187266
 0.00138122 0.00154799 0.00485437 0.00121951 0.00127877 0.125
 0.00117647 0.00507614 0.00564972 1.         0.01960784 0.00169205
 0.00172414 0.00198807 0.01282051 0.0010989  0.00555556 0.00116686
 0.00247525 0.00689655 0.01492537 0.0037037  0.01315789 0.001321
 0.00143472 0.001287   0.00662252 0.00168919 0.00280899 0.00298507
 0.004      0.03333333 0.00204499 0.0013245  0.00181818 0.00[...]<jupyter_text>Usage example for DiCE with torch<jupyter_code>import dice_ml
from dice_ml.utils import helpers # helper functions

backend = 'PYT'
# Dataset for training an ML model
d = dice_ml.Data(dataframe=helpers.load_adult_income_dataset(),
                 continuous_features=['age', 'hours_per_week'],
                 outcome_name='income')
# Pre-trained ML model
m = dice_ml.Model(model_path=dice_ml.utils.helpers.get_adult_income_modelpath(backend=backend), backend=backend)
# DiCE explanation instance
exp = dice_ml.Dice(d, m)
query_instance = {
    'age':22,
    'workclass':'Private',
    'education':'HS-grad',
    'marital_status':'Single',
    'occupation':'Service',
    'race': 'White',
    'gender':'Female',
    'hours_per_week': 45
}
# Generate counterfactual examples
dice_exp = exp.generate_counterfactuals(query_instance, total_CFs=4, desired_class="opposite")
# Visualize counterfactual explanation
dice_exp.visualize_as_dataframe()<jupyter_output>Diverse Counterfactuals found! total time taken: 00 min 03 sec
Query instance (original outcome : 0)<jupyter_text>Brute-force example on Sequential model<jupyter_code># load trained model
ofile = 'entire_model_1m.pt'
model = torch.load(os.path.join(models_path, ofile))
# initialize input parameters
k = 10
no_interactions = 5
user_id = 8
class SelectedInteractions:
    def __init__(self, p=-1, i=None):
        pos = p
        interactions = i
        
    def __str__(self): 
        items_order = [(n[0], n[1].detach().numpy().flatten()[0]) if isinstance(n[1], torch.Tensor) else (n[0], n[1]) for n in self.items_order]
            
        return (f'Found in iter {self.counter_found_best} with score/in pos {self.score} with interactions {self.interactions}\n'
                f'10-best proposed items {items_order}')
    
    score = 0
    pos = -1
    interactions = []
    items_order = []
    counter_found_best = -1
items_interacted = test.sequences[test.user_ids==user_id][0]
predictions = -model.predict(items_interacted[:no_interactions])

print(f'Given the following interactions {items_interacted[:no_interactions]} for user {user_id} the next most {k} possible items'
      f'to interact with are {list(predictions.argsort()[:k])}')
cand = input('Choose one of the above next interacted items that should become less candidate: ')
try:
    cand = int(cand)
except ValueError:
    print("That's not an int!")

print(f'Current pos of selected item {cand} is {st.rankdata(predictions, method="ordinal")[cand]}\n')
from itertools import permutations
import torch.nn.functional as F


counter = 1
best_inter = SelectedInteractions()

for l in range(1, no_interactions + 1):
    perm = permutations(items_interacted[:no_interactions], l)    

    for i in list(perm):        
        preds = model.predict(i) 
        tensor = torch.from_numpy(preds).float()
        preds = F.softmax(tensor, dim=0)        
        item_pos = st.rankdata(-preds, method='ordinal')[cand]
        if item_pos > best_inter.score:
            best_inter.score = item_pos
            best_inter.interactions = i
            best_inter.items_order = sorted(enumerate(preds), key=lambda x: x[1], reverse=True)[:k]
            best_inter.counter_found_best = counter

        counter += 1
    
print(best_inter, f'\nTotal iterations: {counter}')
import cvxpy as cp

# Create two scalar optimization variables.
x = cp.Variable()
y = cp.Variable()

# Create two constraints.
constraints = [x + y == 1,
               x - y >= 1]

# Form objective.
obj = cp.Minimize((x - y)**2)

# Form and solve problem.
prob = cp.Problem(obj, constraints)
prob.solve()  # Returns the optimal value.
print("status:", prob.status)
print("optimal value", prob.value)
print("optimal var", x.value, y.value)
# Solves a bounded least-squares problem.

import cvxpy as cp
import numpy

# Problem data.
m = 10
n = 5
numpy.random.seed(1)
A = numpy.random.randn(m, n)
b = numpy.random.randn(m)

# Construct the problem.
x = cp.Variable(n)
objective = cp.Minimize(cp.sum_squares(A @ x - b))
constraints = [0 <= x, x <= 1]
prob = cp.Problem(objective, constraints)

print("Optimal value", prob.solve())
print("Optimal var")
print(x.value) # A numpy ndarray.
import h5py
filename = "~/spotlight_data/movielens/v0.2.0/movielens_movielens_100K.hdf5"

with h5py.File(os.path.expanduser(filename), "r") as f:
    # List all groups
    print("Keys: %s" % f.keys())
    a_group_key = list(f.keys())[0]

    # Get the data
    data = list(f[a_group_key])
os.system("jupyter nbconvert misc.ipynb --to slides")
!jupyter nbconvert misc.ipynb --to pdf
!pwd
!ls<jupyter_output>archive.ics.uci.edu	    matrix_factorization_for_rec_expl.ipynb
brute_force_rec_expl.ipynb  misc.ipynb
budget_strategies.ipynb     misc.pdf
cvxpy_usage_rec_expl.ipynb  pooling_repr_for_rec_expl.ipynb
Dice_test.ipynb		    README.md
fair_rec		    score_preds.ipynb
helpers.ipynb		    torch_rec
{'fraction_non_alphanumeric': 0.11528799569352234, 'fraction_numerical': 0.08173335725820922, 'mean_word_length': 3.891180342255375, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '614212', 'license': 'MIT', 'n_tokens_mistral': 4472, 'n_tokens_neox': 3825, 'n_words': 757, 'path': 'notebooks/misc.ipynb', 'repo_name': 'vkaff/CFExplainability', 'size': '11146'}