我正在使用keras来构建推荐模型。因为项目集非常大,我想计算Hits @ N指标作为准确度的度量。也就是说,如果观察到的项目位于前N个预测中,则将其视为相关推荐。
我能够使用numpy在N函数中构建命中。但是当我试图将它移植到keras的自定义丢失函数时,我遇到了张量问题。具体而言,在张量上的枚举是不同的。当我查看语法以找到相同的东西时,我开始质疑整个方法。它邋and而缓慢,反映了我对蟒蛇的熟悉程度。
def hits_at(y_true, y_pred): #numpy version
a=y_pred.argsort(axis=1) #ascending, sort by row, return index
a = np.fliplr(a) #reverse to get descending
a = a[:,0:10] #return only the first 10 columns of each row
Ybool = [] #initialze 2D arrray
for t, idx in enumerate(a):
ybool = np.zeros(num_items +1) #zero fill; 0 index is reserved
ybool[idx] = 1 #flip the recommended item from 0 to 1
Ybool.append(ybool)
A = map(lambda t: list(t), Ybool)
right_sum = (A * y_true).max(axis=1) #element-wise multiplication, then find the max
right_sum = right_sum.sum() #how many times did we score a hit?
return right_sum/len(y_true) #fraction of observations where we scored a hit
我应该如何以更紧凑,更紧张的方式处理这个问题?
更新:
我能够获得Top 1的版本。我基于GRU4Rec描述松散地基于它
def custom_objective(y_true, y_pred):
y_pred_idx_sort = T.argsort(-y_pred, axis=1)[:,0] #returns the first element, which is the index of the row with the largest value
y_act_idx = T.argmax(y_true, axis=1)#returns an array of indexes with the top value
return T.cast(-T.mean(T.nnet.sigmoid((T.eq(y_pred_idx_sort,y_act_idx)))), theano.config.floatX)
我只需要将前1个预测的数组与实际元素数组进行比较。而Theano有一个eq()函数来做到这一点。
答案 0 :(得分:0)
与N无关,损失函数的可能值的数量是有限的。因此,它不能以明显的张量方式区分,你不能在Keras / Theano中将它用作损失函数。您可以尝试使用前N个人的theano日志丢失。
更新:
在Keras - 您可以编写自己的损失函数。他们有一份表格声明:
def loss_function(y_pred, y_true):
y_true
和y_pred
都是numpy数组,因此您可以轻松获得向量v
,当给出的示例位于前500时为0,否则为0。然后你可以将它转换为theano张量常数向量并以一种方式应用它:
return theano.tensor.net.binary_crossentropy(y_pred * v, y_true * v)
这应该可以正常工作。
更新2:
日志丢失与binary_crossentropy相同。