Los sistemas de recomendación (motores de recomendación) son un tipo de aplicación que predice e impulsa elementos (servicios) que los usuarios necesitan actualmente o en los que están interesados en función de información como el comportamiento del usuario y los puntos de interés. Los sistemas de recomendación comunes incluyen sistemas de recomendación de películas, libros, música o artículos de noticias.
Basados en diferentes algoritmos o tecnologías, existen muchos tipos de sistemas de recomendación, como sistemas de recomendación de filtrado colaborativo, sistemas de recomendación basados en contenido, sistemas de recomendación híbridos y sistemas de recomendación basados en vectores. Entre ellos, los sistemas de recomendación basados en vectores utilizan el espacio vectorial para encontrar (es decir, recomendar) los productos o contenidos más similares en la base de datos. La forma más eficaz de almacenar datos vectoriales es utilizar la base de datos de vectores líder en el mundo como Milvus.
Este artículo presentará cómo utilizar Milvus y Python para crear un sistema de recomendación de películas. Durante el proceso de construcción, usaremos SentenceTransformers para convertir información de texto en vectores y almacenar estos vectores en Milvus. Una vez configurado, los usuarios pueden ingresar una descripción y buscar películas similares en el sistema de recomendación. Para ver todo el código de este tutorial, consulte:
Repositorio de Milvus Bootcamp en GitHub (https://github.com/milvus-io/bootcamp)
Cuaderno Jupyter (https://github.com/milvus-io/bootcamp/blob/master/solutions/nlp/recommender_system/recommender_system.ipynb)
01.
Configurar el entorno
Antes de comenzar, instale:
Pitón 3.x
Administrador de paquetes de Python (PIP)
Cuaderno Jupyter
Estibador
Sistema de hardware con al menos 32 GB de RAM o cuenta Zilliz Cloud
Instale las herramientas y el software necesarios utilizando Python
$ python -m pip install pymilvus pandas sentence_transformers kaggle
Base de datos vectorial Milvus
En este tutorial usaremos Milvus para almacenar el vector de incrustación convertido a partir de la información de la película. Dado que el conjunto de datos utilizado es grande, se recomienda crear un clúster de Zilliz Cloud (https://cloud.zilliz.com.cn/signup) para almacenar la base de datos vectorial. Pero si aún desea instalar una instancia local, puede descargar el archivo de configuración de Docker-Compose y ejecutarlo.
$ wget https://github.com/milvus-io/milvus/releases/download/v2.3.0/milvus-standalone-docker-compose.yml -O docker-compose.yml
$ docker-compose up -d
Una vez que todo esté listo, ¡puedes crear un sistema de recomendación de películas!
02.
Preparar y preprocesar datos
Primero, elegimos utilizar el conjunto de datos de películas (https://www.kaggle.com/datasets/rounakbanik/the-movies-dataset) en Kaggle Puede descargar el conjunto de datos directamente o utilizar la API de Kaggle a través de Python para descargar el conjunto de datos. Si desea descargar a través de Python, primero descargue el archivo kaggle.json en el perfil de Kaggle.com (https://www.kaggle.com/docs/api). ¡Aviso! Asegúrese de almacenar este archivo en una ruta a la que pueda acceder la API.
A continuación, configure las variables de entorno para autenticarse en Kaggle. Abra Jupyter Notebook e ingrese el siguiente código:
%env KAGGLE_USERNAME=username
%env KAGGLE_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
%env TOKENIZERS_PARALLELISM=true
Utilice la dependencia Python de Kaggle para descargar el conjunto de datos de la película en Kaggle:
import kaggle dependency
import kaggle
kaggle.api.authenticate()
kaggle.api.dataset_download_files('rounakbanik/the-movies-dataset', path='dataset', unzip=True)
Una vez descargado el conjunto de datos, utilice pandas read_csv()
para leer el conjunto de datos:
import pandas
import pandas as pd
read csv data
movies=pd.read_csv('dataset/movies_metadata.csv',low_memory=False)
check shapeof data
movies.shape
La figura anterior muestra que se leyeron 45466 piezas de metadatos de películas. Cada dato de la película contiene 24 columnas. Utilice el siguiente comando para ver información de todas las columnas:
check column names
movies.columns
Al crear un sistema de recomendación de películas, no es necesario utilizar todas las columnas. Filtra las columnas que necesitamos con el siguiente código:
filter required columnstrimmed_movies = movies[["id", "title", "overview", "release_date", "genres"]]
trimmed_movies.head(5)
Además, faltan algunos campos en algunos datos. Elimine los datos de estos campos que faltan:
unclean_movies_dict = trimmed_movies.to_dict('records')
print('{} movies'.format(len(unclean_movies_dict)))
movies_dict = []for movie in unclean_movies_dict:if movie["overview"] == movie["overview"] and movie["release_date"] == movie["release_date"] and movie["genres"] == movie["genres"] and movie["title"] == movie["title"]:
movies_dict.append(movie)
03.
Proceso de construcción
Conéctate con Milvus
Después de procesar los datos, conéctese al clúster Milvus para importar los datos. Necesitamos usar URI y token para conectarnos al clúster Milvus; esta información se puede encontrar en la interfaz de Zilliz Cloud.
Utilice el siguiente comando para conectarse al servidor Milvus a través de PyMilvus (https://pypi.org/project/pymilvus/):
import milvus dependencyfrom pymilvus import *
connect to milvusmilvus_uri="YOUR_URI"token="YOUR_API_TOKEN"
connections.connect("default", uri=milvus_uri, token=token)
print("Connected!")
Convertir información de película en vectores de incrustación
A continuación, convierta el conjunto de datos de la película en vectores de incrustación. Primero, cree una colección para almacenar ID de películas y vectores de información de películas. También se pueden agregar índices al crear una Colección para hacer que las búsquedas posteriores sean más eficientes:
COLLECTION_NAME = 'film_vectors'
PARTITION_NAME = 'Movie'Here's our record schema"""
"title": Film title,
"overview": description,
"release_date": film release date,
"genres": film generes,
"embedding": embedding
"""
id = FieldSchema(name='title', dtype=DataType.VARCHAR, max_length=500, is_primary=True)
field = FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, dim=384)
schema = CollectionSchema(fields=[id, field], description="movie recommender: film vectors", enable_dynamic_field=True)
if utility.has_collection(COLLECTION_NAME): # drop the same collection created before
collection = Collection(COLLECTION_NAME)
collection.drop()
collection = Collection(name=COLLECTION_NAME, schema=schema)
print("Collection created.")
index_params = {"index_type": "IVF_FLAT","metric_type": "L2","params": {"nlist": 128},
}
collection.create_index(field_name="embedding", index_params=index_params)
collection.load()
print("Collection indexed!")
Una vez creada la Colección, debe escribir una función para generar vectores. El vector de la película contendrá información como la introducción de la película, el tipo de película, la fecha de lanzamiento, etc. Utilice SentenceTransformer para generar vectores:
from sentence_transformers import SentenceTransformer
import ast
function to extract the text from genre columndef build_genres(data):
genres = data['genres']
genre_list = ""
entries= ast.literal_eval(genres)
genres = ""for entry in entries:
genre_list = genre_list + entry["name"] + ", "
genres += genre_list
genres = "".join(genres.rsplit(",", 1))return genres
create an object of SentenceTransformer
transformer = SentenceTransformer('all-MiniLM-L6-v2')
function to generate embeddingsdef embed_movie(data):
embed = "{} Released on {}. Genres are {}.".format(data["overview"], data["release_date"], build_genres(data)) embeddings = transformer.encode(embed)return embeddings
La función anterior utiliza build_genres()
un estilo de película claro y extrae texto. Luego se crea un objeto SentenceTransformer para generar vectores de texto. Finalmente, encode()
el vector de película se genera utilizando el método.
Importar vectores a Milvus
Debido a que el conjunto de datos es demasiado grande, insertar datos en Milvus uno por uno es ineficiente y resultará en un aumento del tráfico de la red. Por lo tanto, recomendamos importar datos a Milvus en lotes, con 5000 datos importados en un lote.
Loop counter for batching and showing progressj = 0batch = []
for movie_dict in movies_dict:
try:
movie_dict["embedding"] = embed_movie(movie_dict)batch.append(movie_dict)
j += 1
if j % 5 == 0:
print("Embedded {} records".format(j))
collection.insert(batch)
print("Batch insert completed")batch=[]
except Exception as e:
print("Error inserting record {}".format(e))
pprint(batch)
break
collection.insert(movie_dict)
print("Final batch completed")
print("Finished with {} embeddings".format(j))
Nota: Puede ajustar la cantidad de datos cargados en lotes según sus preferencias y necesidades. Al mismo tiempo, es posible que algunas películas no se puedan importar porque sus ID no se pueden convertir a números enteros. Podemos ajustar el esquema en consecuencia o verificar el formato de los datos para evitar fallas en la importación .
04.
Busca y recomienda películas con Milvus
Para utilizar las capacidades de búsqueda vectorial casi en tiempo real de Milvus para recomendar películas adecuadas a los usuarios, cree las dos funciones siguientes:
embed_search()
Utilice Transformer para convertir el texto de búsqueda del usuario (cadena) en un vector de incrustación. Transformer es el mismo que antes.search_for_movies()
Se utiliza para realizar búsquedas de similitud de vectores.
load collection memory before search
collection.load()
Set search parameters
topK = 5
SEARCH_PARAM = {
"metric_type":"L2",
"params":{"nprobe": 20},
}
convertsearch string to embeddings
def embed_search(search_string):
search_embeddings = transformer.encode(search_string)return search_embeddings
search similar embeddings for user's query
def search_for_movies(search_string):
user_vector = embed_search(search_string)
return collection.search([user_vector],"embedding",param=SEARCH_PARAM, limit=topK, expr=None, output_fields=['title', 'overview'])
En el código anterior, configuramos los siguientes parámetros:
Top-K :
topK = 5
, estipula que la búsqueda devolverá los 5 vectores más similaresTipo de similitud :
metric_type
establecido en distancia euclidiana (Euclidean/L2) https://iq.opengenus.org/euclidean-distance/nprobe : establecido en 20, especificando la búsqueda de 20 grupos de datos
Finalmente, utilice search_for_movies()
la función para recomendar películas relacionadas según las búsquedas de los usuarios:
from pprint import pprint
search_string = "A comedy from the 1990s set in a hospital. The main characters are in their 20s and are trying to stop a vampire."
results = search_for_movies(search_string)
check resultsfor hits in iter(results):for hit in hits:print(hit.entity.get('title'))print(hit.entity.get('overview'))print("-------------------------------")
La imagen de arriba muestra que se encontraron 5 películas similares. Hasta ahora, hemos creado con éxito un sistema de recomendación de películas utilizando Milvus.
Este artículo se publicó originalmente en The New Stack y se ha reproducido con autorización.
本文分享自微信公众号 - ZILLIZ(Zilliztech)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。