Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
MongoDBchevron-right

Confissões de um PyMongoArrowholic: usando Atlas Vector Search e PyMongoArrow para pesquisar semanticamente itens de moda de luxo

Anaiya Raisinghani9 min read • Published Aug 09, 2024 • Updated Aug 09, 2024
IAPandasPythonMongoDB
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Como um jovem de vinte e poucos anos que mora na cidade de Nova York, as compras online são meu segundo hobby favorito. Qual é o meu primeiro, você pergunta? Descobrir maneiras de otimizar meu vício em compras para que eu possa passar menos horas rolando.
Qualquer pessoa que fantasie com luxo (isso se chama manifestação, pessoal!) conhece o Net-A-Porter e todas as peças incríveis que o site oferece. Embora minha abordagem normal seja classificar por preço, do mais baixo ao mais alto, eu estaria mentindo se dissesse que não é incrivelmente divertido ver o escopo completo do que existe por aí. Então, vamos usar um conjunto de dados divertido que contém os itens da última temporada do Net-A-Porter e fazer uma busca semântica para explorar alguns dos itens mais caros, de qualquer marca, qualquer categoria e com consultas em linguagem natural.
Neste tutorial, usaremos o MongoDB Atlas, a bibliotecaPyMongoArrow , o MongoDB Atlas Vector Search e um conjunto de dados de moda de privilégio do Kaggle.
Antes de começarmos, vamos abordar alguns dos aspectos importantes que nos ajudarão a alcançar nosso resultado geral.

O que é PyMongoArrow?

PyMongoArrow é uma biblioteca Python para análise de dados com MongoDB. Como nosso conjunto de dados é um arquivo.csv, vamos lê-lo usando a biblioteca Pandas, então ele será lido como um dataframe Pandas. Com a bibliotecapymongoarrow, podemos exportar todos os nossos dados para o MongoDB Atlas no formato mais ideal para o nosso tutorial com algumas etapas fáceis. Ele é baseado no pymongo, então nos permite trabalhar com dados do MongoDB de uma maneira superfácil e de alto desempenho. Ao trabalhar neste tutorial, você verá como é simples transferir seus dados e configurá-los ao usar a bibliotecapymongoarrow, um problema com o qual muitos desenvolvedores de dados lidaram no passado.

O que é o Atlas Vector Search do MongoDB?

O MongoDB Atlas Vector Search realmente revolveu os recursos de pesquisa do Atlas. Ele permite que você Atlas Search semanticamente através do seu banco de dados facilmente, mantendo suas incorporações vetoriais no mesmo local que seus dados de origem. Pesquisar semanticamente significa Atlas Search por significado, portanto, em vez de usar palavras-chave exatas, podemos consultar e receber resultados que transmitem a mesma ideia sem palavras precisas.
Por exemplo, em vez de pesquisar o tamanho da amostra usando query simples como "dress, ", podemos usar frases ou generalidades, como "summer beach tropical " ou apenas "summer. ". Vamos utilizar o $vectorSearch estágio de agregação neste tutorial, que simplifica ainda mais o uso do Atlas Vector Search.
Vamos começar!

Pré-requisitos

  1. IDE de sua escolha — este tutorial usa o Google CoLab. Sinta-se à vontade para executar os comandos diretamente no bloco de anotações.
  2. Uma conta do MongoDB Atlas conta
  3. Um cluster MongoDB Atlas — a camada grátis funciona perfeitamente para este tutorial.
  4. Conjunto de dados do Kaggle — verifique se você está baixando o .csv arquivo correto .
  5. Uma chave de API OpenAI - é assim que vamos incorporar nossos dados antes de carregá-los no MongoDB Atlas.
Depois que seu cluster for criado e você tiver baixado o conjunto de dados localmente, você estará pronto para começar!

Carregue nosso arquivo .csv arquivo

Nosso primeiro passo é fazer upload do nosso arquivo.csv no Google Colab. No lado esquerdo do Google Colab, acesse a seção “Arquivos”. Selecione o arquivonet-a-porter.csvbaixado e faça upload. Arquivo carregado no Google CoLab
Depois que seu arquivo for carregado, precisamos fazer duas coisas importantes:
  1. Precisamos usar o OpenAI para criar incorporações em cada item em nosso arquivo.
  2. Precisamos limpar nosso conjunto de dados e reconfigurá-lo em um formato mais adequado ao nosso objetivo final, que é garantir que possamos usar a pesquisa semântica para encontrar itens em nosso banco de dados.

Configurar OpenAI

Se você dar uma olhada no seu arquivo.csv, notará que ele consiste em quatro colunas (marca, descrição, preço_usd, tipo) e uma variedade de linhas. Nosso arquivo .csv arquivo
Precisamos adicionar uma coluna em nosso dataframe que contenha as incorporações para nossas descrições de itens. Para incorporar cada descrição de item, usaremos o modelode incorporação "text-embedding-3-small" e esta função de incorporação:
1def get_embedding(text):
2 embedding = openai.embeddings.create(input=text, model=EMBEDDING_MODEL).data[0].embedding
3 return embedding
Também precisamos usar a bibliotecapandas para trabalhar com os dados que temos disponíveis. Pandas é uma biblioteca Python usada para trabalhar com conjuntos de dados e é superchave ao analisar, limpar, explorar e manipular dados.
Para começar, queremos instalar nossas dependências. Isso significa instalar openai e importar pandas.
1!pip install openai
2import pandas as pd
3import openai
Agora, precisamos pegar nossa chave secreta OpenAI. Certifique-se de salvar sua chave em algum lugar seguro e não a compartilhe em nenhum lugar, pois ela é muito sensível. Neste tutorial, para manter as coisas simples e demonstrar outras funcionalidades disponíveis, estamos codificando em nossa chave de API, mas na produção ou em qualquer outro lugar, é importante armazenar seus valores sensíveis em um arquivo.env.
Copie sua chave e a função de incorporação de cima:
1# we need our openai secret key
2openai.api_key = 'OPENAI-APIKEY'
3
4
5# we are going to use this embedding model for text
6EMBEDDING_MODEL = "text-embedding-3-small"
7
8
9# this is the embedding function we will use to create our embeddings for the descriptions
10def get_embedding(text):
11 embedding = openai.embeddings.create(input=text, model=EMBEDDING_MODEL).data[0].embedding
12 return embedding
Nós nos preparamos para o sucesso no processamento de nossos embeddings, então vamos configurar nosso dataframe!
Primeiro, queremos ler o arquivo que acabou de ser carregado:
1# we want to read in our file that we just uploaded
2df = pd.read_csv('/content/net-a-porter.csv')
Queremos nos concentrar apenas nas três primeiras colunas, já que não precisamos necessariamente da colunatype, então vamos soltá-la:
1# drop the 'type' column
2df.drop(columns=['type'], inplace=True)
É importante garantir que as colunas com as quais estamos lidando estejam limpas e não tenham valores nulos. Isso é crucial porque valores nulos podem atrapalhar nossos dados a longo prazo, e é uma boa prática sempre garantir que você esteja trabalhando com um conjunto de dados limpo. Para fazer isso, use dropna:
1# this is just saying to drop null values from our specific subsets, we want 'brand', price_usd', and 'description'
2df.dropna(subset=['brand', 'price_usd', 'description'], inplace=True)
Para garantir que não estamos gastando muito dinheiro e tempo incorporando cada descrição em nosso grande conjunto de dados, vamos dividi-lo em 100 linhas. Isso ainda nos fornecerá um tamanho de amostra interessante, mas não ocupará muitos recursos:
1# cut our entire file down to just 100 rows so that we don't spend a million dollars embedding the file
2df = df.head(100)
Agora, estamos prontos para criar uma nova coluna para onde nossas incorporações Go e, em seguida, podemos imprimir nossas primeiras 20 linhas apenas para garantir que estamos no caminho certo:
1# this is creating a new column with the embeddings
2df["description_embedding"] = df['description'].apply(get_embedding)
3
4
5# this is going to give us the first twenty rows from our file
6print(df.head(20))
Esse deve ser seu resultado, com a nova coluna description_embedding:Nossos dados e a coluna descrição_embedding recém-incluída
Como você pode ver, temos um dataframe com as colunas de que precisamos e, especificamente, nossa colunadescription_embeddingrecém-incluída ! Vamos nos certificar de que podemos salvar isso em nosso cluster para que possamos usar o MongoDB Atlas Vector Search quando estivermos prontos para fazê-lo.

Importar dados para Atlas utilizando PyMongoArrow

Como opymongoarrow usa o Apache Arrow nos detalhes, para mover nossos dados para o MongoDB Atlas, precisamos converter nosso dataframe do Pandas em uma tabela do Arrow. A grande parte das tabelas Arrow é que elas permitem colunas aninhadas, portanto, se tivéssemos um conjunto de dados mais complicado, não precisaremos pular muitos arcos para acomodar o aninhamento.
Agora que temos todos os nossos itens e incorporações, vamos usar pymongoarrow para importar todos os nossos dados para o MongoDB Atlas. Utilize um comandopip para instalar o pymongo, pymongoarrowe pyarrow.
1!pip install pymongo pymongoarrow pyarrow
Depois que isso for feito, podemos classificar nossos itens do mais caro ao mais barato (apenas por conveniência) e, em seguida, podemos importar todos os nossos itens para o cluster. Certifique-se de ter sua cadeia de conexão MongoDB disponível para que você possa se conectar ao seu cluster e executar esta etapa. Embora estejamos codificando isso para este tutorial, lembre-se de que não é seguro e as variáveis devem sempre ser armazenadas em um arquivo separado.
Copie o código abaixo para fazer isso:
1from pymongo import MongoClient
2from pymongoarrow.api import write
3import pyarrow as pa
4
5
6# I want to sort by most expensive item to least expensive
7df = df.sort_values(by=['price_usd'], ascending=False)
8
9
10# this is your connection to your cluster
11connection_string = "MONGODB-CONNECTION-STRING"
12client = MongoClient(connection_string)
13
14
15# you can name your database and collection anything you like
16database = client['net-a-porter']
17collection = database['average_prices_descending']
18
19
20# in order to save our data, we need to first convert our Pandas DataFrame to an Arrow Table using pyarrow
21arrow_table = pa.Table.from_pandas(df)
22
23
24write(collection, arrow_table)
25
26
27print("Successful")
28print(arrow_table)
Depois de executar esse bloco de código, certifique-se de verificar novamente no MongoDB Atlas se tudo está conforme o esperado. As linhas do seu arquivo.csv terão sido transformadas em documentos separados, com cada coluna como um novo campo. Certifique-se de que seu novo campodescription_embedding também esteja incluído!
Nossos dados foram importados corretamente para o MongoDB Atlas
Agora que temos nossos documentos incorporados, podemos configurar o MongoDB Atlas Vector Search.
Vamos começar a pesquisar semanticamente nos dados recém-importados. Primeiro, precisamos criar um MongoDB Atlas Vector Search. Para fazer isso, acesse sua conta do Atlas e siga as etapas.
Depois de concluído, deve ficar assim.
1{
2 "fields": [
3 {
4 "numDimensions": 1536,
5 "path": "description_embedding",
6 "similarity": "cosine",
7 "type": "vector"
8 }
9 ]
10}
O caminho que estamos usando é description_embedding, pois queremos que o índice do Vector Search seja usado em relação à nossa coluna de incorporação recém-incorporada. Para o camposimilarity, estamos escolhendo "euclidean,", mas, dependendo do seu caso de uso, você pode usar "cosine" ou "dot-product."
Mantenha seu "Index Name" como "vector_index," ou altere-o para algo que você se lembre, mas certifique-se de ter selecionado o banco de dados e a coleção corretos. Depois de salvar seu índice e carregá-lo, você saberá que ele está ativo quando o status for assim. Índice ativo do Vector Search
Tenha em mente que seu índice do Vector Search está isolado do MongoDB Atlas. Não faz parte do seu script Python geral e você não deve estar executando o índice em seu script.
Agora, Go ao arquivo do Google CoLab. Para pesquisar semanticamente, precisamos incorporar nossas queries. Essa é uma parte muito importante: Quando usamos a pesquisa semântica, não estamos comparando vetores com texto - estamos comparando vetores com vetores! Faça isso com estas duas linhas:
1# my query
2query_description = "summer"
3
4
5# we need to embed the query as well, since our documents are embedded
6query_vector = get_embedding(query_description)
Como já usamos o modelo de incorporação acima, também não é preciso muito trabalho incorporar nossas consultas.
Agora, precisamos definir o pipeline de agregação para que possamos pesquisar semanticamente. Podemos fazer isso usando $vectorSearch. O pipeline tem a seguinte aparência:
1# write the aggregation pipeline
2pipeline = [
3 {
4 '$vectorSearch': {
5 'index': 'vector_index',
6 'path': 'description_embedding',
7 'queryVector': query_vector,
8 # I only had 100 rows saved so that it's easier to use OpenAI
9 'numCandidates': 100,
10 'limit': 5
11 }
12 },
13 {
14 '$project': {
15 # i do not need to see the ID, but I do want to see my other columns.
16 '_id': 0,
17 'brand': 1,
18 'description': 1,
19 'price_usd': 1,
20 'score': {
21 '$meta': 'vectorSearchScore'
22 }
23 }
24 },
25 {
26 '$sort': {
27 'price_usd': -1 # sort by most expensive to least expensive
28 }
29 }
30]
Como você pode ver, usamos o recurso$projectpara mostrar apenas os campos que desejamos. Também usamos $vectorSearch para definir o índice, o caminho e nosso vetor de consulta. Verifique novamente se todos os campos estão corretos antes de prosseguir. Caso contrário, ele não será executado.
Depois que o pipeline for gravado, defina em qual banco de dados e coleção você deseja que ele seja executado e imprima os resultados:
1# the pipeline is run on this database and collection
2database = client['net-a-porter']
3collection = database['average_prices_descending']
4result = collection.aggregate(pipeline)
5
6
7
8
9for clothing in result:
10 print(clothing)
Neste tutorial usamos a query simples de "summer " e estes são os nossos resultados: Os nossos resultados com a query: “summer "
É interessante aqui porque quando eu perguntei sobre "summer," itens que incluíam meses de verão apareceram, como o mês de agosto.
Vamos mudar nossa query para "winter " e ver os resultados. Como você pode ver, do tamanho da nossa amostra, estamos obtendo resultados voltados para o clima mais frio, como casacos, jaquetas de esqui e calças de lã. Saída da nossa query "winter "
Eles também são classificados em ordem decrescente, do mais caro para o mais barato (para sonhar!), e podemos pesquisar os itens com rolagem limitada. Portanto, se você estiver no melhor modo de descanso e precisar de um modelo de cashmere com capuz e calça de moletom que custará quase $1300 (antes de impostos), você sabe onde procurar.

Próximos passos

Embora este tutorial tenha sido feito usando um conjunto de dados simples, depois de realmente entender os conceitos sobre como incorporar as plataformas e bibliotecas introduzidas, sinta-se à vontade para criar um web scraper e tentar esse mesmo método em dados ao vivo.

Conclusão

Este tutorial fornece uma ótima visão geral do que é possível fazer com o PyMongoArrow e o MongoDB Atlas Vector Search. Conseguimos pegar um conjunto de dados, processá-lo usando o Pandas, gerar as incorporações necessárias com o OpenAI, armazenar nossa recém-desenvolvida tabela Arrow no MongoDB Atlas usando PyMongoArrow e, em seguida, consultar semanticamente nosso banco de dados.
Para obter mais informações sobre o PyMongoArrow, acesse a documentaçãoe, para obter mais informações sobre oMongoDB Atlas Vector Search, consulte o tutorial. Se você tiver dúvidas ou quiser compartilhar seu trabalho, junta-se a nós na comunidade de desenvolvedores do MongoDB.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Artigo

Tudo que você sabe sobre MongoDB está errado!


Sep 23, 2022 | 11 min read
Início rápido

Armazene dados confidenciais com a criptografia em nível de campo do lado do cliente do Python & MongoDB


Sep 23, 2022 | 11 min read
Tutorial

Criptografia no nível do campo do lado do cliente (CSFLE) no MongoDB com Golang


Feb 03, 2023 | 15 min read
Artigo

Definir preocupações globais de leitura e gravação no MongoDB 4.4


Sep 23, 2022 | 7 min read
Sumário