Aprende a construir un sistema de recomendación simple en Python.

Construyendo un sistema de recomendación simple en Python

¿Alguna vez pensaste en cómo Google crea películas de recomendación que se acercan a tu gusto? ¿Cómo lo “resuelve” por ti? Bueno, después de leer este post podrás saber cómo hacerlo. Aún mejor, podrá crear un sistema de recomendaciones usted mismo.

Como creador web, hay  cosas que todo desarrollador de Python debe saber , como pandas y bibliotecas numpy. El programa para principiantes utilizado en este artículo ni siquiera se puede comparar con los estándares de la industria. Por lo tanto, se usa solo como una introducción a los sistemas. Suponemos que los lectores tienen experiencia previa con Python.

¿Qué es un sistema de recomendación?

El sistema de recomendación es un cálculo básico que tiene por objeto detectar correlaciones en un conjunto de datos para proporcionar al cliente la información más relevante. El algoritmo evalúa los elementos y muestra al usuario muchos elementos que están cerca de su preferencia.

Netflix y Amazon son algunos de los mejores ejemplos de tales sistemas de recomendación. Cada vez que elige un artículo en Amazon, automáticamente comienza a mostrarle otro artículo que podría gustarle. Lo mismo ocurre con Netflix y su opción de películas recomendadas para ti.

Recommendor System Python

Hay tres formas de crear un sistema de recomendación;

  • Sistema de recomendación basado en popularidad
  • Sistema de recomendación basado en contenido
  • Sistema de recomendación basado en similitud

Construyendo un sistema de recomendación simple en Python

En el sistema de este recomendador básico, estamos usando movielens. Este es un sistema de recomendación basado en similitudes. Puede usar PyCharm o Skit-Learn si lo desea y ver  por qué pycharm se está volviendo importante para todos los programadores de Python . Entonces, pasando al primer paso, importar numPy y pandas es nuestra principal prioridad.

import pandas as pd 
import numpy as np
import warnings
warnings.filterwarnings('ignore')

Posteriormente, usamos la utilidad pandas read_csv () en el conjunto de datos. El conjunto de datos está separado de la pestaña, por lo que el   parámetro sep se pasa en  \ t . Luego pasamos al parámetro de nombres.

df = pd.read_csv('u.data', sep='\t', names=['user_id','item_id','rating','titmestamp'])

Busquemos en el cabezal de datos para ver los datos que nos interesan.

df.head()

Podría ser mucho más fácil si pudiéramos ver los títulos de las películas en lugar de simplemente ocuparnos de las identificaciones. Para cargar los títulos de las películas y fusionar el conjunto de datos;

movie_titles = pd.read_csv('Movie_Titles')
movie_titles.head()

Dado que las columnas de item_id son todas iguales, estos conjuntos de datos se pueden combinar en esta sección.

df = pd.merge(df, movie_titles, on='item_id')
df.head()

Echemos un vistazo a las representaciones de cada columna:

  • user_id: el ID del usuario que calificó la película.

  • item_id: el ID de la película.

  • rating: la calificación que el usuario le dio a la película, entre 1 y 5.

  • marca de tiempo: la hora a la que se calificó la película.

  • title: el título de la película.

Podemos obtener una breve descripción de nuestro conjunto de datos usando los comandos description o info.

df.describe()

Podemos decir que el puntaje promedio es 3.52 y el puntaje máximo es 5.

Construyamos un marco de datos con la calificación promedio y el número de calificación de cada película. Usaremos estas calificaciones más adelante para medir la correlación entre las películas. Las películas con un alto coeficiente de correlación son las películas más comparables entre sí. Usaremos el coeficiente de correlación de Pearson en nuestro caso. El número variará de -1 a 1. 1 muestra una correlación lineal positiva mientras que la correlación negativa se indica con -1. 0 no muestra ninguna correlación lineal y muestra que estas películas son menos similares de alguna manera.

ratings = pd.DataFrame(df.groupby('title')['rating'].mean())
ratings.head()

Ahora queremos ver la cantidad de calificaciones de cada película. Esto es lo que hacemos al crear una columna como number_of_ratings. Es relevante ver la relación entre la calificación promedio de una película y el número de calificaciones que ha recibido la película. Solo una persona puede haber calificado una película de 5 estrellas. Por lo tanto, clasificar esa película con una película de 5 estrellas es estadísticamente incorrecto.

Por lo tanto, a medida que construimos el sistema de recomendación, necesitamos establecer un umbral para el número mínimo de calificaciones. Usamos pandas de grupo por utilidad para crear esta nueva columna. Agrupamos los títulos y luego usamos la función de conteo para determinar el número de calificaciones de cada película. Usemos la función head () para ver el nuevo marco de datos.

ratings['number_of_ratings'] = df.groupby('title')['rating'].count()
ratings.head()

Usemos ahora pandas para trazar un histograma para representar la distribución de calificaciones

import matplotlib.pyplot as plt
%matplotlib inline
ratings['rating'].hist(bins=50)

Vemos que casi todas las películas van de 2.5 a 4. A continuación, echemos un vistazo similar a la columna de número de calificación.

ratings['number_of_ratings'].hist(bins=60)

Es evidente por el histograma anterior que varias películas tienen muy pocas calificaciones. Las películas con más calificaciones son las más famosas.

Ahora probemos la correlación entre la calificación de una película y el número de calificaciones. Lo hacemos usando seaborn para mapear un gráfico de dispersión. Seaborn lo permite con la función de jointplot ().

import seaborn as sns
sns.jointplot(x='rating', y='number_of_ratings', data=ratings)

Vemos en el gráfico que su conexión es positiva entre el número de calificaciones y las calificaciones promedio de una película. El gráfico muestra que cuanto más alta sea la calificación de una película, más alta será.

Avancemos rápidamente ahora y creemos un sistema de recomendación simple basado en la similitud. Si deseamos ver los títulos de las películas como columnas, user_id como lista y calificaciones como valores, entonces, necesitamos convertir nuestro conjunto de datos en una matriz.

Al hacerlo, obtendremos un marco de datos con columnas como títulos de películas y filas como identificadores de usuario. Cada columna refleja todas las calificaciones de los usuarios de una película. La clasificación indica NAN donde un usuario no ha calificado una película en particular. Para construir la matriz de la película, usamos la utilidad pandas pivot_table.

movie_matrix = df.pivot_table(index='user_id', columns='title', values='rating')
movie_matrix.head()

Primero, veamos las películas mejor calificadas y escojamos 2 de ellas, para comenzar con este sencillo sistema de recomendaciones. Para organizar las películas de las más valoradas, usamos la utilidad de ordenar valores de pandas y las configuramos en falso. Luego usamos la función head () para los 10 primeros.

ratings.sort_values('number_of_ratings', ascending=False).head(10)

Supongamos que Air Force One (1997) y Contact (1997) fueron vistos por un usuario. Según este historial de reproducciones, nos gustaría recomendar películas a este usuario. El objetivo es buscar películas similares a Contact (1997) y Air Force One (1997), que recomendaremos a este usuario. Esto se puede lograr calculando la similitud entre las calificaciones de estas dos películas y las calificaciones del resto de las películas en el conjunto de datos. El primer paso es desarrollar un marco de datos con las calificaciones de dichas películas de la matriz de películas.

AFO_user_rating = movie_matrix['Air Force One (1997)']
contact_user_rating = movie_matrix['Contact (1997)']
AFO_user_rating.head()
contact_user_rating.head()

Usamos la funcionalidad pandas corwith para calcular la correlación entre dos marcos de datos. Corrwith calcula la correlación de pares de filas o columnas de dos objetos de marco de datos. Usemos esta función para obtener nuestros resultados;

similar_to_air_force_one=movie_matrix.corrwith(AFO_user_rating)

Podemos ver que la correlación de la película del Air Force One con Til Was You es 0.867. Esto sugiere que estas dos películas tienen una similitud muy fuerte.

similar_to_air_force_one.head()

Continuando, calculemos la correlación entre las calificaciones de "Contacto" y el resto de las películas usando el mismo procedimiento.

similar_to_contact = movie_matrix.corrwith(contact_user_rating)

Vemos una correlación muy fuerte entre Contact (1997) y Til There Was You (1997).

similar_to_contact.head()

Como se señaló anteriormente, nuestra matriz tenía muchos valores faltantes ya que no todas las películas fueron calificadas por todos los suscriptores. Por lo tanto, volcamos esos valores nulos y convertimos los resultados de la correlación en marcos de datos para que la información parezca más atractiva.

corr_contact = pd.DataFrame(similar_to_contact, columns=['Correlation'])
corr_contact.dropna(inplace=True)
corr_contact.head()
corr_AFO = pd.DataFrame(similar_to_air_force_one, columns=['correlation'])
corr_AFO.dropna(inplace=True)
corr_AFO.head()

Dichos marcos de datos anteriores nos indican las películas que son más similares a las películas de Contact y Air Force One. No obstante, tenemos el problema de que algunas de las películas tienen bastantes críticas y pueden terminar siendo recomendadas simplemente porque una o dos personas les dieron una calificación de 5 estrellas.

Podemos solucionar esto estableciendo varios umbrales de calificación. Hemos visto una fuerte disminución en el número de puntuaciones de 100 del histograma anterior. Por tanto, fijaremos esto como límite, pero este es un número con el que puedes jugar hasta que tengas una opción adecuada.

Para hacer esto, los dos marcos de datos deben unirse con el número de columna de calificación en las calificaciones del marco de datos.

corr_AFO = corr_AFO.join(ratings['number_of_ratings'])
corr_contact = corr_contact.join(ratings['number_of_ratings'])
corr_AFO .head()
corr_contact.head()

Ahora vamos a tener las películas que son más similares a Air Force One al limitarlas a películas que tengan al menos 100 comentarios. Luego los formamos por la columna de la correlación y vemos los primeros diez.

corr_AFO[corr_AFO['number_of_ratings']>100].sort_values(by='correlation', ascending=False).head(10)

Notamos una correlación perfecta entre el Air Force One consigo mismo. La siguiente película más similar de Air Force One es Hunt for Red October, con una correlación de 0.554. Obtenemos resultados diferentes de la forma anterior de hacerlo cambiando el umbral para el número de revisiones. Limitar la cantidad de calificaciones nos da mejores resultados y podemos recomendar las películas anteriores a alguien que haya visto Air Force One (1997) con seguridad y credibilidad.

Conclusión

es, por supuesto, una forma muy fácil de crear un programa de recomendación y no se acerca a los estándares de la industria. Pero aún así, ahora puede encontrar una recomendación de película auténtica similar por su cuenta. ¡Cuan genial es eso!

Puede usar esto como un tutorial de aprendizaje básico y puede  construir una red neuronal simple usando Python  ahora. Si encuentra que Python es difícil de usar, siempre puede cambiar para estudiar  Programación Java .

Recuerde siempre que el secreto de la codificación es seguir adelante.


Stella Lincoln trabaja actualmente como desarrolladora front-end en Academist Help. Lleva mucho tiempo asesorando a principiantes sobre cómo adentrarse en el mundo de la programación. Además de programación y enseñanza, Stella también tiene su blog en Educator House.

Conviertete en un programador más sociable

Patrocinadores