Crea un motore di raccomandazione di film con Milvus e Python
Questo articolo è stato originariamente pubblicato su The New Stack e viene ripubblicato qui con autorizzazione.
Usa strumenti open source per aiutare le persone a trovare film che potrebbero essere interessate a guardare.
I sistemi di raccomandazione o motori di raccomandazione sono sistemi di filtraggio delle informazioni che mirano a prevedere e suggerire cose a cui gli utenti potrebbero essere interessati. Questi elementi includono prodotti, servizi e contenuti come film, libri, musica o articoli di notizie.
Esistono vari tipi di sistemi di raccomandazione, come il filtraggio collaborativo, il filtraggio basato sul contenuto, i sistemi di raccomandazione ibridi e i sistemi di raccomandazione basati su vettori. I sistemi basati su vettori usano lo spazio vettoriale per trovare (raccomandare) gli elementi più vicini nel database. Esistono vari modi per archiviare questi vettori; uno dei più efficienti è l'uso del database vettoriale open source Milvus. Questo database è altamente flessibile, veloce e affidabile e consente l'aggiunta, l'eliminazione, l'aggiornamento e la ricerca quasi in tempo reale di vettori su scala di trilioni di byte.
Questo articolo spiega come creare un motore di raccomandazione di film con Milvus e Python. Questo sistema userà SentenceTransformers per convertire le informazioni testuali in vettori e archiviare questi vettori in Milvus. Milvus consente agli utenti di cercare un film nel database in base alle informazioni testuali che forniscono.
Immagine in evidenza di Tima Miroshnichenko su Pexels
Configurazione dell'ambiente
Per questo articolo, dovrai avere installati i seguenti requisiti:
Python Package Manager (PIP) per installare pacchetti
Jupyter Notebook per scrivere codice
Un sistema con almeno 32GB di RAM o un account Zilliz Cloud
Requisiti Python
Devi anche installare un insieme di librerie che saranno necessarie durante questo tutorial. Installa le librerie usando PIP:
$ python -m pip install pymilvus pandas sentence_transformers kaggle
Archivio dati vettoriali (Milvus)
Userai il database vettoriale Milvus per archiviare gli embedding che genererai usando le descrizioni dei film. Il dataset è relativamente grande, almeno per un server in esecuzione su un personal computer. Quindi potresti voler usare un'istanza Zilliz Cloud per archiviare questi vettori.
Se preferisci rimanere con un'istanza locale, puoi scaricare una configurazione docker-compose ed eseguirla con:
$ 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
Ora hai tutti i requisiti per creare il tuo sistema di raccomandazione di film con Milvus.
Raccolta e preelaborazione dei dati
Per questo progetto, userai il Movies Dataset di Kaggle che contiene metadati per 45.000 film. Puoi scaricare questo dataset direttamente oppure usare l'API di Kaggle per scaricare il dataset usando Python. Per farlo con Python, devi scaricare il file kaggle.json dalla sezione del profilo di Kaggle.com e metterlo in una posizione in cui l'API lo troverà.
Successivamente, configura alcune variabili d'ambiente per l'autenticazione Kaggle. Per questo, puoi aprire il Jupyter Notebook e scrivere le seguenti righe di codice:
%env KAGGLE_USERNAME=username
%env KAGGLE_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
%env TOKENIZERS_PARALLELISM=true
Una volta fatto, puoi usare la dipendenza Python di Kaggle per scaricare il dataset da Kaggle:
# import kaggle dependency
import kaggle
kaggle.api.authenticate()
kaggle.api.dataset_download_files('rounakbanik/the-movies-dataset', path='dataset', unzip=True)
Una volta scaricato il dataset, puoi usare il metodo read_csv() di pandas per leggere il dataset:
# 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
Forma del dataset
L'immagine mostra che hai 45.466 record con 24 colonne di metadati. Controlla tutte queste colonne di metadati con:
# check column names
movies.columns
Colonne del dataset
Ci sono molte colonne di cui non hai bisogno per creare il sistema di raccomandazione. Puoi filtrare le colonne richieste con:
# filter required columns
trimmed_movies = movies[["id", "title", "overview", "release_date", "genres"]]
trimmed_movies.head(5)
Colonne richieste
Inoltre, alcuni campi nei dati sono mancanti, quindi elimina quelle righe per produrre un dataset pulito:
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)
Connettersi a Milvus
Ora che hai tutte le colonne richieste, connettiti a Milvus per iniziare a caricare i dati. Per connetterti all'istanza cloud di Milvus, avrai bisogno dell'Uniform Resource Identifier (URI) e del token, che puoi scaricare dalla tua dashboard di Zilliz Cloud.
Dashboard Zilliz
Una volta ottenuti il tuo URI e la tua chiave API, puoi usare il metodo connect() di PyMilvus per connetterti al server 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!")
Generare embeddings per i film
Ora è il momento di calcolare gli embeddings per i dati testuali nel dataset dei film. Per prima cosa, crea un oggetto collection che memorizzerà l'ID del film e gli embeddings per i dati testuali. Crea anche un campo index per rendere le ricerche più efficienti:
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!")
Ora che hai una raccolta indicizzata, crea una funzione per generare gli embedding per il testo. Sebbene overview sia la colonna principale utilizzata per generare gli embedding, userai anche le informazioni di genre e release data insieme a un overview per rendere i dati più logici.
Per generare gli embedding, usa 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
Questa funzione usa il metodo build_genres() per pulire la colonna del genere ed estrarne il testo. Poi crea un oggetto SentenceTransformer per aiutare a generare gli embedding dal testo. Infine, usa il metodo encode() per generare gli embedding utilizzando le funzionalità overview, release_date e genre.
Inviare gli embedding a Milvus
Ora puoi creare gli embedding usando il metodo embed_movie(). Questo dataset è troppo grande per essere inviato a Milvus in una singola istruzione insert, ma inviare le righe di dati una alla volta creerebbe traffico di rete non necessario e richiederebbe troppo tempo. Quindi, crea invece batch (ad esempio, 5.000 righe) di dati da inviare a 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))
Nota: Puoi sperimentare con la dimensione del batch per adattarla alle tue esigenze e preferenze individuali. Inoltre, alcuni film falliranno per ID che non possono essere convertiti in interi. Potresti risolvere questo problema con una modifica dello schema o verificandone il formato.
Invia Embedding a Milvus
Consigliare nuovi film usando Milvus
Ora puoi sfruttare la funzionalità di ricerca vettoriale quasi in tempo reale di Milvus per ottenere una corrispondenza stretta di film che soddisfano i criteri dello spettatore. Per farlo, crea due funzioni diverse:
embed_search(): Hai bisogno di un transformer per convertire la stringa di ricerca dell'utente in un embedding. Questa funzione prende i criteri dello spettatore e li passa allo stesso transformer che hai usato per popolare Milvus.
search_for_movies(): Questa funzione esegue la ricerca vettoriale effettiva usando l'altra funzione come supporto.
# 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'])
Il codice sopra definisce i parametri topK per ottenere i primi cinque vettori simili, metric_type come L2 (euclidea quadratica) che calcola la distanza tra due vettori e nprobe che indica il numero di unità di cluster da cercare. Implementa anche diverse funzioni per ottenere vettori simili dalla query dell'utente (raccomandazione).
Infine, usa la funzione search_for_movies() per consigliare film in base alla stringa di ricerca dell'utente:
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("-------------------------------")
Consiglia film
Utilizzando la funzionalità di ricerca vettoriale di Milvus, il codice consiglia i primi cinque film simili in base alla query dell'utente. Ecco fatto: ora hai creato il tuo sistema di raccomandazione di film utilizzando Milvus.
Conclusione
Dopo aver letto questo articolo, sai cos'è un sistema di raccomandazione basato su vettori e come creare un sistema di raccomandazione di film con Milvus. Milvus aiuta a creare un sistema di raccomandazione di film efficiente e scalabile. Sfruttando l'archiviazione vettoriale e la ricerca di similarità, Milvus ha un grande potenziale per abilitare raccomandazioni personalizzate, migliorare il coinvolgimento degli utenti e mostrare il ruolo dei modelli avanzati basati su vettori nei moderni sistemi di raccomandazione. Puoi saperne di più sul sito web di Milvus.
Continua a leggere

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.

AI Agents Are Quietly Transforming E-Commerce — Here’s How
Discover how AI agents transform e-commerce with autonomous decision-making, enhanced product discovery, and vector search capabilities for today's retailers.

Vector Databases vs. Hierarchical Databases
Use a vector database for AI-powered similarity search; use a hierarchical database for organizing data in parent-child relationships with efficient top-down access patterns.



