Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tarea 1] Implementación de métricas de evaluación #11

Open
josuetsm opened this issue Sep 14, 2021 · 2 comments
Open

[Tarea 1] Implementación de métricas de evaluación #11

josuetsm opened this issue Sep 14, 2021 · 2 comments
Labels
Practico Tarea 1 Pregunta acerca de la tarea 1

Comments

@josuetsm
Copy link

Hola!, estaba realizando una implementación alternativa de las métricas MAP y nDCG para evaluar más rápido y me quedan dos dudas respecto a la implementación de nDCG en el práctico de Implicit feedback:

# Definicion de métricas (No editar)
# Obtenido de https://gist.github.com/bwhite/3726239

def precision_at_k(r, k):
    assert k >= 1
    r = np.asarray(r)[:k] != 0
    if r.size != k:
        raise ValueError('Relevance score length < k')
    return np.mean(r)

def average_precision(r):
    r = np.asarray(r) != 0
    out = [precision_at_k(r, k + 1) for k in range(r.size) if r[k]]
    if not out:
        return 0.
    return np.mean(out)

def mean_average_precision(rs):
    return np.mean([average_precision(r) for r in rs])
  
def dcg_at_k(r, k):
    r = np.asfarray(r)[:k]
    if r.size:
        return np.sum(np.subtract(np.power(2, r), 1) / np.log2(np.arange(2, r.size + 2)))
    return 0.


def ndcg_at_k(r, k):
    idcg = dcg_at_k(sorted(r, reverse=True), k)

    if not idcg:
        return 0.
    return dcg_at_k(r, k) / idcg

def evaluate_model(model, n):
    mean_map = 0.
    mean_ndcg = 0.
    for u in user_items_test.keys():
        rec = [t[0] for t in model.recommend(u, user_item_matrix, n)]
        rel_vector = [np.isin(user_items_test[u], rec, assume_unique=True).astype(int)]
        mean_map += mean_average_precision(rel_vector)
        mean_ndcg += ndcg_at_k(rel_vector, n)

    mean_map /= len(user_items_test)
    mean_ndcg /= len(user_items_test)

    return mean_map, mean_ndcg

Lo primero (entiendo que ya lo comentaron), tiene que ver con rel_vector = [np.isin(user_items_test[u], rec, assume_unique=True).astype(int)]

Esto genera vectores de tamaño variable, dependiendo de cuántos items relevantes hay en el test. Ante esto, entiendo que debería ser al revés:
rel_vector = [np.isin(rec, user_items_test[u], assume_unique=True).astype(int)]
De esta forma estaríamos consultando si las recomendaciones (10 recomendaciones por ejemplo) están en los ítems del test del usuario, obteniendo vectores de tamaño fijo. ¿Estoy en lo correcto?

Mi segunda duda tiene que ver con ndcg_at_k(rel_vector, n), debido a que esta da solo 0 o 1 para cada usuario. Entiendo que esto tiene que ver con que rel_vector no es un array, sino que una lista que contiene 1 array. De esta forma, al calcular nDCG@10 en [0, 0, 0, 0, 0, 0, 1, 0, 0, 0] nos queda:

ndcg_at_k([np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0])], 10)
1

Mientras que si lo aplicamos directamente sobre el array nos queda:
ndcg_at_k(np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 10)
0.3333333

Una solución rápida a esto podría ser calcular mean_ndcg += ndcg_at_k(rel_vector[0], n) ¿Estoy en lo correcto? Quedo atento, saludos!

@josuetsm josuetsm changed the title Implementación de métricas de evaluación [Tarea 1] Implementación de métricas de evaluación Sep 14, 2021
@jfacuse jfacuse added Tarea 1 Pregunta acerca de la tarea 1 Practico labels Sep 14, 2021
@alfa-labarca
Copy link
Contributor

Hola, estás en lo correcto en todo lo que dijiste!

@josuetsm
Copy link
Author

Gracias!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Practico Tarea 1 Pregunta acerca de la tarea 1
Projects
None yet
Development

No branches or pull requests

3 participants