在 Theano 中计算 Hits At 指标
Calculate Hits At metric in Theano
我正在使用 keras
构建推荐模型。因为项目集很大,所以我想计算 Hits @ N metric
作为准确性的衡量标准。也就是说,如果观察到的项目在预测的前N个中,则算作相关推荐。
我能够使用 numpy
在 N 函数上构建命中。但是当我试图将它移植到 keras
的自定义损失函数时,我遇到了张量问题。具体来说,枚举张量是不同的。当我研究语法以找到等效的东西时,我开始质疑整个方法。它草率而缓慢,反映了我一般 python 的熟悉程度。
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()
函数可以做到这一点。
与 N 无关,损失函数的可能值的数量是有限的。因此它不能以合理的张量方式微分,你不能将它用作 Keras / Theano 中的损失函数。你可以尝试对前 N 个人使用 theano log loss。
更新:
在 Keras 中 - 您可以编写自己的损失函数。他们有一个表格声明:
def loss_function(y_pred, y_true):
y_true
和 y_pred
都是 numpy 数组,所以你可以很容易地得到一个向量 v
当给出的例子在前 500 名时它是 1,否则是 0。然后你可以将它转换为 theano 张量常数向量并以某种方式应用它:
return theano.tensor.net.binary_crossentropy(y_pred * v, y_true * v)
这应该可以正常工作。
更新 2:
日志丢失与 binary_crossentropy.
是一回事
我正在使用 keras
构建推荐模型。因为项目集很大,所以我想计算 Hits @ N metric
作为准确性的衡量标准。也就是说,如果观察到的项目在预测的前N个中,则算作相关推荐。
我能够使用 numpy
在 N 函数上构建命中。但是当我试图将它移植到 keras
的自定义损失函数时,我遇到了张量问题。具体来说,枚举张量是不同的。当我研究语法以找到等效的东西时,我开始质疑整个方法。它草率而缓慢,反映了我一般 python 的熟悉程度。
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()
函数可以做到这一点。
与 N 无关,损失函数的可能值的数量是有限的。因此它不能以合理的张量方式微分,你不能将它用作 Keras / Theano 中的损失函数。你可以尝试对前 N 个人使用 theano log loss。
更新:
在 Keras 中 - 您可以编写自己的损失函数。他们有一个表格声明:
def loss_function(y_pred, y_true):
y_true
和 y_pred
都是 numpy 数组,所以你可以很容易地得到一个向量 v
当给出的例子在前 500 名时它是 1,否则是 0。然后你可以将它转换为 theano 张量常数向量并以某种方式应用它:
return theano.tensor.net.binary_crossentropy(y_pred * v, y_true * v)
这应该可以正常工作。
更新 2:
日志丢失与 binary_crossentropy.
是一回事