-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathutils.py
executable file
·85 lines (70 loc) · 2.42 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from __future__ import division
import math
import scipy.misc
import numpy as np
import random
import copy
import pickle
import pandas as pd
import csv
import os
import sys
import torch
import shutil
import pickle
import numpy as np
import bottleneck as bn
def save_weights_pkl(fname, weights):
with open(fname, 'wb') as f:
pickle.dump(weights, f, pickle.HIGHEST_PROTOCOL)
def load_weights_pkl(fname):
with open(fname, 'rb') as f:
weights = pickle.load(f)
return weights
def get_parameters(model, bias=False):
for k, m in model.named_parameters():
if bias:
if k.endswith('.bias'):
yield m
else:
if k.endswith('.weight'):
yield m
class AverageMeter(object):
"""Computes and stores the average and current value"""
def __init__(self):
self.reset()
def reset(self):
self.val = 0
self.avg = 0
self.sum = 0
self.count = 0
def update(self, val, n=1):
self.val = val
self.sum += val * n
self.count += n
self.avg = self.sum / self.count
# borrowed from https://github.com/dawenl/vae_cf/blob/master/VAE_ML20M_WWW2018.ipynb
def NDCG_binary_at_k_batch(X_pred, heldout_batch, k=100):
'''
normalized discounted cumulative gain@k for binary relevance
ASSUMPTIONS: all the 0's in heldout_data indicate 0 relevance
'''
batch_users = X_pred.shape[0]
idx_topk_part = bn.argpartition(-X_pred, k, axis=1)
topk_part = X_pred[np.arange(batch_users)[:, np.newaxis], idx_topk_part[:, :k]]
idx_part = np.argsort(-topk_part, axis=1)
idx_topk = idx_topk_part[np.arange(batch_users)[:, np.newaxis], idx_part]
# build the discount template
tp = 1. / np.log2(np.arange(2, k + 2))
DCG = (heldout_batch[np.arange(batch_users)[:, np.newaxis], idx_topk] * tp).sum(axis=1)
IDCG = np.array([(tp[:min(int(n), k)]).sum() for n in heldout_batch.sum(axis=1)])
return DCG / IDCG
def Recall_at_k_batch(X_pred, heldout_batch, k=100):
batch_users = X_pred.shape[0]
idx = bn.argpartition(-X_pred, k, axis=1) # top k
X_pred_binary = np.zeros_like(X_pred, dtype=bool)
X_pred_binary[np.arange(batch_users)[:, np.newaxis], idx[:, :k]] = True
X_true_binary = (heldout_batch > 0)
tmp = (np.logical_and(X_true_binary, X_pred_binary).sum(axis=1)).astype(np.float32)
recall = tmp / np.minimum(k, X_true_binary.sum(axis=1))
return recall