Sistemas de Recomendação

A ideia aqui é bem simples: implementarmos um Sistema de Recomendação que vai recomendar áreas de estudo da computação para usuários. O nosso Sistema de Recomendação se baseará nos interesses dos outros usuários para efetuar a recomendação.


In [ ]:
import exercise_utils as eu
import math
from collections import defaultdict

# esse é o nosso dataset
users_interests = eu.get_users_interests() # se não tivermos o dataset, usar eu.get_users_interests_poor()

O código abaixo cria um vetor global de todos os possíveis interesses.


In [ ]:
unique_interests = sorted(list({ interest 
                                for user_interests in users_interests
                                for interest in user_interests }))
unique_interests

Montando a Matrix

Implemente a função make_user_interest_vector abaixo. Ela será usada para montar a matrix de interesse.


In [ ]:
def make_user_interest_vector(user_interests):
    """ Essa função recebe uma lista de interesses de um usuário e 
        retorna a lista unique_interests substituindo o interesses 
        por 0 ou 1 seguindo a lógica: 
            1, se o item de unique_interests está na user_interest.
            0, se o item de unique_interests NÃO está na user_interest """
    return []

In [ ]:
user_interest_matrix = map(make_user_interest_vector, users_interests)

# A user é formada dos seguintes dados:
#   - cada LINHA representa o interesse de um usuário para todos os interesses
#   - cada COLUNA é o índice global de um interesse
#   - cada CÉLULA(u, i) contém 1 ou 0: 1 se o usuário u se interessa em i, 0 caso contrário
eu.print_matrix(user_interest_matrix)

Função de Similaridade

Implemente a função de similaridade cosseno. Essa função retorna valores entre 0 e 1. Quanto mais próximo de 1, mais semelhantes são os vetores. Quanto mais próximo de 0, mais diferentes eles são.


In [ ]:
def cosine_similarity(va, vb):
    return 0.0

Usando a função de similaridade implementada, o código abaixo cria uma outra matriz. Essa nova matriz é NxN, onde N é o número de usuários. Cada célula (i, j) contém a similaridade do vetor de interesse do usuário i com o vetor de interesse do usuário j.


In [ ]:
user_similarities = [[cosine_similarity(user_i_interest_vector, user_j_interest_vector) 
                      for user_j_interest_vector in user_interest_matrix] 
                     for user_i_interest_vector in user_interest_matrix]

eu.print_matrix(user_similarities)

Algoritmo de Recomendação

A primeira etapa da implementação do nosso algoritmo envolve essa função auxiliar, definida abaixo. Ela deve ser implementada de acordo com a implementação do algoritmo abaixo.


In [ ]:
# ALGORITMO: most_similar_users_to
# ENTRADA: usuario_id: identificador de um usuário. O índice do usuário na matriz dos dados.
# SAÍDA: Lista de 2-tuplas contendo ( outro usuário != user_id, similaridade entre o usuário e user_id).
#        A lista retornada deve ser ordenada pela similaridade entre os usuários.
#
# BEGIN
# 
# pares <- []
#
# FOR EACH outro_usuario_id, similaridade IN enumerate(user_similarities) THEN:
#   IF outro_usuario_id != user_id AND similaridade > 0 THEN:
#     pares.add((outro_usuario_id, similaridade))
#
# RETURN ordenar(pares, por=similaridade, em_ordem=decrescente)
# 
# END

def most_similar_users_to(user_id):
    return []

Implementada a função que obtém os usuários mais similares a um dado usuário, a segunda etapa do nosso algoritmo pode usá-la para obter uma lista de recomendações de interesses para um dado usuário. Basta implementar a função a seguir de acordo com a descrição dada:


In [ ]:
# ALGORITMO: user_based_suggestions
# ENTRADA: usuario_id: identificador de um usuário. O índice do usuário na matriz dos dados.
# SAÍDA: Uma lista de interesses não "marcados" pelo usuário ordenada pelo índice de recomendação do algoritmo.
#
# BEGIN
#
# // Somando as similaridades de cada interesse em um dicionário. A chave é o interesse e o valor o peso.
# sugestoes <- empty_float_dict()
# FOR EACH outro_usuario_id, similaridade IN most_similar_users_to(usuario_id) THEN:
#   FOR EACH interesse IN users_interests[outro_usuario_id] THEN:
#     sugestoes[intersse] += similaridade
#
# // convertendo dicionário para um lista ordenada
# sugestoes = ordernar(sugestoes.items(), por=peso, em_order=decrescente)
#
# sugestoes_final = []
# FOR EACH sugestao IN sugestoes THEN:
#   IF sugestao NOT IN users_interests[user_id] THEN:
#     suggestoes_final.add(sugestao)
# END

def user_based_suggestions(user_id):
    return []

Para vermos o resultado da recomendação, basta chamar a função user_based_suggestions informado o identificador do usuário:


In [ ]:
user_based_suggestions(0)