Metflix: porque você assistiu X

Mohtadi Ben Fraj 31 de março Netflix porque você assistiu ao recurso

Onde estamos?

Foi isso que fizemos até agora

  • Na parte 0 , baixamos nossos dados do MovieLens , fizemos alguns EDA e criamos nossa matriz de itens de usuário. A matriz tem 671 usuários únicos, 9066 filmes únicos e é 98,35% esparsa
  • Na parte 1 , descrevemos 3 dos métodos de recomendação mais comuns: Filtragem Colaborativa Baseada em Usuário, Filtragem Colaborativa Baseada em Item e Fatoração de Matriz
  • Na parte 2 , implementamos a Fatoração de Matriz através do ALS e encontramos filmes semelhantes
  • Na parte 3, nesta parte, recomendamos filmes aos usuários com base nos filmes que eles classificaram. Também tentamos clonar o recurso "porque você assistiu X" da Netflix e fazer uma recomendação completa de página com filmes populares

Recomendar filmes para usuários

Pegamos nosso código onde treinamos o modelo ALS da biblioteca implícita . O código anterior para carregar e processar os dados pode ser encontrado nas postagens anteriores desta série ou no meu Github .

 model = implicit.als.AlternatingLeastSquares (fatores = 10, 
iterações = 20,
regularização = 0,1,
num_threads = 4)
 model.fit (user_item.T) 

Primeiro vamos escrever uma função que retorne os filmes que um determinado usuário tinha avaliado

 def get_rated_movies_ids (user_id, user_item, usuários, filmes): 
“” ”
Entrada
-----
 user_id: int 
ID do usuário
 user_item: scipy.Sparse Matrix 
Matriz de interação entre itens do usuário
 usuários: np.array 
Mapeando matriz entre o ID do usuário e o índice na matriz de item do usuário
 filmes: np.array 
Mapeamento de matriz entre o ID do filme e o índice na matriz de itens do usuário
 Saída 
-----
 movieTableIDs: lista de python 
Lista de IDs de filmes que o usuário avaliou
 “” ” 
user_id = users.index (user_id)
# Obter identificações de matriz de filmes classificados pelo usuário selecionado
ids = user_item [user_id] .nonzero () [1]
# Converter identificações de matriz em IDs de filmes
movieTableIDs = [filmes [item] para item em ids]
 return movieTableIDs 
 movieTableIDs = get_rated_movies_ids (1, user_item, usuários, filmes) 
rated_movies = pd.DataFrame (movieTableIDs, columns = ['movieId'])
rated_movies
 def get_movies (movieTableIDs, movies_table): 
“” ”
Entrada
-----
 movieTableIDs: lista de python 
Lista de IDs de filmes que o usuário avaliou
 movies_table: pd.DataFrame 
DataFrame de informações sobre filmes
 Saída 
-----
 rated_movies: pd.DataFrame 
DataFrame de filmes classificados
 “” ” 
 rated_movies = pd.DataFrame (movieTableIDs, columns = ['movieId']) 
 rated_movies = pd.merge (rated_movies, movies_table, on = 'movieId', como = 'left') 
 return rated_movies 

movieTableIDs = get_rated_movies_ids (1, user_item, usuários, filmes)
df = get_movies (movieTableIDs, movies_table)
df

Agora, recomendamos os filmesID para um ID de usuário específico com base nos filmes que eles classificaram.

 def recommend_movie_ids (user_id, model, user_item, usuários, filmes, N = 5): 
“” ”
Entrada
-----
 user_id: int 
ID do usuário
 modelo: modelo ALS 
Modelo treinado de ALS
 user_item: sp.Sparse Matrix 
Matriz de interação do item de usuário para que não recomendamos filmes já classificados
 usuários: np.array 
Mapeamento de matriz entre o ID do usuário e o índice do item do usuário
 filmes: np.array 
Mapeamento de matriz entre o ID do filme e o índice do item do usuário
 N: int (padrão = 5) 
Número de recomendações
 Saída 
-----
 movies_ids: lista de python 
Lista de IDs de filmes
“” ”
 user_id = users.index (user_id) 
 recomendações = model.recommend (user_id, user_item, N = N) 
 recomendações = [item [0] para item nas recomendações] 
 movies_ids = [movies [ids] para ids em recomendações] 
 retornar movies_ids 
 movies_ids = recommend_movie_ids (1, modelo, user_item, usuários, filmes, N = 5) 
movies_ids
 > [1374, 1127, 1214, 1356, 1376] 
 movies_rec = get_movies (movies_ids, movies_table) 
movies_rec
 display_posters (movies_rec) 
 movies_ids = recommended_movie_ids (100, modelo, user_item, usuários, filmes, N = 7) 
movies_rec = get_movies (movies_ids, movies_table)
display_posters (movies_rec)

Porque você assistiu

Vamos implementar o recurso "Porque você assistiu" da Netflix. É sobre recomendar filmes com base no que você assistiu. Isso é semelhante ao que já fizemos, mas, desta vez, é mais seletivo. Veja como faremos isso: escolheremos aleatoriamente cinco filmes que um usuário assistiu e, para cada filme, recomendamos filmes semelhantes a ele. Finalmente, exibimos todos eles em um layout de uma página

 def similar_items (item_id, movies_table, filmes, N = 5): 
“” ”
Entrada
-----
item_id: int
MovieID na tabela de filmes
 movies_table: DataFrame 
DataFrame com IDs de filmes, título do filme e gênero
 filmes: np.array 
Mapeamento entre o movieID na movies_table e o id na matriz do usuário do item
 N: int 
Número de filmes semelhantes para devolver
 Saída 
-----
df: DataFrame
DataFrame com o filme selecionado na primeira linha e filmes semelhantes para N linhas seguintes
“” ”
 # Obter o índice do usuário do filme a partir do array de mapeamento 
user_item_id = movies.index (item_id)
# Obtenha filmes semelhantes do modelo ALS
similars = model.similar_items (user_item_id, N = N + 1)
# ALS similar_items fornece (id, score), extraímos uma lista de ids
l = [item [0] para item em similar [1:]]
# Converta esses ids em movieID do array de mapeamento
ids = [movies [ids] para ids em l]
# Faça um dataFrame do movieIds
ids = pd.DataFrame (ids, columns = ['movieId'])
# Adicione títulos de filmes e gêneros juntando-se à tabela de filmes
recomendação = pd.merge (ids, movies_table, on = 'movieId', como = 'left')
 recomendação de retorno 
 def similar_and_display (item_id, movies_table, filmes, N = 5): 
 df = similar_items (item_id, movies_table, movies, N = N) 
 df.dropna (inplace = True) 
 display_posters (df) 
 def because_you_watched (usuário, user_item, usuários, filmes, k = 5, N = 5): 
“” ”
Entrada
-----
usuário: int
ID do usuário
 user_item: matriz escassa escassa 
Matriz de interação entre itens do usuário
 usuários: np.array 
Mapeamento de matriz entre o ID do usuário e o índice do item do usuário
 filmes: np.array 
Mapeamento de matriz entre o ID do filme e o índice do item do usuário
 k: int 
Número de recomendações por filme
 N: int 
Número de filmes já assistidos escolhidos
 “” ” 
 movieTableIDs = get_rated_movies_ids (usuário, user_item, usuários, filmes) 

df = get_movies (movieTableIDs, movies_table)
 movieIDs = random.sample (df.movieId, N) 
 para movieID em movieIDs: 
title = df [df.movieId == movieID] .iloc [0] .title
print ("Porque você assistiu", título)
similar_and_display (movieID, movies_table, movies, k)
 because_you_watched (500, user_item, usuários, filmes, k = 5, N = 5) 

"Porque você assistiu", "Definitivamente, talvez (2008)"

"Porque você assistiu", "Pocahontas (1995) "

"Porque você assistiu", 'Simpsons Movie, The (2007)'

"Porque você assistiu", 'Catch Me If You Can (2002)'

"Porque você assistiu", "Risky Business (1983)"

Trending movies

Vamos também implementar filmes de tendências. Em nosso contexto, os filmes populares são os mais classificados pelos usuários

 def get_trending (user_item, filmes, filmes_table, N = 5): 
“” ”
Entrada
-----
 user_item: matriz escassa escassa 
Matriz de interação de item do usuário para usar para extrair filmes populares
 filmes: np.array 
Mapeando matriz entre movieId e ID na matriz user_item
 movies_table: pd.DataFrame 
DataFrame para informação de filmes
 N: int 
Top N filmes mais populares para retornar
 “” ” 
 binário = user_item.copy () 
binário [binário! = 0] = 1
 populars = np.array (binary.sum (axis = 0)). reformular (-1) 
 movieIDs = populars.argsort () [:: - 1] [: N] 
 movies_rec = get_movies (movieIDs, movies_table) 
 movies_rec.dropna (inplace = True) 
 print (“Tendência agora”) 
 display_posters (movies_rec) 
 get_trending (user_item, filmes, movies_table, N = 6) 

Tendências agora

Recomendação de página

Vamos colocar tudo em um método de linha do tempo. O método da linha do tempo obterá o ID do usuário e exibirá filmes e recomendações de tendências com base em filmes semelhantes que esse usuário assistiu.

 def my_timeline (usuário, user_item, usuários, filmes, movies_table, k = 5, N = 5): 
 get_trending (user_item, movies, movies_table, N = N) 
 because_you_watched (usuário, user_item, usuários, filmes, k = k, N = N) 
 my_timeline (500, user_item, usuários, filmes, movies_table, k = 5, N = 5) 

Tendências agora

"Porque você assistiu", "Definitivamente, talvez (2008)"

"Porque você assistiu", "Pocahontas (1995)"

"Porque você assistiu", 'Simpsons Movie, The (2007)'

"Porque você assistiu", 'Catch Me If You Can (2002)'

"Porque você assistiu", "Risky Business (1983)"

Exporte modelos treinados para serem usados na produção

Neste ponto, queremos colocar nosso modelo em produção. Queremos criar um serviço da web em que um usuário forneça um ID do usuário para o serviço, e o serviço retornará todas as recomendações, incluindo a tendência e o "porque você assistiu".

Para fazer isso, primeiro exportamos o modelo treinado e os dados usados para uso no serviço da web.

 import scipy.sparse 
 scipy.sparse.save_npz ('model / user_item.npz', user_item) 
 np.save ('model / movies.npy', filmes) 
np.save ('model / users.npy', users)
movies_table.to_csv ('model / movies_table.csv', index = False)
 de joblib de importação sklearn.externals 
joblib.dump (model, 'model / model.pkl')

Conclusão

Nesta postagem, recomendamos filmes para usuários com base no histórico de classificações de filmes. A partir daí, tentamos clonar o recurso "porque você assistiu" do Netflix e também exibimos os filmes "Tendências" como filmes que foram classificados com o maior número de vezes. Na próxima postagem, tentaremos colocar nosso trabalho em um serviço da web, em que um usuário solicita recomendações de filme, fornecendo seu ID de usuário.

Fique ligado!