-
Notifications
You must be signed in to change notification settings - Fork 1
/
learn-mslr.py
231 lines (163 loc) · 8.27 KB
/
learn-mslr.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import pickle
from collections import defaultdict
import sys
from torch.utils.data import Dataset, DataLoader
from Mmetrics import *
import LTR
import datautil
import permutationgraph
import DTR
import EEL
import PPG
import PPG_single
import PL
def df2ds(df_path):
with open(df_path, 'rb') as f:
df = pickle.load(f)
ds = df.to_dict(orient='list')
for k in ds:
ds[k] = np.array(ds[k])
ds['dlr'] = np.concatenate([np.zeros(1), np.where(np.diff(ds['qid'])==1)[0]+1, np.array([ds['qid'].shape[0]])]).astype(int)
return type('ltr', (object,), ds)
def dict2ds(df_path):
with open(df_path, 'rb') as f:
ds = pickle.load(f)
return type('ltr', (object,), ds)
dsmslr = dict2ds('nLTRMSLR_dict.df')
epochs = 50
alg = 'PPG'
if len(sys.argv) > 1:
alg = sys.argv[1]
metric = 'EEL'
if len(sys.argv) > 2:
metric = sys.argv[2]
intra = False
suffix = 'nointra_'
if len(sys.argv) > 3:
if sys.argv[3] == 'intra':
intra = True
suffix='intra_'
sessions_cnt=20
if len(sys.argv) > 4:
sessions_cnt = eval(sys.argv[4])
suffix += f'{alg}_{sessions_cnt}_{sys.argv[5]}_mslr'
exposuremslr = np.array([1./np.log2(2+i) for i in range(1,np.diff(dsmslr.dlr).max()+2)])
def learn_one_PPG_single(metric, qid, verbose, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt):
s, e = dlr[qid:qid+2]
if metric == 'EEL':
objective_ins = EEL.EEL(y_pred = y_pred[s:e], g = g[s:e], dlr = np.array([0,e-s]), exposure=exposure, grade_levels = grade_levels)
else:
objective_ins = DTR.DTR(y_pred = y_pred[s:e], g = g[s:e], dlr = np.array([0,e-s]), exposure=exposure)
learner = PPG_single.Learner( PPG_mat=None, samples_cnt=samples_cnt,
objective_ins=objective_ins,
sorted_docs = y_pred[s:e].argsort()[::-1],
intra = g[s:e] if intra else np.arange(g[s:e].shape[0]),
sessions_cnt=sessions_cnt)
vals = learner.fit(epochs, lr, verbose=verbose)
return vals
def learn_all_PPG_single(metric, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt):
sorted_docs = []
# for qid in trange(dlr.shape[0] - 1, leave=False):
for qid in range(dlr.shape[0] - 1):
min_b = learn_one_PPG_single(metric, qid, 0, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt)
sorted_docs.append(min_b)
# print(ndcg_dtr(exposure, lv, np.concatenate(y_rerank), dlr, g, query_counts))
return sorted_docs
def learn_one_PPG(metric, qid, verbose, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt):
s, e = dlr[qid:qid+2]
y_pred_s, g_s, sorted_docs_s, dlr_s = \
EEL.copy_sessions(y=y_pred[s:e], g=g[s:e], sorted_docs=y_pred[s:e].argsort()[::-1], sessions=sessions_cnt)
if metric == 'EEL':
objective_ins = EEL.EEL(y_pred = y_pred_s, g = g_s, dlr = dlr_s, exposure=exposure, grade_levels = grade_levels)
else:
objective_ins = DTR.DTR(y_pred = y_pred_s, g = g_s, dlr = dlr_s, exposure=exposure)
learner = PPG.Learner( PPG_mat=None, samples_cnt=samples_cnt,
objective_ins=objective_ins,
sorted_docs = sorted_docs_s,
dlr = dlr_s,
intra = g_s if intra else np.arange(g_s.shape[0]),
inter = np.repeat(dlr_s[:-1], np.diff(dlr_s)))
vals = learner.fit(epochs, lr, verbose=verbose)
return vals
def learn_all_PPG(metric, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt):
sorted_docs = []
# for qid in trange(dlr.shape[0] - 1, leave=False):
for qid in range(dlr.shape[0] - 1):
min_b = learn_one_PPG(metric, qid, 0, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt)
sorted_docs.append(min_b)
# print(ndcg_dtr(exposure, lv, np.concatenate(y_rerank), dlr, g, query_counts))
return sorted_docs
def learn_one_PL(metric, qid, verbose, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt):
s, e = dlr[qid:qid+2]
if metric == 'EEL':
objective_ins = EEL.EEL(y_pred = y_pred[s:e], g = g[s:e], dlr = np.array([0,e-s]), exposure=exposure, grade_levels = grade_levels)
else:
objective_ins = DTR.DTR(y_pred = y_pred[s:e], g = g[s:e], dlr = np.array([0,e-s]), exposure=exposure)
learner = PL.Learner(logits=y_pred[s:e], samples_cnt=samples_cnt,
objective_ins=objective_ins, sessions_cnt=sessions_cnt)
vals = learner.fit(epochs, lr, verbose=verbose)
return vals
def learn_all_PL(metric, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt):
sorted_docs = []
# for qid in trange(dlr.shape[0] - 1, leave=False):
for qid in range(dlr.shape[0] - 1):
min_b = learn_one_PL(metric, qid, 0, y_pred, g, dlr, epochs, lr, exposure, grade_levels, samples_cnt, sessions_cnt)
sorted_docs.append(min_b)
# print(ndcg_dtr(exposure, lv, np.concatenate(y_rerank), dlr, g, query_counts))
return sorted_docs
def estimated_evaluate_one(metric, qid, y_pred, g, dlr, output_permutation, exposure, sessions_cnt):
s, e = dlr[qid:qid+2]
permutation = output_permutation[qid]
lv_s, g_s, sorted_docs_s, dlr_s = \
EEL.copy_sessions(y=y_pred[s:e], g=g[s:e], sorted_docs=y_pred[s:e].argsort()[::-1], sessions=sessions_cnt)
if metric == 'EEL':
objective_ins = EEL.EEL(y_pred = lv_s, g = g_s, dlr = dlr_s, exposure=exposure, grade_levels = 2)
else:
objective_ins = DTR.DTR(y_pred = lv_s, g = g_s, dlr = dlr_s, exposure=exposure)
return objective_ins.eval(permutation)
def estimated_evaluate_all(metric, y_pred, g, dlr, output_permutation, exposure, sessions_cnt):
eel_res = []
for qid in range(dlr.shape[0] - 1):
s,e = dlr[qid:qid+2]
if len(np.unique(g[s:e])) == 1:
continue
eel = estimated_evaluate_one(metric, qid, y_pred, g, dlr, output_permutation, exposure, sessions_cnt)
eel_res.append(eel)
return np.array(eel_res).mean()
learn_fn = eval(f'learn_all_{alg}')
res = {}
def find_best(y_pred, sds, exposure, sessions_cnt):
best_lr = 0
best_samples_cnt = 0
best_fairness = np.inf
for learning_rate in ['0.01', '0.1']:
for samples_cnt in [4,8,16,32]:
output_permutation = learn_fn(metric, y_pred, sds.g, sds.dlr,
epochs, eval(learning_rate), exposure=exposure,
grade_levels=5, samples_cnt=samples_cnt, sessions_cnt=sessions_cnt)
fairness = estimated_evaluate_all(metric, y_pred, sds.g, sds.dlr,
output_permutation, exposure, sessions_cnt)
if fairness < best_fairness:
best_lr = learning_rate
best_samples_cnt = samples_cnt
best_fairness = fairness
return best_lr, best_samples_cnt
for run_i in range(2):
# learning_rate, samples_cnt = find_best(sdsmslr.y_pred, sdsmslr, exposuremslr, sessions_cnt)
learning_rate, samples_cnt = '0.1', 16
res[f'mslr_{learning_rate}_{samples_cnt}_{run_i}'] = \
learn_fn(metric, dsmslr.y_pred, dsmslr.g, dsmslr.dlr, epochs, eval(learning_rate), exposure=exposuremslr,
grade_levels=5, samples_cnt=samples_cnt, sessions_cnt=sessions_cnt)
with open(f'/ivi/ilps/personal/avardas/_data/PPG/n/mslr/{suffix}_{metric}_results.pkl', 'wb') as f:
pickle.dump(res, f)
learning_rate, samples_cnt = '0.1', 16
# learning_rate, samples_cnt = find_best(sdsmslr.lv, sdsmslr, exposuremslr, sessions_cnt)
res[f'lv_mslr_{learning_rate}_{samples_cnt}_{run_i}'] = \
learn_fn(metric, dsmslr.lv, dsmslr.g, dsmslr.dlr, epochs, eval(learning_rate), exposure=exposuremslr,
grade_levels=5, samples_cnt=samples_cnt, sessions_cnt=sessions_cnt)
with open(f'/ivi/ilps/personal/avardas/_data/PPG/n/mslr/{suffix}_{metric}_results.pkl', 'wb') as f:
pickle.dump(res, f)