Skip to content

Commit

Permalink
Added IPRL
Browse files Browse the repository at this point in the history
  • Loading branch information
makgyver committed Mar 13, 2019
1 parent 9e69741 commit 331c222
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 5 deletions.
28 changes: 23 additions & 5 deletions PRL/genK.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
import random
import math

#TODO documentation

Expand Down Expand Up @@ -50,7 +51,6 @@ def get_kernel_function(self, d):
return self.kernel_list[d]



class GenHPK(GenK):
def __init__(self, min_deg=2, max_deg=2):
self.min_deg = min_deg
Expand All @@ -62,8 +62,26 @@ def __repr__(self):
def get_random_kernel(self):
return random.randint(self.min_deg, self.max_deg)

def get_pref_kernel_function(self, d):
return lambda p1, p2: apply2prefs(self.get_kernel_function(d), p1, p2)
def get_pref_kernel_function(self, degree):
return lambda p1, p2: apply2prefs(self.get_kernel_function(degree), p1, p2)

def get_kernel_function(self, d):
return lambda x,z: np.dot(x,z)**d
def get_kernel_function(self, degree):
return lambda x,z: np.dot(x,z)**degree


class GenRBFK(GenKList):
def __init__(self, gamma_range):
self.gamma_range = gamma_range

def __repr__(self):
return "GenRBFK(gamma_range=%s)" %(self.gamma_range)

def get_random_kernel(self):
return random.choice(self.gamma_range)

def get_pref_kernel_function(self, gamma):
return lambda p1, p2: apply2prefs(self.get_kernel_function(gamma), p1, p2)

def get_kernel_function(self, gamma):
return lambda x,z: math.exp(-gamma * np.linalg.norm(x-z)**2)
#return lambda x,z: math.exp(-gamma * np.sum((x-z)**2))
21 changes: 21 additions & 0 deletions PRL/genP.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,24 @@ def get_all_prefs(self):

def __repr__(self):
return "Micro preference generator"


class GenIP(GenP):
"""Instance-based preference generator. These are actually degenerate preferences that are
simple instances."""

def __init__(self, X):
self.X = X
self.n = X.shape[0]

def get_random_pref(self):
return random.randint(0, self.n-1)

def get_pref_value(self, p):
return self.X[p]

def get_all_prefs(self):
return range(self.n)

def __repr__(self):
return "Instance-based preference generator"
70 changes: 70 additions & 0 deletions PRL/prl.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,73 @@ def predict(self, gen_pref_test):
y_pred.append(np.argmax(sco))

return np.array(y_pred)


class IBPRL(PRL):

def __init__(self, X, gen_feat, n_cols, solver):
super(IBPRL, self).__init__(self, GenIP(X), gen_feat, 1, n_cols, solver)

def __repr__(self):
return "IBPRL(gen_pref=%s, gen_feat=%s, n_rows=%d, n_cols=%d, solver=%s)"\
%(self.gen_pref, self.gen_feat, self.n_rows, self.n_cols, self.solver)

def compute_column(self, iqx, f):
qx = self.gen_pref.get_pref_value(iqx)
R = np.zeros((self.n_rows, 1))
for i, ipx in enumerate(self.pref_list):
R[i, 0] = self.gen_feat.get_feat_value(f, self.gen_pref.get_pref_value(ipx))

return R*qx

def get_new_col(self):
(ix, f) = self.get_random_pair()
while (ix, f) in self.col_set:
(ix, f) = self.get_random_pair()
return (ix, f)


def fit(self, iterations=1000, verbose=False):
if verbose:
logging.info("Starting training of %s" %self)
logging.info("Matrix game initialization...")

for j in range(self.n_cols):
(ix, f) = self.get_new_col()
self.col_list.append((ix, f))
self.col_set.add((ix, f))
self.M[:,j] = self.compute_column(ix, f)

#iterative updates
for t in range(iterations):
if verbose: logging.info("IBPRL iteration %d/%d" %(t+1, iterations))
(P, Q, V) = self.solver.solve(self.M, self.n_rows, self.n_cols)
if verbose: logging.info("Value of the game (current margin): %.6f" %V)
if (t+1 < iterations):
for j in range(self.n_cols):
if Q[j] <= 0:
(ix, f) = self.get_new_col()
self.col_set.remove(self.col_list[j])
self.col_list[j] = (ix, f)
self.col_set.add((ix, f))
self.M[:,j] = self.compute_column(ix, f)

if verbose:
logging.info("# of kept columns: %d" %(np.sum(Q>0)))
logging.info("# of unique features: %d\n" %len(set([f for i, (ix, f) in enumerate(self.col_list) if Q[i]>0.])))
self.Q = Q


def predict(self, gen_pref_test):
X = gen_pref_test.X
y_pred = []
for i in range(gen_pref_test.n):
x = X[i,:]
y = 0
for j, (ix, f) in enumerate(self.col_list):
if self.Q[j] > 0.0:
xp = self.gen_pref.get_pref_value(ix)
y += self.Q[j]*self.gen_feat.get_feat_value(f, xp)*self.gen_feat.get_feat_value(f, x)
y_pred.append(y)

return np.array(y_pred)

0 comments on commit 331c222

Please sign in to comment.