The PRank algorithm is a modification of the perceptron classifier. It aims to classify items into tiers, where the tiers are ordered.
def prank(stats, tiers, n_tiers, iters): ''' Implementation of the PRank algorithm (http://papers.nips.cc/paper/2023-pranking-with-ranking.pdf) stats: array of features, a column per feature tiers: array of rankings, one ranking per player n_tiers: number of tiers, tiers are numbered 0,1,2,...,n_tiers-1 iters: number of iterations of loop ''' n_players = len(stats) n_features = len(stats[0]) w = np.zeros([n_features]) # weight of features b = np.zeros([n_tiers]) # cutoffs for rankings b[-1] = np.inf loss = 0 # total loss incurred by algorithm for i in range(iters): # update w and b given training example x n = i%n_players x = stats[n].copy() y = np.argmax(b > np.dot(x,w)) # get rank of x as determined by current w and b y_act = tiers[n] loss += abs(y-y_act) if y != tiers[n]: # if predicted rank is not actual rank, update w and b y_arr = np.repeat([1,-1],[y_act,n_tiers-1-y_act]) # create y array t_arr = np.zeros([n_tiers-1]) y_n = np.argmax(b >= np.dot(x,w)) if y_act > y_n: t_arr = np.repeat([0,1,0],[y_n,y_act-y_n,n_tiers-1-y_act]) else: t_arr = np.repeat([0,-1,0],[y_act,y_n-y_act,n_tiers-1-y_n]) w = w + np.sum(t_arr)*x b[:-1] = b[:-1] - t_arr return w, b, 1.0*loss/iters def rank(x,w,b): ''' Subroutine for use in PRank Calculates rank of example x given feature weights w and rank cutoffs b ''' return np.argmax(b > np.dot(x,w))