¡Serie práctica! Cree un sistema de recomendación de películas usando Milvus y Python


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 similares

  • Tipo de similitud : metric_typeestablecido 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.


Lectura recomendada



本文分享自微信公众号 - ZILLIZ(Zilliztech)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

商汤科技创始人汤晓鸥离世,享年 55 岁 2023 年,PHP 停滞不前 鸿蒙系统即将走向独立,多家高校设立“鸿蒙班” 夸克浏览器 PC 版开启内测 字节跳动被 OpenAI “封号”事件始末 稚晖君创业公司再融资,金额超 6 亿元,投前估值 35 亿元 AI 代码助手盛行,编程语言排行榜都没法做了 Mate 60 Pro 的 5G 调制解调器和射频技术遥遥领先 No Star, No Fix MariaDB 拆分 SkySQL,作为独立公司成立
{{o.name}}
{{m.name}}

Supongo que te gusta

Origin my.oschina.net/u/4209276/blog/10320773
Recomendado
Clasificación