Créer un moteur de recommandation de films avec Milvus et Python
Cet article a été initialement publié dans The New Stack et est republié ici avec autorisation.
Utilisez des outils open source pour aider les gens à trouver des films qu’ils pourraient avoir envie de regarder.
Les systèmes de recommandation ou moteurs de recommandation sont des systèmes de filtrage d’informations qui visent à prédire et à suggérer des choses susceptibles d’intéresser les utilisateurs. Ces éléments incluent des produits, des services et des contenus tels que des films, des livres, de la musique ou des articles d’actualité.
Il existe différents types de systèmes de recommandation, tels que le filtrage collaboratif, le filtrage basé sur le contenu, les systèmes de recommandation hybrides et les systèmes de recommandation basés sur les vecteurs. Les systèmes basés sur les vecteurs utilisent l’espace vectoriel pour trouver (recommander) les éléments les plus proches dans la base de données. Il existe différentes façons de stocker ces vecteurs ; l’une des plus efficaces consiste à utiliser la base de données vectorielle open source Milvus. Cette base de données est très flexible, rapide et fiable, et permet l’ajout, la suppression, la mise à jour et la recherche de vecteurs à une échelle de plusieurs billions d’octets, presque en temps réel.
Cet article explique comment créer un système de recommandation de films avec Milvus et Python. Ce système utilisera SentenceTransformers pour convertir les informations textuelles en vecteurs et stocker ces vecteurs dans Milvus. Milvus permet aux utilisateurs de rechercher un film dans la base de données à partir des informations textuelles qu’ils fournissent.
Image à la une par Tima Miroshnichenko sur Pexels
Configuration de l’environnement
Pour cet article, vous aurez besoin des éléments suivants installés :
Python Package Manager (PIP) pour installer des packages
Jupyter Notebook pour écrire du code
Un système avec au moins 32 Go de RAM ou un compte Zilliz Cloud
Prérequis Python
Vous devez également installer un ensemble de bibliothèques qui seront nécessaires tout au long de ce tutoriel. Installez les bibliothèques à l’aide de PIP :
$ python -m pip install pymilvus pandas sentence_transformers kaggle
Magasin de données vectorielles (Milvus)
Vous utiliserez la base de données vectorielle Milvus pour stocker les embeddings que vous générerez à partir des descriptions de films. Le jeu de données est relativement volumineux, du moins pour un serveur exécuté sur un ordinateur personnel. Vous pouvez donc vouloir utiliser une instance Zilliz Cloud pour stocker ces vecteurs.
Si vous préférez rester avec une instance locale, vous pouvez télécharger une configuration docker-compose et l’exécuter avec :
$ 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
Vous disposez maintenant de tous les prérequis pour créer votre propre système de recommandation de films avec Milvus.
Collecte et prétraitement des données
Pour ce projet, vous utiliserez le Movies Dataset de Kaggle qui contient des métadonnées pour 45 000 films. Vous pouvez télécharger ce jeu de données directement ou utiliser l’API Kaggle pour télécharger le jeu de données avec Python. Pour le faire avec Python, vous devez télécharger le fichier kaggle.json depuis la section profil de Kaggle.com et le placer à un emplacement où l’API le trouvera.
Ensuite, configurez quelques variables d’environnement pour l’authentification Kaggle. Pour cela, vous pouvez ouvrir le Jupyter Notebook et écrire les lignes de code suivantes :
%env KAGGLE_USERNAME=username
%env KAGGLE_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
%env TOKENIZERS_PARALLELISM=true
Une fois cela fait, vous pouvez utiliser la dépendance Python de Kaggle pour télécharger le jeu de données depuis Kaggle :
# import kaggle dependency
import kaggle
kaggle.api.authenticate()
kaggle.api.dataset_download_files('rounakbanik/the-movies-dataset', path='dataset', unzip=True)
Une fois le jeu de données téléchargé, vous pouvez utiliser la méthode read_csv() de pandas pour lire le jeu de données :
# import pandas
import pandas as pd
# read csv data
movies=pd.read_csv('dataset/movies_metadata.csv',low_memory=False)
# check shape of data
movies.shape
Forme du jeu de données
L’image montre que vous avez 45 466 enregistrements avec 24 colonnes de métadonnées. Vérifiez toutes ces colonnes de métadonnées avec :
# check column names
movies.columns
Colonnes du jeu de données
Il y a beaucoup de colonnes dont vous n’avez pas besoin pour créer le système de recommandation. Vous pouvez filtrer les colonnes requises avec :
# filter required columns
trimmed_movies = movies[["id", "title", "overview", "release_date", "genres"]]
trimmed_movies.head(5)
Colonnes requises
De plus, certains champs dans les données sont manquants, donc supprimez ces lignes afin de produire un jeu de données propre :
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)
Se connecter à Milvus
Maintenant que vous avez toutes les colonnes requises, connectez-vous à Milvus pour commencer à téléverser les données. Pour vous connecter à l’instance cloud Milvus, vous aurez besoin de l’Uniform Resource Identifier (URI) et du jeton, que vous pouvez télécharger depuis votre tableau de bord Zilliz Cloud.
Tableau de bord Zilliz
Une fois que vous avez votre URI et votre clé API, vous pouvez utiliser la méthode connect() de PyMilvus pour vous connecter au serveur Milvus :
# import milvus dependency
from pymilvus import *
# connect to milvus
milvus_uri="YOUR_URI"
token="YOUR_API_TOKEN"
connections.connect("default", uri=milvus_uri, token=token)
print("Connected!")
Générer des embeddings pour les films
Il est maintenant temps de calculer les embeddings pour les données textuelles du jeu de données de films. Tout d’abord, créez un objet collection qui stockera l’ID du film et les embeddings pour les données textuelles. Créez également un champ index pour rendre les recherches plus efficaces :
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!")
Maintenant que vous disposez d’une collection indexée, créez une fonction pour générer les embeddings du texte. Bien que overview soit la colonne principale utilisée pour générer les embeddings, vous utiliserez également les informations genre et release data avec un overview afin de rendre les données plus logiques.
Pour générer les embeddings, utilisez le SentenceTransformer :
from sentence_transformers import SentenceTransformer
import ast
# function to extract the text from genre column
def 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 embeddings
def embed_movie(data):
embed = "{} Released on {}. Genres are {}.".format(data["overview"], data["release_date"], build_genres(data))
embeddings = transformer.encode(embed)
return embeddings
Cette fonction utilise la méthode build_genres() pour nettoyer la colonne genre et en extraire le texte. Elle crée ensuite un objet SentenceTransformer pour aider à générer les embeddings à partir du texte. Enfin, elle utilise la méthode encode() pour générer les embeddings à l’aide des fonctionnalités overview, release_date et genre.
Envoyer les embeddings à Milvus
Vous pouvez maintenant créer les embeddings à l’aide de la méthode embed_movie(). Ce jeu de données est trop volumineux pour être envoyé à Milvus dans une seule instruction insert, mais envoyer les lignes de données une par une créerait un trafic réseau inutile et prendrait trop de temps. Créez donc plutôt des lots (par exemple, 5 000 lignes) de données à envoyer à Milvus :
# Loop counter for batching and showing progress
j = 0
batch = []
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))
Remarque : Vous pouvez modifier la taille des lots selon vos besoins et préférences. De plus, quelques films échoueront pour des ID qui ne peuvent pas être convertis en entiers. Vous pourriez corriger cela en modifiant le schéma ou en vérifiant leur format.
Envoyer les embeddings à Milvus
Recommander de nouveaux films avec Milvus
Vous pouvez maintenant tirer parti de la fonctionnalité de recherche vectorielle quasi en temps réel de Milvus pour obtenir une correspondance proche avec les films qui répondent aux critères du spectateur. Pour cela, créez deux fonctions différentes :
embed_search() : Vous avez besoin d’un transformer pour convertir la chaîne de recherche de l’utilisateur en embedding. Cette fonction prend les critères du spectateur et les transmet au même transformer que celui que vous avez utilisé pour alimenter Milvus.
search_for_movies() : Cette fonction effectue la recherche vectorielle réelle en utilisant l’autre fonction comme support.
# load collection memory before search
collection.load()
# Set search parameters
topK = 5
SEARCH_PARAM = {
"metric_type":"L2",
"params":{"nprobe": 20},
}
# convert search 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'])
Le code ci-dessus définit les paramètres topK pour obtenir les cinq premiers vecteurs similaires, metric_type comme L2 (euclidienne au carré) qui calcule la distance entre deux vecteurs et nprobe qui indique le nombre d’unités de cluster à rechercher. Il implémente également différentes fonctions pour obtenir des vecteurs similaires à partir de la requête de l’utilisateur (recommandation).
Enfin, utilisez la fonction search_for_movies() pour recommander des films en fonction de la chaîne de recherche de l’utilisateur :
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 results
for hits in iter(results):
for hit in hits:
print(hit.entity.get('title'))
print(hit.entity.get('overview'))
print("-------------------------------")
Recommander des films
En utilisant la fonctionnalité de recherche vectorielle de Milvus, le code recommande les cinq films les plus similaires en fonction de la requête de l’utilisateur. Voilà : vous avez maintenant construit votre propre système de recommandation de films avec Milvus.
Conclusion
Après avoir lu cet article, vous savez ce qu’est un système de recommandation basé sur des vecteurs et comment créer un système de recommandation de films avec Milvus. Milvus aide à construire un système de recommandation de films efficace et évolutif. En tirant parti du stockage vectoriel et de la recherche de similarité, Milvus présente un grand potentiel pour permettre des recommandations personnalisées, renforcer l’engagement des utilisateurs et mettre en évidence le rôle des modèles avancés basés sur des vecteurs dans les systèmes de recommandation modernes. Vous pouvez en apprendre davantage sur le site web de Milvus.
Continuer à lire

How Zilliz Ended Up at the Center of NVIDIA’s Unstructured Data Story at GTC 2026
If unstructured data is the context of AI, then the ceiling of AI applications will be set not just by models, but by how mature the infrastructure for unstructured data becomes.

Announcing the General Availability of Single Sign-On (SSO) on Zilliz Cloud
SSO is GA on Zilliz Cloud, delivering the enterprise-grade identity management capabilities your teams need to deploy vectorDB with confidence.

Build for the Boom: Why AI Agent Startups Should Build Scalable Infrastructure Early
Explore strategies for developing AI agents that can handle rapid growth. Don't let inadequate systems undermine your success during critical breakthrough moments.



