DEV Community

Cover image for MindsDB + Docker: Utilizando SQL e containers para integrações com IA
Rafael Pazini
Rafael Pazini

Posted on

MindsDB + Docker: Utilizando SQL e containers para integrações com IA

Já pensou em criar sua própria IA, treiná-la com seus dados e utilizar esse "conhecimento" para alavancar seu app ou algum projeto em que você está trabalhando? Eu também pensei nisso e tive a mesma reação: "Nossa, que preguiça! Imagina quanto tempo eu ia perder fazendo isso..."

Quando pensamos em IA, geralmente imaginamos ter que começar do zero, aprender uma nova linguagem, escrever milhares de linhas de código para integrar com o app. Mas e se eu te disser que dá para fazer isso apenas usando SQL ou então fazendo uma requisição HTTP? É exatamente isso que o MindsDB faz por nós.

O que é o MindsDB?

O MindsDB é uma plataforma que facilita a criação e integração de modelos de aprendizado de máquina (machine learning) diretamente com bancos de dados, utilizando SQL - sim, você não precisa aprender outra linguagem para trabalhar com IA 😅.

Ela permite que desenvolvedores, como nós, aproveitem os dados existentes em seus bancos de dados e construam modelos de aprendizado de máquina sem a necessidade de conhecimentos avançados em ciência de dados ou machine learning.

Em resumo, ele permite termos nossa IA personalizada para nossos dados direto da nossa aplicação. Se liga no diagrama abaixo, nele podemos ver como é a estrutura do MindsDB e um pouco de como é sua integração.

MindsDB DIAGRAM

Benefícios do MindsDB

  • Facilidade de Uso: Ideal para desenvolvedores que já estão familiarizados com SQL, eliminando a necessidade de aprender novas linguagens de programação.
  • Agilidade: Reduz o tempo e esforço necessários para desenvolver e implementar modelos de machine learning.
  • Flexibilidade: Funciona com uma ampla gama de bancos de dados e pode ser integrado em diversas aplicações.

Depois disso, você deve estar se perguntando: "Mas e aí, Rafa, será que é tão simples a integração e a brincadeira com ele?" Vamos colocar a mão na massa e ver se é assim mesmo…

Contexto e Problema

Vamos imaginar que temos uma loja de café onde nossos usuários deixam seus reviews sobre o que acharam do nosso café. A cada 3 meses renovamos o cardápio da loja e queremos trocar os cafés que têm opiniões “neutras” ou “negativas” sobre eles.

Coffee shop

Queremos fazer isso de uma forma rápida e simples, sem ter que ficar lendo milhões de comentários para analisar um a um e, no fim, contar as opiniões sobre o que temos. Então, como todo bom programador, vamos utilizar a hype do momento: a IA para classificar esses comentários para nós e, de quebra, aprender uma tecnologia nova.

Deploy com Docker

Eu gosto de facilitar tudo na minha vida, então a maneira mais simples de instalar uma ferramenta ou algum app sem ter que ficar configurando mil coisas em nossa máquina local é usando Docker 😄.

O MindsDB utiliza várias dependências para funcionar, como Python, MongoDB, MySQL, e utilizando a imagem Docker não temos que nos preocupar em instalar nada disso em nossa máquina.

Para seguir esse tutorial, você deve ter o Docker instalado e rodando em sua máquina. Caso ainda não tenha ele instalado, basta seguir o tutorial da documentação oficial.

Como eu quero trazer um exemplo de uso real, vamos ter dois containers rodando: um com o MindsDB e outro com um MySQL, que é o banco de dados onde já existem nossos comentários sobre os cafés.

Para ter acesso ao projeto, basta baixar a pasta dele no meu Github, onde teremos a seguinte estrutura dentro da pasta:

mindsdb_docker
    ├── compose.yml //incia os nossos containers
    └── dump.sql    //insere os dados em nosso DB
Enter fullscreen mode Exit fullscreen mode

Com o projeto baixado, é hora de rodá-lo localmente. Para executar o docker compose, digite o seguinte comando:

$ docker compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Após realizar o comando, você receberá a seguinte mensagem em seu terminal dizendo que tudo foi inicializado:

 ✔ Network mindsdb_sample_default      Created      0.0s 
 ✔ Container mindsdb_sample-mysql-1    Started      0.3s 
 ✔ Container mindsdb_sample-mindsdb-1  Started      0.3s 
Enter fullscreen mode Exit fullscreen mode

Agora é só acessar a URL do MindsDB que é http://localhost:47334 para ver a interface gráfica dele.

Interface mindsDB

Configurando a conexão com DB

Como já temos a instância do MindsDB rodando localmente, vamos configurar a conexão dele com nossa base de dados, de onde serão retiradas as reviews.

Para isso, basta digitar o seguinte comando SQL:

CREATE DATABASE mysql_sample
WITH ENGINE = 'mysql',
PARAMETERS = {
    "user": "root",
    "password": "r00tPassword123",
    "host": "<ip-local-do-seu-computador>", --troque pelo seu ip local
    "port": "3306",
    "database": "cool_data"
};
Enter fullscreen mode Exit fullscreen mode

Um detalhe importante é que no host devemos colocar o IP local do nosso computador. Por exemplo, o meu é 10.0.2.10 pois não podemos esquecer que estamos dentro de um container e que a porta mapeada para acesso é a do nosso host. Se colocarmos localhost, ele não encontrará o banco de dados. Caso não saiba qual é seu IP, aqui vai um comando que pode ajudar 😄

$ ifconfig | grep \"inet \" | grep -v 127.0.0.1 | cut -d\  -f2 
Enter fullscreen mode Exit fullscreen mode

O que estamos fazendo com esse comando SQL:

  • Criando a conexão com o banco e dizendo que ela se chamará mysql_sample.
  • Dizendo qual é a ENGINE de banco de dados que queremos utilizar.
  • Passando os parâmetros de conexão: usuário, senha, host e o nome do banco de dados que vamos nos conectar.

Agora vamos validar se nossa conexão está funcionando. Para isso, vamos usar o bom e velho SELECT do nosso querido SQL:

SELECT * 
FROM mysql_sample.coffee_review
LIMIT 2;
Enter fullscreen mode Exit fullscreen mode

Ele deve retornar os valores que existem em nosso banco de dados. No caso, temos uma tabela chamada coffee_review e os seguintes campos: id, coffee_name, origin e review com os dados já preenchidos. Note também que durante a consulta SQL utilizei o nome da conexão que criamos no passo acima para dizer para o MindsDB que quero pegar a tabela coffee_review que está dentro do meu banco mysql_sample.

Assim sabemos que temos uma conexão de sucesso entre a nossa base de dados e o MindsDB

Criando uma ML Engine

O MindsDB, como eu disse no início, tem suporte para vários plugins e um deles são as ML Engines. No nosso caso, como queremos fazer a análise dos comentários, vamos utilizar a OpenAI engine e para isso precisamos configurá-la.

Para o próximo passa você precisará de uma API Key e consegue gera-la no próprio site da OpenAI: platform.openai.com

Com a API Key em mãos podemos criar a ML Engine dentro do MindsDB, é bem tranquilo:

CREATE ML_ENGINE openai
FROM openai
USING
    openai_api_key = 'sk-xxxx'; --substitua o valor pela sua chave
Enter fullscreen mode Exit fullscreen mode

O MindsDB disponibiliza o handler, que é a integração do MindsDB com as APIs das IAs. Então, o que temos que fazer é apenas dizer que queremos criar uma nova engine usando o handler específico para ela. Existem vários e você pode encontrar a lista deles na documentação. No código acima, estamos criando a openai engine, usando o handler da openai e passando a nossa API key para ele.

Essa simples configuração já faz a integração do nosso MindsDB com a IA que escolhemos.

Hora de criar o Modelo

Quando falamos de modelo, em palavras simplificadas, é o modelo de aprendizagem que a IA vai utilizar para fazer a tarefa que queremos que ela execute.

No MindsDB vamos criar este modelo de aprendizagem utilizando SQL e passando algumas informações para ele.

Assim ficará nosso modelo que classifica os comentários sobre o café como positivo, negativo e neutro.

CREATE MODEL coffee_review_sentiment
PREDICT sentiment
USING
    engine = 'openai',
    model_name = 'gpt-4',
    prompt_template = 'descreva o sentimento dos comentários apenas como "positivo", "negativo" ou "neutro".
                    "Amei este café":positivo
                    "Não me agradou": negativo
                    "{{review}}.":';
Enter fullscreen mode Exit fullscreen mode

No código acima, a primeira coisa que fazemos é dar um nome para o modelo, que se chama coffee_review_sentiment. Logo em seguida, falamos para o modelo que ele vai “prever” a propriedade sentiment, ou seja, estamos falando que o resultado do nosso prompt será exibido nessa coluna. Por fim, dizemos qual engine queremos usar: openai, que é a que acabamos de configurar. Dizemos também que queremos utilizar o gpt-4 como modelo de IA e como estamos usando a OpenAI, ela sempre espera um prompt de comando, que é onde passamos para o modelo o que esperamos que ele faça e com qual informação ele vai trabalhar.

Após executar o comando de criar, você provavelmente receberá o seguinte output:

| TABLES              | NAME                      | ENGINE | PROJECT | ACTIVE | VERSION | STATUS     | ACCURACY | PREDICT   | UPDATE_STATUS | MINDSDB_VERSION | ERROR  | SELECT_DATA_QUERY | TRAINING_OPTIONS                                                                                                                                                                                                                                                                                                                 | TAG    |
|---------------------|---------------------------|--------|---------|--------|---------|------------|----------|-----------|---------------|-----------------|--------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|
| ["args","metadata"] | coffee_review_sentiment_6 | openai | mindsdb | true   | 1       | generating | [NULL]   | sentiment | up_to_date    | 24.4.3.0        | [NULL] | [NULL]            | {'__mdb_sql_task': None, 'target': 'sentiment', 'using': {'model_name': 'gpt-4', 'prompt_template': 'descreva o sentimento dos comentários apenas como "positivo", "negativo" ou "neutro".\n                    "Amei este café":positivo\n                    "Não me agradou": negativo\n                    "{{review}}.":'}} | [NULL] |

Enter fullscreen mode Exit fullscreen mode

Repare que na coluna STATUS temos o valor generating, ou seja, o nosso modelo está sendo gerado ainda. Ainda não podemos utilizá-lo em nossas consultas; para ele se tornar útil o status deve ser complete. Para consultar o valor do status, utilizamos o comando DESCRIBE para descrever o que temos na nossa tabela de modelo:

DESCRIBE coffee_review_sentiment;
Enter fullscreen mode Exit fullscreen mode

Quando o status for complete, você verá no resultado da query:

| TABLES              | NAME                      | ENGINE | PROJECT | ACTIVE | VERSION | STATUS   | ACCURACY | PREDICT   | UPDATE_STATUS | MINDSDB_VERSION | ERROR  | SELECT_DATA_QUERY | TRAINING_OPTIONS                                                                                                                                                                                                                                                                                                                 | TAG    |
|---------------------|---------------------------|--------|---------|--------|---------|----------|----------|-----------|---------------|-----------------|--------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|
| ["args","metadata"] | coffee_review_sentiment_6 | openai | mindsdb | true   | 1       | complete | [NULL]   | sentiment | up_to_date    | 24.4.3.0        | [NULL] | [NULL]            | {'__mdb_sql_task': None, 'target': 'sentiment', 'using': {'model_name': 'gpt-4', 'prompt_template': 'descreva o sentimento dos comentários apenas como "positivo", "negativo" ou "neutro".\n                    "Amei este café":positivo\n                    "Não me agradou": negativo\n                    "{{review}}.":'}} | [NULL] |

Enter fullscreen mode Exit fullscreen mode

Aplicando a classificação

Agora que temos o modelo pronto e configurado, é hora de classificar nossos reviews. Faremos isso utilizando os comandos mais clássicos de SQL: SELECT e FROM 😊.

Relembrando o que queremos fazer, queremos classificar os reviews dos nossos cafés como neutro, positivo e negativo. Para nosso exemplo, acho legal mostrar primeiro qual é o sentimento e depois o comentário caso for necessário ler o comentário que recebeu aquela avaliação.

Então vamos para o nosso select:

SELECT m.sentiment, t.review         --campos que quero exibir na minha consulta
FROM mysql_sample.coffee_review AS t --tabela do DB que contem o review
JOIN mindsdb.coffee_review AS m;     --tabela que contém a previsão da IA
Enter fullscreen mode Exit fullscreen mode

Aqui fazemos um pequeno select usando join para obter o nosso sentimento e logo em seguida o review que teve aquela análise de nossa IA. Seu resultado deve ser o seguinte:

| sentiment | review                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| positivo  | Assim que eu levei a xícara aos lábios, parecia que eu estava num mercado de especiarias. O aroma floral e cítrico tomou conta e me deixou super curioso. No primeiro gole, senti uma explosão de sabores complexos: limão e bergamota, com um toque sutil de jasmim. A acidez brilhante equilibrada por uma doçura suave, quase como mel, foi incrível. A cada gole, o café ia mostrando mais camadas, deixando um gostinho refrescante na boca. É como uma dança de sabores no paladar, perfeito para começar o dia cheio de energia e inspiração.                        |
| positivo  | Desde que o espresso começou a sair, o cheiro rico e achocolatado tomou conta do lugar. O primeiro gole foi como um abraço quentinho - notas de chocolate amargo, nozes torradas e um toque de caramelo. A crema espessa dá uma textura cremosa, deixando tudo ainda mais gostoso. A doçura natural e o corpo encorpado desse blend são bem típicos dos cafés brasileiros. Cada gole traz uma sensação de conforto e familiaridade, perfeito para uma pausa à tarde ou um bate-papo com amigos.                                                                              |
| positivo  | Quando comecei a prensar o café na Prença Francesa, o cheiro doce e terroso começou a se espalhar pelo ambiente. No primeiro gole, já senti uma profundidade incrível: notas de frutas vermelhas, como cereja e amora, com um toque leve de cacau. A acidez suave e a doçura das frutas se equilibram perfeitamente, e a textura é super aveludada. Esse café me fez sentir super conectado com a natureza, como se eu estivesse saboreando os frutos direto da terra. É uma experiência revigorante e autêntica, perfeita para quem curte um café cheio de personalidade. |
| neutro    | Preparei esse café na máquina automática e o aroma que surgiu foi ok, nada demais. No primeiro gole, o sabor era simples e direto, sem muita complexidade. Tinha notas de nozes levemente tostadas e um toque sutil de chocolate ao leite. A acidez estava bem equilibrada e o corpo era médio, dando uma sensação satisfatória, mas sem impressionar. Esse café não tem nada de muito especial, mas é uma escolha segura pra quem quer um café consistente e previsível, sem grandes surpresas.                                                                           |
| negativo  | Ao coar esse café, o aroma foi bem fraquinho e nada convidativo. O primeiro gole foi uma decepção - um sabor raso e sem vida, com um amargor queimado que lembrava borra de café velha. A acidez estava desbalanceada e a textura era bem aquosa, deixando uma sensação desagradável na boca. Não havia qualquer traço de doçura ou complexidade para salvar a experiência. Cada gole foi um esforço para terminar a xícara, e fiquei frustrado e arrependido de não ter escolhido um café melhor.                                                                      |
Enter fullscreen mode Exit fullscreen mode

Pronto, temos todos nossos reviews classificados com o “sentimento”.

Ótimo!! mas e se formos um pouco além e melhorarmos esse select com outro modelo para termos acesso aos motivos que levaram esse comentário a expressar aquele sentimento? hehehe

Detalhando a classificação

Agora vamos melhorar um pouco mais nossa classificação e inserir os motivos para ela. Isso facilitaria, por exemplo, a vida de um executivo que não quer ficar horas lendo comentários para entender o que o seu cliente escreveu, mas quer otimizar o tempo indo direto para os principais motivos do que aconteceu. A famosa leitura dinâmica virando leitura eficiente 😀

Para facilitar nosso lado de “dev”, vamos criar outro modelo, onde diremos a ele para listar os principais motivos do sentimento por trás daquele review.

CREATE MODEL coffee_review_reasons
PREDICT reasons
USING
    engine = 'openai',
    model_name = 'gpt-4',
    prompt_template = 'liste resumidamente os principais motivos do sentimento: "{{review}}";';
Enter fullscreen mode Exit fullscreen mode

Como estamos acostumados, criamos o modelo com o nome coffee_review_reasons, onde ele vai ter o output na coluna reasons. No prompt, pedimos de uma forma direta para que ele liste resumidamente os principais motivos do sentimento; esse sentimento virá do nosso campo review que está em nosso DB.

Agora é só sentar e melhorar nosso select que acabamos de fazer, e como melhoraremos ele? Através de JOINS:

SELECT t.id, m.sentiment, m2.reasons 
FROM mysql_sample.coffee_review AS t
JOIN coffee_review_sentiment AS m
JOIN coffee_review_reasons AS m2
WHERE m.sentiment = 'negativo' OR m.sentiment = 'neutro'
Enter fullscreen mode Exit fullscreen mode

Para explicar esse nosso novo select: Primeiro dizemos que queremos exibir o id, o sentimento sentiment e os motivos reasons. Logo em seguida pegamos o review do nosso banco de dados, depois fazemos os JOINS com o primeiro modelo que é o coffee_review_sentiment e depois com o novo modelo coffee_review_reasons. Como acho que o que importa neste momento são apenas termos mais detalhes dos negativos e neutros, colocamos uma cláusula WHERE filtrando apenas por neutro e negativo. Mais uma análise completa!

Esse é o resultado de nossa análise final, com os cafés que têm sentimento negativo e neutro sobre eles e os principais motivos de terem tido este julgamento resumidos para nós:

| id | sentiment | reasons                                                                                                                                                                                                                                                                                                                                                                      |
|----|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 5  | negativo  | 1. Aroma fraco e não convidativo: O aroma do café é um dos primeiros indicadores de sua qualidade. Neste caso, o aroma fraco pode ter indicado que o café não seria satisfatório.2. Sabor raso e sem vida: Um bom café deve ter um sabor rico e complexo. O sabor raso e sem vida deste café foi uma grande decepção.3. Amargor queimado: O amargor                          |
| 4  | neutro    | 1. Aroma: O aroma do café preparado na máquina automática foi considerado apenas "ok", não se destacando de maneira especial.2. Sabor: O sabor do café foi descrito como simples e direto, sem muita complexidade. As notas de nozes levemente tostadas e um toque sutil de chocolate ao leite foram identificadas, mas não trouxeram um diferencial significativo.3. Acidez |

Enter fullscreen mode Exit fullscreen mode

Inserindo nossa consulta em uma nova tabela

Agora você deve estar se perguntando: “Poxa, mas como que eu salvo esses dados da análise?”. Bom, temos algumas formas de fazer isso; para facilitar nossa vida, que tal salvá-las no banco de dados em uma nova tabela?

Vamos criar essa tabela com a ajuda do SQL novamente e usando o CREATE TABLE. Então reescreva o último select que fizemos, mas agora vamos inseri-lo junto com o comando de criar uma nova tabela em nosso banco de dados:

CREATE TABLE mysql_sample.reviews_processed (
    SELECT t.id, m.sentiment, m2.reasons 
        FROM mysql_sample.coffee_review AS t
        JOIN coffee_review_sentiment AS m
        JOIN coffee_review_reasons AS m2
        WHERE m.sentiment = 'negativo' OR m.sentiment = 'neutro'
);
Enter fullscreen mode Exit fullscreen mode

Dessa forma, garantimos que temos um registro salvo e não precisamos ficar reprocessando a nossa análise toda vez que quisermos consultar o que os clientes estão achando de nossos cafés.

E assim terminamos nosso sistema de análises de reviews sobre cafés e podemos tirar os cafés menos desejados de nosso cardápio 🥰

Benefícios da analise

A análise de sentimento é uma ferramenta poderosa que permite entender as opiniões e emoções dos clientes em relação a produtos ou serviços. No contexto de uma loja de café, como exemplificado no artigo, a implementação de uma IA para realizar essa análise pode trazer inúmeros benefícios estratégicos, como por exemplo:

  • Melhoria da Experiência do Cliente: permite uma resposta rápida às críticas dos clientes, ajudando a resolver problemas antes que eles se tornem amplamente conhecidos e afetem a reputação da marca.
  • Tomada de Decisões Baseada em Dados: com insights sobre quais produtos são mais apreciados e quais não agradam, a empresa pode tomar decisões informadas sobre quais itens manter, modificar ou remover do cardápio.
  • Vantagem Competitiva: negócios que utilizam a análise de sentimento conseguem se adaptar rapidamente às mudanças nas preferências dos consumidores, mantendo-se à frente da concorrência, podendo inovar de maneira contínua.

Entre outros que não citei aqui, mas hoje em dia o produto mais valioso que temos em mãos são os dados, então devemos dar um carinho especial para eles.

Conclusão

A combinação do MindsDB e Docker revoluciona a maneira como integramos IA e machine learning em nossos projetos, tornando todo o processo incrivelmente simples e acessível. Com o MindsDB, desenvolvedores podem criar e implementar modelos de aprendizado de máquina usando apenas SQL, eliminando a necessidade de aprender novas linguagens de programação complexas. Docker, por sua vez, facilita a implantação dessas tecnologias, permitindo que várias dependências sejam gerenciadas de forma eficiente através de containers. Essa sinergia não só acelera o desenvolvimento e a implementação de soluções de IA, mas também reduz significativamente a complexidade operacional, permitindo que negócios de todos os tamanhos aproveitem o poder da IA para melhorar a experiência do cliente e impulsionar o crescimento.

Top comments (1)

Collapse
 
ajeetraina profile image
Ajeet Singh Raina

What if I tell you that you can save a lot of your time deploying MindsDB as a Docker Extension. Just a click and you get the full-fledge MindsDB running on your Docker Desktop.

Check out this blog post docker.com/blog/mindsdb-docker-ext...