milvus-logo
LFAI
Home
  • Tutoriais

Recomendação de filmes com o Milvus

Open In Colab GitHub Repository

Neste caderno, vamos explorar como gerar embeddings de descrições de filmes utilizando o OpenAI e aproveitar esses embeddings no Milvus para recomendar filmes que correspondam às suas preferências. Para melhorar os nossos resultados de pesquisa, vamos utilizar a filtragem para efetuar pesquisas de metadados. O conjunto de dados utilizado neste exemplo é proveniente dos conjuntos de dados HuggingFace e contém mais de 8.000 entradas de filmes, fornecendo um conjunto rico de opções para recomendações de filmes.

Dependências e ambiente

Pode instalar as dependências executando o seguinte comando:

$ pip install openai pymilvus datasets tqdm

Se estiver a utilizar o Google Colab, para ativar as dependências acabadas de instalar, poderá ser necessário reiniciar o tempo de execução (clique no menu "Tempo de execução" na parte superior do ecrã e selecione "Reiniciar sessão" no menu pendente).

Neste exemplo, vamos utilizar o OpenAI como LLM. Deve preparar a chave api OPENAI_API_KEY como uma variável de ambiente.

import os

os.environ["OPENAI_API_KEY"] = "sk-***********"

Inicializar o cliente OpenAI e o Milvus

Inicialize o cliente OpenAI.

from openai import OpenAI

openai_client = OpenAI()

Defina o nome e a dimensão da coleção para os embeddings.

COLLECTION_NAME = "movie_search"
DIMENSION = 1536

BATCH_SIZE = 1000

Ligar ao Milvus.

from pymilvus import MilvusClient

# Connect to Milvus Database
client = MilvusClient("./milvus_demo.db")

Tal como para o argumento de url e token:

  • Definir o uri como um ficheiro local, por exemplo./milvus.db, é o método mais conveniente, uma vez que utiliza automaticamente o Milvus Lite para armazenar todos os dados neste ficheiro.
  • Se tiver uma grande escala de dados, digamos mais de um milhão de vectores, pode configurar um servidor Milvus mais eficiente em Docker ou Kubernetes. Nesta configuração, use o endereço e a porta do servidor como seu uri, por exemplo,http://localhost:19530. Se você ativar o recurso de autenticação no Milvus, use "<seu_nome_de_usuário>:<sua_senha>" como o token, caso contrário, não defina o token.
  • Se pretender utilizar o Zilliz Cloud, o serviço de nuvem totalmente gerido para o Milvus, ajuste os campos uri e token, que correspondem ao Public Endpoint e à chave Api no Zilliz Cloud.
# Remove collection if it already exists
if client.has_collection(COLLECTION_NAME):
    client.drop_collection(COLLECTION_NAME)

Defina os campos para a coleção, que incluem o id, o título, o tipo, o ano de lançamento, a classificação e a descrição.

from pymilvus import DataType

# Create collection which includes the id, title, and embedding.

# 1. Create schema
schema = MilvusClient.create_schema(
    auto_id=True,
    enable_dynamic_field=False,
)

# 2. Add fields to schema
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="title", datatype=DataType.VARCHAR, max_length=64000)
schema.add_field(field_name="type", datatype=DataType.VARCHAR, max_length=64000)
schema.add_field(field_name="release_year", datatype=DataType.INT64)
schema.add_field(field_name="rating", datatype=DataType.VARCHAR, max_length=64000)
schema.add_field(field_name="description", datatype=DataType.VARCHAR, max_length=64000)
schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=DIMENSION)

# 3. Create collection with the schema
client.create_collection(collection_name=COLLECTION_NAME, schema=schema)

Crie o índice na coleção e carregue-o.

# Create the index on the collection and load it.

# 1. Prepare index parameters
index_params = client.prepare_index_params()


# 2. Add an index on the embedding field
index_params.add_index(
    field_name="embedding", metric_type="IP", index_type="AUTOINDEX", params={}
)


# 3. Create index
client.create_index(collection_name=COLLECTION_NAME, index_params=index_params)


# 4. Load collection
client.load_collection(collection_name=COLLECTION_NAME, replica_number=1)

Conjunto de dados

Com o Milvus instalado e a funcionar, podemos começar a obter os nossos dados. Hugging Face Datasets é um hub que contém muitos conjuntos de dados de utilizadores diferentes e, para este exemplo, estamos a utilizar o conjunto de dados netflix-shows do HuggingLearners. Esse conjunto de dados contém filmes e seus pares de metadados para mais de 8 mil filmes. Vamos inserir cada descrição e armazená-la no Milvus juntamente com o título, o tipo, o ano de lançamento e a classificação.

from datasets import load_dataset

dataset = load_dataset("hugginglearners/netflix-shows", split="train")

Inserir os dados

Agora que temos os nossos dados na nossa máquina, podemos começar a incorporá-los e a inseri-los no Milvus. A função de embedding recebe texto e devolve os embeddings num formato de lista.

def emb_texts(texts):
    res = openai_client.embeddings.create(input=texts, model="text-embedding-3-small")
    return [res_data.embedding for res_data in res.data]

O próximo passo é a inserção propriamente dita. Percorremos todas as entradas e criamos lotes que inserimos quando atingimos o tamanho definido para o lote. Após o fim do ciclo, inserimos o último lote remanescente, se existir.

from tqdm import tqdm

# batch (data to be inserted) is a list of dictionaries
batch = []

# Embed and insert in batches
for i in tqdm(range(0, len(dataset))):
    batch.append(
        {
            "title": dataset[i]["title"] or "",
            "type": dataset[i]["type"] or "",
            "release_year": dataset[i]["release_year"] or -1,
            "rating": dataset[i]["rating"] or "",
            "description": dataset[i]["description"] or "",
        }
    )

    if len(batch) % BATCH_SIZE == 0 or i == len(dataset) - 1:
        embeddings = emb_texts([item["description"] for item in batch])

        for item, emb in zip(batch, embeddings):
            item["embedding"] = emb

        client.insert(collection_name=COLLECTION_NAME, data=batch)
        batch = []

Consultar a base de dados

Com os nossos dados inseridos em segurança no Milvus, podemos agora efetuar uma consulta. A consulta recebe uma tupla com a descrição do filme que se está a procurar e o filtro a utilizar. Mais informações sobre o filtro podem ser encontradas aqui. A pesquisa imprime primeiro a descrição e a expressão do filtro. Depois, para cada resultado, imprimimos a pontuação, o título, o tipo, o ano de lançamento, a classificação e a descrição dos filmes resultantes.

import textwrap


def query(query, top_k=5):
    text, expr = query

    res = client.search(
        collection_name=COLLECTION_NAME,
        data=emb_texts(text),
        filter=expr,
        limit=top_k,
        output_fields=["title", "type", "release_year", "rating", "description"],
        search_params={
            "metric_type": "IP",
            "params": {},
        },
    )

    print("Description:", text, "Expression:", expr)

    for hit_group in res:
        print("Results:")
        for rank, hit in enumerate(hit_group, start=1):
            entity = hit["entity"]

            print(
                f"\tRank: {rank} Score: {hit['distance']:} Title: {entity.get('title', '')}"
            )
            print(
                f"\t\tType: {entity.get('type', '')} "
                f"Release Year: {entity.get('release_year', '')} "
                f"Rating: {entity.get('rating', '')}"
            )
            description = entity.get("description", "")
            print(textwrap.fill(description, width=88))
            print()


my_query = ("movie about a fluffly animal", 'release_year < 2019 and rating like "PG%"')

query(my_query)
Description: movie about a fluffly animal Expression: release_year < 2019 and rating like "PG%"
Results:
    Rank: 1 Score: 0.42213767766952515 Title: The Adventures of Tintin
        Type: Movie Release Year: 2011 Rating: PG
This 3-D motion capture adapts Georges Remi's classic comic strip about the adventures
of fearless young journalist Tintin and his trusty dog, Snowy.

    Rank: 2 Score: 0.4041026830673218 Title: Hedgehogs
        Type: Movie Release Year: 2016 Rating: PG
When a hedgehog suffering from memory loss forgets his identity, he ends up on a big
city journey with a pigeon to save his habitat from a human threat.

    Rank: 3 Score: 0.3980264663696289 Title: Osmosis Jones
        Type: Movie Release Year: 2001 Rating: PG
Peter and Bobby Farrelly outdo themselves with this partially animated tale about an
out-of-shape 40-year-old man who's the host to various organisms.

    Rank: 4 Score: 0.39479154348373413 Title: The Lamb
        Type: Movie Release Year: 2017 Rating: PG
A big-dreaming donkey escapes his menial existence and befriends some free-spirited
animal pals in this imaginative retelling of the Nativity Story.

    Rank: 5 Score: 0.39370301365852356 Title: Open Season 2
        Type: Movie Release Year: 2008 Rating: PG
Elliot the buck and his forest-dwelling cohorts must rescue their dachshund pal from
some spoiled pets bent on returning him to domesticity.

Traduzido porDeepL

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Esta página foi útil?