Olá! É um prazer estar aqui novamente. Vamos iniciar nosso projeto integrador: plataforma de análise de reviews (avaliações).
Ao longo deste projeto, integraremos conceitos vistos nos cursos anteriores em um único projeto. Construiremos um dashboard (painel) no qual será possível utilizar um chatbot (robô de conversa) que fará consultas aos dados e trará respostas com base em análises de reviews (avaliações) da Amazon.
Meu nome é Julio Smitoro. Sou homem branco, tenho barba e estou vestindo uma camisa verde.
Audiodescrição: Julio é um homem branco, com barba, vestindo uma camisa verde.
Nosso treinamento será estruturado em quatro módulos.
No primeiro módulo, apresentaremos os dados, a fundação de dados e a análise exploratória. Identificaremos quais são os dados que utilizaremos. Já adiantamos que são dados de avaliações de produtos feitas por pessoas compradoras.
No módulo 2, trataremos de embeddings (incorporações vetoriais) e análise de sentimento. Abordaremos a conversão de texto em vetor e desenvolveremos um modelo de análise de sentimento baseado em XGBoost para associar um texto a um sentimento positivo, negativo ou neutro.
No módulo 3, construiremos o chatbot (robô de conversa) com RAG (recuperação aumentada por geração) e function calling (chamada de função).
No módulo 4, desenvolveremos o dashboard (painel), que adotaremos como produto final deste projeto integrador.
Sobre os requisitos, desenvolveremos o projeto utilizando o Visual Studio Code.
Vamos utilizar Pandas, SQLite, Sentence Transformers, LangChain e Streamlit; os LLMs (grandes modelos de linguagem) serão consumidos via Grok. Estamos utilizando o Visual Studio Code, mas é possível utilizar o Antigravity ou o Cursor. Utilizaremos o Visual Studio Code com a extensão Cloud Code.
O objetivo é simular um cenário real em que utilizamos um coding agent (agente de codificação) para auxiliar no processo de desenvolvimento dos projetos.
A estrutura do projeto que vamos desenvolver será organizada ao longo de alguns notebooks (cadernos de código). O nosso chatbot será implementado em módulos de Python, e desenvolveremos um front-end (camada de apresentação) com o Streamlit.
Para executar a aplicação, utilizamos o comando python -m streamlit run app.
No terminal, você pode executar:
python -m streamlit run app.py
Este é o produto final do projeto. A interface está carregando. Disponibilizamos dois modos: o modo de consulta SQL com busca e o modo de RAG (recuperação aumentada por geração). Explicaremos ao longo do curso o que cada recurso faz. Por exemplo, poderemos enviar uma consulta como: quantas reviews (avaliações) negativas, neutras e positivas existem. Nesse caso, o chatbot utilizará uma tool (ferramenta) de consulta SQL com base na pergunta, gerará a query (consulta) SQL e executará a chamada no banco de dados.
Esse é o objetivo do treinamento. Ao longo de quatro módulos, construiremos a base até chegar a esse produto final.
Nos encontramos na próxima aula. [♪]
Vamos iniciar o módulo 01, Fundação de Dados e Análise Exploratória. Como mencionado anteriormente, o dataset (conjunto de dados) que vamos estudar ao longo deste treinamento é o Amazon Reviews de 2023. Trata-se de uma série de avaliações feitas por pessoas consumidoras da Amazon.
Ao comprar um produto, normalmente verificamos as avaliações. Na Amazon, as avaliações recebem notas de uma a cinco estrelas e podem incluir um comentário. É exatamente isso que temos neste dataset (conjunto de dados): o comentário da pessoa consumidora e a nota atribuída ao produto. Este é um grande conjunto público de avaliações de produtos da Amazon, compilado por um grupo de pesquisa de uma universidade, e reúne muitos dados, o que ficará mais claro quando apresentarmos o dataset (conjunto de dados).
Estávamos avaliando comprar um fone de ouvido, que inclusive compramos. Esse tipo de situação ilustra bem como as avaliações funcionam e por que são relevantes para análise.
Os objetivos deste primeiro módulo são:
Vamos iniciar o projeto do zero. No entanto, utilizaremos os materiais de referência. Esses são os materiais que vocês receberão ao longo do treinamento. Para cada um dos quatro módulos, haverá um material específico. Desde o primeiro momento, haverá acesso ao projeto final, que deve ser usado como referência. Recomendamos acompanhar o fluxo de desenvolvimento apresentado ao longo das aulas.
Neste primeiro momento, vamos utilizar os materiais do módulo 01. Aqui temos:
README;requirements;Podemos copiar os arquivos para o diretório do projeto. Em seguida, precisamos preparar o ambiente que vamos utilizar.
Vamos abrir um terminal.
Especificamos a versão do Python 3.11 e criamos um ambiente virtual utilizando o módulo de ambientes virtuais. Essas informações estão apresentadas no arquivo README. No terminal, fazemos isso com o comando:
python3.11 -m venv .venv
Como estamos utilizando macOS, ativamos o ambiente virtual com o comando apropriado para esse sistema. Se estivermos no Windows, utilizamos o comando correspondente. No macOS, o comando é:
source .venv/bin/activate
No README, trazemos um resumo do projeto, a estrutura final do projeto e o passo a passo para executar.
Na sequência, fazemos a instalação das dependências do projeto. No arquivo requirements.txt, descrevemos as bibliotecas necessárias para o ambiente: pandas, NumPy, Matplotlib, tqdm e huggingface_hub. Abaixo está o conteúdo do arquivo:
# modulo 01 - EDA
pandas
numpy
matplotlib
tqdm
huggingface_hub
Poderíamos remover NumPy, pois, ao instalar pandas, NumPy já é instalado como dependência. No README, indicamos o uso do gerenciador pip para instalar as dependências a partir do requirements.txt. Para isso, executamos:
pip install -r requirements.txt
Em seguida, executamos a instalação, que prepara tudo o que é necessário para a execução deste projeto.
Concluímos a configuração do ambiente; tudo está pronto para iniciar a execução do projeto.
Na aula seguinte, vamos iniciar com o primeiro Jupyter Notebook, GetData.
Pessoal, dito isso, eu te encontro na próxima aula.
Olá!
Agora que concluímos a configuração do nosso ambiente, podemos seguir com as etapas de execução dos nossos notebooks.
Temos o nosso ambiente virtual configurado, com as dependências instaladas e tudo pronto.
Vamos executar o nosso primeiro Jupyter Notebook, GetData.ipynb. Nesse notebook, o objetivo será realizar a aquisição dos dados.
Antes de prosseguir, vamos esclarecer quais são os dados que estamos analisando ao longo deste projeto. Trata-se do conjunto Amazon Reviews 2023. Podemos facilmente localizar esse material no Google, procurando pela plataforma Hugging Face. Ao buscar por Hugging Face e Amazon Reviews 2023, encontramos o conjunto de dados que precisamos analisar neste momento.
Na página do conjunto de dados, há um link para a página oficial das pessoas desenvolvedoras, com mais detalhes. Entre as informações, estão os anos contemplados: 2013, 2014, 2018 e 2023. A quantidade de avaliações é bastante grande; por exemplo, em 2023 há 571,54 milhões de avaliações. Também há a divisão por categorias, uma vez que, dentro da Amazon, existem diversos tipos de produtos, agrupados por categoria. Entre elas, encontramos All Beauty, Amazon Fashion, Appliances e Automotive, entre outras. É possível baixar as avaliações e os dados diretamente pela página, mas faremos isso utilizando linhas de código em Python.
Voltando ao nosso ambiente, o objetivo será buscar os dados do conjunto de dados disponível no Hugging Face. Como recorte, usaremos a categoria All Beauty. Desse conjunto, vamos extrair as avaliações e armazená-las em um banco de dados local no formato .db, por exemplo, no arquivo reviews.db.
Para este exercício, vamos trabalhar com uma única categoria (All Beauty) e com o ano de 2021. Vamos obter todas as avaliações dessa categoria referentes ao ano de 2021. É possível adotar outras estratégias, como incluir mais categorias ou ampliar o recorte do conjunto de dados, mas isso exigiria mais memória para treinar o modelo. Por esse motivo, vamos fixar o ano de 2021 e a categoria All Beauty.
Antes de executar o Jupyter Notebook, vamos tratar da estrutura do projeto. Uma boa prática é centralizar, em um arquivo de configuração ou em variáveis de ambiente, as informações que podemos querer ajustar ao longo da execução do projeto. No arquivo config.py, reunimos uma série de configurações, como:
META_COLS);DB_PATH).Veja um exemplo de como centralizamos essas configurações em config.py:
import os
REPO_ID = 'McAuley-Lab/Amazon-Reviews-2023'
CATEGORIA = 'All_Beauty'
REVIEW_COLS = ["rating", "title", "text", "parent_asin", "user_id",
"timestamp", "helpful_vote", "verified_purchase"]
META_COLS = ["parent_asin", "title", "main_category",
"average_rating", "rating_number", "price", "store"]
# Aquisição: uma categoria, um ano inteiro, sem amostragem.
ANO_ALVO = 2021
MIN_CARACTERES = 20
DB_PATH = 'data/reviews.db'
Alguns pontos podem gerar dúvidas, como, por exemplo, o significado das colunas. Para entendê-las melhor, podemos abrir a página do conjunto de dados no Hugging Face, acessar a aba Files and Versions (Arquivos e versões) e, em seguida, Raw (bruto). Ali, nas seções correspondentes a avaliações (por exemplo, Review Categories), são listadas as colunas disponíveis. Como estamos trabalhando com a categoria All Beauty, esse é o arquivo que vamos buscar. O arquivo é do tipo JSON Lines (JSON por linhas). Portanto, especificamos em config.py quais colunas vamos extrair desse formato para cada categoria. Essa configuração pode parecer intuitiva para quem já utiliza conjuntos de dados do Hugging Face, mas vamos avançar no desenvolvimento e, depois, voltamos a esses detalhes conforme necessário.
Com a categoria e o ano definidos, criamos as variáveis correspondentes em config.py. Para executar o Jupyter Notebook, precisamos selecionar o kernel, isto é, o kernel associado ao nosso ambiente virtual. No nosso caso, usaremos o ambiente virtual .venv. Com isso selecionado, podemos executar as funções normalmente.
Do config.py, importamos informações como ano-alvo, categoria, DB_PATH, as colunas e o REPO_ID. No arquivo utils.py, criamos uma função para executar consultas SQL. Explicaremos esse ponto mais adiante; por ora, vamos até comentar o trecho associado, para que ocorra um erro mais à frente e possamos retomar a explicação no momento oportuno.
Primeiro, fazemos as importações gerais: sqlite3, pandas e utilitários do pacote huggingface_hub (vamos apelidar hf_hub_download como hf para facilitar). O snippet abaixo mostra essas importações, além de carregar as configurações do config.py:
import os
import sqlite3
import pandas as pd
from huggingface_hub import hf_hub_download as hf
from config import (ANO_ALVO, CATEGORIA, DB_PATH, META_COLS, MIN_CARACTERES,
REPO_ID, REVIEW_COLS)
from utils.sql import query_sql
Como mencionado, vamos comentar temporariamente a importação da função de utilitários para que possamos demonstrar o erro e, depois, corrigi-lo no momento oportuno:
from config import (ANO_ALVO, CATEGORIA, DB_PATH, META_COLS, MIN_CARACTERES,
REPO_ID, REVIEW_COLS)
# from utils.sql import query_sql
Em seguida, limpamos todos os resultados anteriores e executamos a primeira célula. Será solicitado que instalemos o pacote do kernel para o Jupyter dentro do ambiente virtual (por exemplo, o pacote ipykernel). Concluída essa etapa, o notebook estará pronto para uso.
Neste ponto, importamos sqlite3, pandas e utilitários do pacote huggingface_hub (por exemplo, a função hf_hub_download), que será utilizada para realizar o download (transferência) do conjunto de dados. Podemos apelidar o módulo/função, conforme a conveniência do código, para facilitar as chamadas.
Para baixar os arquivos brutos, criaremos uma função auxiliar. Em linhas gerais, ela recebe:
repo_id (identificador do repositório no Hugging Face);repo_type (tipo de repositório);filename (caminho do arquivo a ser baixado);O repo_id corresponde ao identificador do nosso conjunto de dados (informação exibida no topo da página do repositório). O filename é o caminho do arquivo que será baixado. Por exemplo, podemos navegar até a raiz do repositório e, então, especificar o caminho dentro de raw (bruto): primeiro a pasta, como "review_categories" ou "meta_categories", e depois o nome do arquivo (relacionado à categoria de interesse). Assim, a função recebe a pasta e o nome, localiza o arquivo na pasta específica e o baixa para a máquina local.
Podemos implementar e usar essa função assim:
def baixar(pasta: str, nome: str) -> str:
return hf(repo_id=REPO_ID, repo_type="dataset",
filename=f"raw/{pasta}/{nome}.jsonl", cache_dir="data/hf_cache")
arquivo_reviews = baixar("review_categories", CATEGORIA)
arquivo_meta = baixar("meta_categories", f"meta_{CATEGORIA}")
print("arquivos prontos")
Para baixar os arquivos de avaliações, chamaremos a função auxiliar informando "review_categories" e a categoria (which comporá o filename). Ao executar, o processo de download (transferência) é iniciado e os arquivos passam a ser armazenados dentro da pasta "data". Dentro de "data", o Hugging Face utiliza uma estrutura de cache (memória de cache), por exemplo, "hf_cache", para gerenciar os arquivos baixados localmente.
Após a conclusão, a ferramenta informa que o download (transferência) foi realizado. Se verificarmos o conteúdo do cache, veremos diretórios como "datasets" e "snapshots" (instantâneos), que registram os artefatos baixados.
Aqui, ReviewCategory e MetaCategory.
Em ReviewCategory, temos o arquivo em formato JSON Lines, exatamente aquele arquivo que estávamos verificando.
Temos uma série de colunas.
Agora, vamos filtrar as colunas de interesse. Foi por isso que definimos essas colunas em config.py.
Por exemplo, temos rating, title e text.
Essas são as informações necessárias dentro das revisões para que possamos treinar nosso modelo de análise de sentimento no módulo seguinte.
Neste momento, já conseguimos baixar as revisões do Hugging Face, utilizando o Hugging Face Hub e o processo de download.
Precisamos agora realizar algumas filtragens, porque o arquivo traz todos os dados e, portanto, vamos especificar as informações que queremos.
A primeira função vai apenas receber o JSON Lines e retornar um DataFrame. Aqui não há nada muito robusto. Vamos, inclusive, comentar esse trecho de código.
Para isso, começamos implementando a função que lê o JSONL em pedaços e devolve um DataFrame com apenas as colunas selecionadas. Em seguida, carregamos as reviews inicialmente:
def jsonl_to_dataframe(arquivo: str, cols: list[str]) -> pd.DataFrame:
# Como o arquivo JSONL pode ser grande, vamos ler em pedaços (chunks)
dfs = []
with pd.read_json(arquivo, lines=True, chunksize=100_000) as reader:
for chunk in reader:
dfs.append(chunk[cols])
return pd.concat(dfs, ignore_index=True)
reviews = jsonl_to_dataframe(arquivo_reviews, REVIEW_COLS)
print(f"reviews na categoria: len({reviews})")
Por ora, deixamos os passos de transformação comentados, mantendo apenas a leitura e a seleção das colunas:
reviews = jsonl_to_dataframe(arquivo_reviews, REVIEW_COLS)
# print(f"reviews na categoria: len({reviews})")
# reviews = reviews.rename(columns={"parent_asin": "product_id", "timestamp": "review_date"})
# reviews["review_date"] = pd.to_datetime(reviews["review_date"], unit='ms')
# # Filtros
# reviews = reviews[(reviews["review_date"].dt.year == ANO_ALVO)
# & (reviews["text"].str.len() >= MIN_CARACTERES)]
# reviews = reviews.drop_duplicates(subset=["user_id", "text"])
# reviews["review_date"] = reviews["review_date"].astype(str)
# reviews["verified_purchase"] = reviews["verified_purchase"].astype(int)
# reviews["helpful_vote"] = reviews["helpful_vote"].fillna(0).astype(int)
# reviews = reviews.sort_values("review_date").reset_index(drop=True)
# reviews.insert(0, 'review_id', range(1, len(reviews) + 1))
# print(f"reviews no ano {ANO_ALVO} após filtros: {len(reviews)}")
# reviews.head()
Se executarmos e verificarmos Reviews depois, basicamente, o que era JSON Lines agora está no formato DataFrame. É simples chegar a essa conclusão quando percebemos que a saída é de fato um DataFrame.
Passamos o arquivo, especificamos quais são as colunas e ele retorna como DataFrame. É exatamente isso que está sendo feito. Passamos REVIEW_COLS, filtramos dentro do JSON Lines somente as colunas de interesse e obtemos um DataFrame contendo apenas os dados necessários.
Agora, vamos realizar outras alterações nesse DataFrame que já convertemos a partir do JSON Lines.
Primeiro, vamos fazer um renomeamento. A coluna parent_asin ficará como product_id, timestamp será convertida para review_date e review_date será convertido para o tipo DateTime.
Esse ajuste de nomes e a conversão de review_date para DateTime são necessários porque agora aplicaremos alguns filtros.
review_date deverá ser igual ao AnoAlvo, que é 2021. Assim, traremos apenas dados de 2021.
Também verificaremos se o tamanho dos textos dos nossos reviews é maior ou igual ao mínimo de caracteres definido anteriormente.
Vamos remover duplicatas: verificamos se o text atribuído a um user_id foi repetido; em caso afirmativo, mantemos somente o primeiro.
Em seguida, convertemos review_date novamente para string.
No caso da verificação de compra, o campo verified_purchase, que é booleano (True/False), será convertido para 0/1.
No campo de voto útil, helpful_vote, valores None serão convertidos para 0. Essa é uma decisão que pode impactar o resultado.
Aplicaremos um sort_values baseado em review_date.
Depois de executar, teremos o DataFrame final com as configurações dos nossos reviews, contendo review_id, rating, title, text, product_id e demais informações necessárias.
Podemos agora aplicar todas essas transformações:
reviews = jsonl_to_dataframe(arquivo_reviews, REVIEW_COLS)
print(f"reviews na categoria: len({reviews})")
reviews = reviews.rename(columns={"parent_asin": "product_id", "timestamp": "review_date"})
reviews["review_date"] = pd.to_datetime(reviews["review_date"], unit='ms')
# Filtros
reviews = reviews[(reviews["review_date"].dt.year == ANO_ALVO)
& (reviews["text"].str.len() >= MIN_CARACTERES)]
reviews = reviews.drop_duplicates(subset=["user_id", "text"])
reviews["review_date"] = reviews["review_date"].astype(str)
reviews["verified_purchase"] = reviews["verified_purchase"].astype(int)
reviews["helpful_vote"] = reviews["helpful_vote"].fillna(0).astype(int)
reviews = reviews.sort_values("review_date").reset_index(drop=True)
reviews.insert(0, 'review_id', range(1, len(reviews) + 1))
print(f"reviews no ano {ANO_ALVO} após filtros: {len(reviews)}")
reviews.head()
Agora, vamos tratar dos metadados do produto.
Basicamente, usaremos a mesma função para processar os arquivos de metadados, META_COLS.
Faremos o renomeamento e alguns outros processamentos, incluindo a remoção de duplicatas com base em product_id.
Podemos imprimir para inspecionar. Ao executar, teremos product_id, title, main_category, a nota média (average_rating), rating_number e price.
products = jsonl_to_dataframe(arquivo_meta, META_COLS)
products = (products.rename(columns={"parent_asin": "product_id"})
.assign(price=pd.to_numeric(products["price"], errors='coerce'))
.dropna(subset=['price', 'store'])
.drop_duplicates(subset=["product_id"]))
print(f"produtos no metadado: len({products})")
products.head(3)
Com base nisso, conseguimos associar essas duas tabelas, pois ambas possuem product_id. Portanto, conseguimos realizar um JOIN entre as duas.
Processamos os produtos e também os nossos reviews.
Agora, vamos converter e enviar tudo para um banco SQLite.
Como primeiro passo, criamos uma conexão com sqlite3.connect, passando dbpath.
Lembrando: dbpath é o que definimos em config.py.
Em seguida, executamos um script no qual passamos a query SQL.
Esse script, primeiro, remove as tabelas Review e Produto, caso existam. Em seguida, cria a tabela Produto, com as colunas ProductId (chave primária), Title, MainCategory, AverageRating, RatingNumber, Price e Store.
Também criamos a tabela Reviews, com ReviewId, ProductId, UserId, ASIN, Rating, Title, Text, ReviewDate, HelpfulVote e VerifiedPurchase.
Veja como isso fica no código (note que os nomes das tabelas/colunas no script estão em inglês, seguindo o padrão do nosso código):
conn = sqlite3.connect(DB_PATH)
cur = conn.cursor()
# DROP TABLE IF EXISTS produtos;
# DROP TABLE IF EXISTS reviews;
cur.executescript('''
CREATE TABLE products (
product_id TEXT PRIMARY KEY,
title TEXT,
main_category TEXT,
average_rating REAL,
rating_number INTEGER,
price REAL,
store TEXT
);
CREATE TABLE reviews (
review_id INTEGER PRIMARY KEY,
product_id TEXT NOT NULL REFERENCES products(product_id),
user_id TEXT NOT NULL,
asin TEXT,
rating REAL NOT NULL,
title TEXT,
text TEXT,
review_date TEXT NOT NULL,
helpful_vote INTEGER,
verified_purchase INTEGER
);
CREATE INDEX idx_review_product ON reviews(product_id);
CREATE INDEX idx_review_date ON reviews(review_date);
''')
# products.to_sql("products", conn, if_exists="append", index=False)
# reviews.to_sql("reviews", conn, if_exists="append", index=False)
# conn.commit()
# print("banco gravado")
Depois de criar as tabelas, comentamos o trecho de código específico e executamos o comando para verificar o resultado. Dentro da pasta "Data", foi criado o arquivo Reviews.db. Nele, constam as estruturas para produtos e reviews.
Agora, pegamos os DataFrames criados anteriormente, Products e Reviews, usamos to_sql para converter cada DataFrame para SQL e enviamos para dentro do nosso Reviews.db.
CREATE INDEX idx_review_product ON reviews(product_id);
CREATE INDEX idx_review_date ON reviews(review_date);
''')
products.to_sql("products", conn, if_exists="append", index=False)
reviews.to_sql("reviews", conn, if_exists="append", index=False)
conn.commit()
print("banco gravado")
Ao executar, teremos a tabela de produtos e a tabela de reviews devidamente persistidas.
Com isso, concluímos a primeira demanda: buscar os dados no Hugging Face e armazená-los em Reviews.db.
Podemos fazer uma breve conferência. Se executarmos uma consulta agora, pode ocorrer um erro. A origem desse erro é a função QuerySql.
Adotamos aqui uma boa prática que utilizamos em nossos projetos: como estamos trabalhando com um banco SQLite e precisaremos executar QuerySql repetidamente, criamos dentro da pasta "utils" um módulo Python sql com a função QuerySql. Essa função recebe a conexão e a query e retorna o resultado no formato DataFrame. Precisamos importá-la.
Para começar a checagem, tentamos rodar consultas usando query_sql — lembrando que deixamos a importação comentada anteriormente, justamente para evidenciar o erro:
# from utils.sql import query_sql
resumo = query_sql(conn, '''
SELECT COUNT(*) AS n_reviews,
ROUND(AVG(rating), 2) AS nota_media,
ROUND(100.0 * AVG(verified_purchase), 2) AS pct_verificados,
MIN(review_date) AS primeira,
MAX(DATE(review_date)) AS ultima
FROM reviews
''')
print(resumo.to_string(index=False))
per_mes = query_sql(conn, '''
SELECT strftime('%m', review_date) AS mes, COUNT(*) AS n, ROUND(AVG(rating), 2) AS nota
FROM reviews GROUP BY mes
''')
# conn.close()
per_mes
Como esperado, sem a importação ativa, ao executar, veremos um erro indicando que query_sql não está definido.
Agora, vamos definir essa função no módulo utils/sql.py e então importá-la. A função simplesmente executa a query e retorna um DataFrame:
import pandas as pd
def query_sql(conn, query: str) -> pd.DataFrame:
"""Executa uma query SQL e devolve um DataFrame com o resultado."""
return pd.read_sql_query(query, conn)
Fazemos o seguinte: from utils.sql import query_sql. Passamos a conexão e a query para QuerySql. Ao executar, tudo funciona.
from utils.sql import query_sql
resumo = query_sql(conn, '''
SELECT COUNT(*) AS n_reviews,
ROUND(AVG(rating), 2) AS nota_media,
ROUND(100.0 * AVG(verified_purchase), 2) AS pct_verificados,
MIN(review_date) AS primeira,
MAX(DATE(review_date)) AS ultima
FROM reviews
''')
print(resumo.to_string(index=False))
per_mes = query_sql(conn, '''
SELECT strftime('%m', review_date) AS mes, COUNT(*) AS n, ROUND(AVG(rating), 2) AS nota
FROM reviews GROUP BY mes
''')
# conn.close()
per_mes
Apresentamos algumas informações: estamos calculando a contagem do número de reviews (avaliações), a nota média, o percentual de verificados, além da primeira e da última avaliação.
Em seguida, obtemos o resumo como resultado.
O resultado é apresentado como um DataFrame (estrutura de dados tabular). Em seguida, convertemos para String (texto) e realizamos outra consulta.
Identificamos um erro: o problema ocorre porque estamos fechando o banco de dados.
Vamos retornar ao início, onde criamos a conexão. Localizamos o trecho em que a conexão foi criada, vamos copiar esse caminho e inseri-lo aqui. Funcionou.
from utils.sql import query_sql
conn = sqlite3.connect(DB_PATH)
resumo = query_sql(conn, '''
Aqui trazemos essas métricas e realizamos outra verificação.
Estamos efetuando um agrupamento por mês.
SELECT strftime('%m', review_date) AS mes, COUNT(*) AS n, ROUND(AVG(rating), 2) AS nota
FROM reviews GROUP BY mes
''')
conn.close()
per_mes
Esse é o resultado e, por ora, está funcionando.
Concluímos nosso primeiro objetivo: extrair os dados do Hugging Face e inseri-los em um SQLite.
Na próxima aula, retornaremos para avaliar esses dados e realizar uma análise exploratória breve.
Pessoal, agradeço muito e te vejo na próxima aula.
O curso Projeto ciência de dados: plataforma de análise de reviews com chatbot possui 146 minutos de vídeos, em um total de 28 atividades. Gostou? Conheça nossos outros cursos de Exploração de Dados em Dados, ou leia nossos artigos de Dados.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
O Plano Plus evoluiu: agora com Luri para impulsionar sua carreira com os melhores cursos e acesso à maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Back-end, Dados, Front-end, DevOps, Mobile, Gestão & Negócios, UX & Design, Cibersegurança, Cloud, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
Acesso à inteligência artificial da Alura.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Catálogo de tecnologia para quem é da área de Marketing
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
20% de desconto na Pós Tech
Luri Vision chegou no Plano Pro: a IA da Alura que enxerga suas dúvidas, acelera seu aprendizado e conta também com o Alura Língua que prepara você para competir no mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Acesso ao catálogo da Casa do Código e leitura dentro da plataforma
Modo entrevista - Pratique situações reais e evolua com feedback personalizado
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para quem quer atingir seus objetivos mais rápido: Luri Vision ilimitado, vagas de emprego exclusivas e mentorias para acelerar cada etapa da jornada.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais de forma ilimitada.
Lives CareerUp: eventos exclusivos com foco em empregabilidade e carreira
Mentorias de carreira: 2 encontros individuais com mentores do Talent Lab
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.