Entendendo de vez a convolução: base para processamento de imagens

Quem tem a formação em áreas como engenharia, estatística ou matemática, no mínimo tem uma ideia do que é uma convolução, pois essa técnica é muito utilizada para se criar filtros digitais em processamento de sinais, definição de correlação em estatística, etc.

Atualmente ouve-se muito o termo convolução na área de Inteligência Artificial, especificamente no Aprendizado de Máquina, que utiliza processamento de imagens como pré-tratamento para classificar ou extrair informações relevantes. 

Mas afinal que é convolução?

Convolução é simplesmente uma operação de somatório do produto entre duas funções, ao longo da região em que elas se sobrepõem, em razão do deslocamento existente entre elas. Na teoria, o cálculo da convolução contínua é dada pela integral deste produto, desde que as funções sejam integráveis no intervalo:

Na computação, utiliza-se o cálculo discreto, que realiza um somatório do produto:

 

 

Quando se trata de utilizar a convolução em processamento de imagens para Inteligência Artificial, são necessários dois somatórios pois temos duas dimensões – altura e largura:

Neste caso a convolução tem o papel de fazer uma filtragem para extração de informações de interesse na imagem. Mais especificamente, o uso de filtros espaciais lineares é feito através de matrizes denominadas máscaras ou kernels – como são mais conhecidos na prática.

Dependendo da dimensão e dos valores presentes nessa matriz ou kernel, é possível se obter características diferentes nas imagens como: suavização, deslocamento, contraste, bordas, texturas, remoção de ruídos, dentre outras.

Durante a aplicação da convolução em uma imagem, o kernel vai se deslocando ao longo da imagem, como uma janela móvel, que vai multiplicando e somando os valores sobrepostos, segundo um número de passos determinados, conhecidos por stride.

Para facilitar o entendimento, vamos considerar uma imagem de 32x32x3, onde a altura e a largura têm 32 pixels, com 3 canais de cores – que é a profundidade da matriz. Suponha um kernel de 5x5x3, onde a altura e a largura têm 5 pixels, com obrigatoriamente a mesma profundidade da imagem – que é 3. Deslizando-se o kernel sobre toda a área da imagem, considerando um stride igual a um, teremos uma matriz convoluída de tamanho 28x28x1, pois a cada passo, é calculado o somatório do produto de todos os valores sobrepostos resultando em um único valor:

Para uma imagem NxN, um kernel FxF, e com passo S, o resultado da convolução será uma matriz GxG tal que:

Com este exemplo, fica fácil perceber que a matriz convoluída será menor que a imagem original, e mesmo ajustando-se o stride igual a um, não será possível cobrir os pixels da borda da imagem original. Para resolver este problema, é usual a inclusão de mais pixels nas bordas da imagem original, com a quantidade P tal que:

Esse preenchimento é chamado de padding, e pode-se preencher com zeros, para se minimizar o efeito de redução rápida de dimensionalidade espacial da imagem convoluída. Agora, considerando a mesma nomenclatura do exemplo anterior, pode-se calcular o tamanho GxG da matriz convoluída incluindo o padding, tal que:

 

No contexto de redes neurais convolucionais (as CNNs), utiliza-se uma coleção de kernels ou agrupamento de filtros. Essa coleção é conhecida como camada convolucional. No exemplo visto anteriormente, onde a convolução resultou em uma matriz 28x28x1, aplicando-se seis kernels 5x5x1, a saída será uma matriz 28x28x6, ou seis mapas de ativação – como também é conhecido na prática.

Vejamos outro exemplo, agora utilizando padding: de acordo com a fórmula explicada anteriormente, para filtros 5×5, utilizaremos um padding de valor 2, preenchendo uma imagem de 32x32x3 com 2 camadas de zeros acima, abaixo e nas laterais. Aplicando-se uma primeira convolução com seis filtros 5x5x3, obtém-se uma imagem de 32x32x6. Após uma segunda convolução com dez filtros 5x5x6, obtém-se uma imagem de 32x32x10, e assim por diante. Com esse exemplo verifica-se que as dimensões altura e largura da imagem de entrada não se alteram.

Este texto é a base para o próximo artigo, onde veremos mais detalhes sobre as camadas de uma rede neural convolucional. Gostou? Então visite nosso Instagram e fique por dentro de mais conteúdos ou fale com um especialista da Viceri

Aplicações Serverless: quais as vantagens de usar esta arquitetura?

Neste texto vamos falar sobre aplicações serverless, o que são e quais as vantagens de usar esta arquitetura. O principal ponto de uma Arquitetura Serverless, é propiciar que empresas de software criem e mantenham aplicativos web sem se preocupar com a infraestrutura em que eles estão funcionando. Mas antes de entrar neste tema, vamos recapitular algumas coisas que já falamos aqui no blog e falar sobre as arquiteturas existentes.  

Arquitetura Monolítica

Arquitetura Monolítica é quando uma única aplicação de software em camadas contém a interface do usuário, as regras de negócio e código de acesso a dados. Tudo isso são combinados em apenas um único programa e uma única plataforma. Então, uma aplicação monolítica é autônoma e independente de outras aplicações.

É uma arquitetura simples de desenvolver, simples de testar e de implementar, porém, tem também suas desvantagens. É difícil de escalar: quando você precisar escalar essa aplicação ou fazer com que ela tenha maior disponibilidade, precisa escalar a aplicação inteira. Isso se torna inviável, o custo fica muito alto, e conforme essa aplicação cresce, complica a manipulação. Depois disso vieram os microsserviços, para solucionar esses problemas.

Arquitetura de microsserviços

A Arquitetura de Microsserviços é uma arquitetura de software diferente do monolito, no qual sistemas grandes e complexos são transformados em componentes individuais. Eles são quebrados e cada um fica espalhado com sua responsabilidade. As vantagens dos microsserviços são a sua escalabilidade distribuída, ou seja, não é preciso crescer a aplicação inteira para solucionar um problema, podemos escalar apenas recursos específicos. Deploys mais rápidos e não ficamos presos a uma linguagem de programação.

Ou seja, se quisermos fazer um componente em java, um outro componente em C# (C Sharp), podemos porque eles são diversas soluções com pequenas responsabilidades. As desvantagens dos microsserviços são: a complexidade de se manter, e se os serviços não forem bem definidos, viram uma bagunça.

◼️ Leia também: Como transformar seu monolito em microsserviço 

Iniciamos falando dessas arquiteturas porque elas enfrentam um problema ainda com o gerenciamento e controle de servidores, ou seja, você precisa de um servidor em funcionamento para que a aplicação continue em funcionamento, independente se está em uso ou não. Os microsserviços já solucionam muitos problemas em relação a escalabilidade, porém, ele ainda não solucionou o problema da ociosidade, ou seja, se o microsserviço está ativo, ele está ocupando recursos gerando custos mesmo em ociosidade.

Arquitetura Serverless

Então, aí entra a Arquitetura Serverless. Embora o seu nome signifique “sem servidor”, na tradução literal, não é bem assim que funciona. A aplicação continua funcionando em um servidor, porém o gerenciamento do servidor ficará por conta de um provedor de nuvem. Um desenvolvedor não precisará se preocupar com configurações relacionadas a infraestrutura em que sua aplicação irá funcionar. Essas decisões ficarão por conta da nuvem.

BaaS (Backend as a Service)

Existem algumas formas de construir aplicações serverless. Vamos tratar sobre BaaS (Backend as a Service). Backend as a Service é uma plataforma que automatiza o desenvolvimento de backend e gerencia a infraestrutura na nuvem. Com o BaaS você precisará apenas focar em desenvolvimento no core do seu sistema. O Backend as a service possui um conjunto de recursos para agilizar o desenvolvimento como APIs, integração com mídia social, armazenamento de arquivos e notificações push. 

E quais são as razões para utilizar o Backend as a Service? O objetivo do BaaS é de reduzir o tempo total de desenvolvimento da aplicação, dando velocidade ao desenvolvimento de um sistema e reduzindo custos. Você foca apenas no core do sistema se preocupando apenas com a necessidade real do seu cliente. E por ser serverless, não tem gerenciamento sobre infraestrutura, isso fica por conta do Backend as a Service.

FaaS (Function as a Service)

Além do BaaS existe também o FaaS, ou Function as a Service. É um modelo de execuções de funções orientados a eventos executado em containers stateless, ou seja, não armazena dados, apenas os processam. Simplificando um pouco, FaaS é uma maneira de executar funções de negócio acionadas por um determinado evento.

Quais as vantagens de usar FaaS? Um dos principais motivos para utilizar FaaS, é seu modelo de cobranças, as cobranças são feitas em relação ao tempo de processamento dessas funções, ou seja, caso elas estejam ociosas, não será cobrado valor algum, diferentemente das arquiteturas monolítica e de microsserviços que precisam de servidores e clusters ativos para mantê-los ativos mesmo sem uso.

Agora que sabemos de serverless, abaixo vou citar algumas ferramentas que possibilitam a construção de uma arquitetura onde não precisaremos nos preocupar com infraestrutura.

AWS Lambda

O AWS Lambda é a ferramenta de FaaS da AWS no qual permite executar código backend sem precisar provisionar ou gerenciar servidores cobrando apenas pelo tempo de processamento das funções.

Google Firebase

O Google Firebase é a ferramenta de BaaS da Google. Com ele é possível agilizar o desenvolvimento de sistemas web ou mobile. No Firebase temos a possibilidade de facilitar o envio de notificações push, ter uma análise do comportamento dos usuários do seu aplicativo utilizando o Firebase Analytics e com o Firebase Authentication é possível fazer o controle de autenticações do seu sistema de uma forma segura e dinâmica. Essas são algumas das ferramentas que o Firebase possui para agilizar o desenvolvimento backend do seu sistema e, claro, tudo isso sem gerenciar infraestrutura.

S3

O S3 é uma ferramenta da AWS para armazenamento de objetos. Tem uma interface simples e você consegue armazenar e recuperar qualquer quantidade de arquivos. Sua precificação fica por conta da quantidade de arquivos armazenados nessa plataforma, ou seja, será pago apenas pelos arquivos armazenados.

DynamoDB

O DynamoDB é um serviço de banco de dados nosql, que possui uma capacidade escrita e leitura muito rápida e segura, e é totalmente gerenciado com segurança e backups. Sua precificação pode ser controlada de duas maneiras, em uma delas, é cobrado por leituras e gravações que a aplicação faz nas tabelas, não será necessário especificar uma taxa de transferência para essas execuções, pois o Dynamo irá se ajustar de acordo com a demanda. E no outro modo é possível especificar a taxa de transferência da sua aplicação e seu custo pode ser controlado.

Amazon API Gateway

O API Gateway é um serviço que permite desenvolvedores criar APIs REST (Representational State Transfer) totalmente escalável e distribuído sem ter que cuidar de infraestrutura. Sua precificação fica por conta do número de chamadas que suas APIs recebem e quantidade de dados que são transferidas.

Para concluir, vimos que com a arquitetura serverless é possível ter as vantagens da escalabilidade e a computação distribuída, sem necessidade de provisionamento e gerenciamento de infraestrutura, e o custo da sua aplicação será proporcional a sua utilização.

Gostou deste conteúdo? Confira outros conteúdos no nosso Instagram ou fale com um de nossos especialistas

Integrando chatbot Rasa com outras aplicações

Já falamos aqui anteriormente sobre o Rasa. No artigo anterior fizemos um resumo geral e agora vamos aprofundar, focando especificamente na integração com outros sistemas, ou seja, como fazer o chatbot entender uma conversa e buscar informações em uma base de dados. Neste texto, vamos lembrar alguns termos que foram apresentados e que precisamos que estejam claros.  

Intenção (Intent): é o que o chatbot acha que você está querendo dizer. A partir de uma lista de exemplos que são treinados no chatbot é criado um modelo. Com esse modelo o Rasa vai tentar prever ou predizer o que o usuário está querendo falar.

Ação Personalizada (Custom Action): é possível escrever rotinas para fazer uma consulta num banco de dados, cálculos, relatórios, logs, enfim, qualquer coisa que possa ser feita num programa, e ainda acessar informações sobre a conversa, como interações anteriores com o chatbot. As ações personalizadas são escritas em Python.

Entidade (Entity): é uma parte variável da frase que pode ser considerada uma informação distinta. Isso parece confuso, então vamos dar um exemplo: Se tivermos uma intenção tipo “quais os hospitais em tal cidade?”, o “tal cidade” é uma entidade. Mesmo se a cidade fosse diferente de uma pergunta para outra, isolamos essa informação e fazemos uma busca para os hospitais da cidade especificada. 

Do mesmo jeito, uma frase do tipo “quais as minhas reuniões para tal dia?”, esse “tal dia” seria uma entidade. Uma entidade pode ter vários formatos. No caso do “tal dia” pode ser “quais as minhas reuniões para a próxima quarta”, “quais as minhas reuniões para o dia 10 de setembro”, ou ainda “quais as minhas reuniões para amanhã”. Em todos esses casos a entidade “data” é extraída da frase, e passada para uma ação personalizada para recuperar as informações daquele dia.

Slot: Não tem uma palavra específica no português, mas seria “ranhura” ou “fresta”. Imagine uma caixinha de correspondência que tem uma fresta por onde você pode passar uma folha de papel com um texto escrito. No Rasa, slots são usados para guardar informações no decorrer da conversa, que podem ser consultadas depois. Essas informações são guardadas nestas caixinha ou slots. Na programação tradicional o equivalente seriam as variáveis. Uma variável tem um nome e um valor, e um slot, do mesmo jeito, tem um nome e um conteúdo. Um slot pode ser de dois tipos básicos: um valor que não interfere no fluxo da conversa (que pode guardar qualquer tipo de informação); ou um valor que pode alterar o fluxo da conversa.

Como assim “interfere no fluxo da conversa”?

Se temos um slot com o sexo do usuário, quando ele (ou ela) escrever “como vai?”, podemos desviar uma conversa de acordo com o conteúdo desse slot, mostrando respostas diferentes para cada caso. Se for um homem mostramos “Eu vou bem, e o senhor, como está?” e se for uma mulher respondemos “Eu vou bem, e a senhora, como está?”. Dentro do tipo que interfere no fluxo da conversa, temos tipos específicos de slot: podemos ter slots numéricos, de texto, lógicos (tipo verdadeiro ou falso) ou categóricos (onde temos uma opção dentro de uma lista de possibilidades). Um exemplo de slot categórico seria sexo: masculino, feminino ou não informado.

Mas um detalhe, mesmo sendo do tipo que interfere no fluxo da conversa, somente conseguimos analisar o conteúdo do slot quando se trata de um slot categórico. Para os outros tipos só sabemos se tem algo no slot, ou se está vazio.

Podemos alterar o conteúdo de um slot de várias formas: preencher automaticamente com a informação extraída de uma entidade com o mesmo nome, mandar diretamente um valor para um slot através de uma API, ou alterar dentro de uma ação personalizada.

Observe que podemos usar a mesma entidade para preencher vários slots! Vamos supor que seja para calcular a área de um retângulo, onde área é igual a altura vezes a largura. Uma entidade “comprimento” pode ser ora a altura, ora a largura. E qual valor dependerá da conversa em si.

Resposta (ou Response): É uma frase que o chatbot irá responder para o usuário. Pode ser só um texto ou pode conter slots no meio da frase. Por exemplo, se temos uma frase de bom dia, e um slot contendo o nome do usuário, podemos colocar essa informação no meio da frase e falar “Bom dia, João” ou “Bom dia, Paulo”. Podemos cadastrar várias frases diferentes, e neste caso, o chatbot irá escolher aleatoriamente uma das respostas, e com isso tornamos as conversas mais humanas e menos fixas.

Respostas também podem conter botões. Definimos os botões, o que deve aparecer no botão, e se o usuário clicar em um desses botões será enviada a frase programada no botão para o chatbot.

Formulário (Form em Inglês): definimos um ou mais slots obrigatórios, e então o formulário age como se fosse uma “trava” na conversa, permitindo apenas que o usuário siga adiante caso todos esses slots estejam preenchidos. Podem ser preenchidos com qualquer texto que o usuário digitar, ou a partir de entidades extraídas de diálogos que o usuário escrever. Formulários são programados em Python, assim como ações personalizadas. Devemos ter frases resposta específicas para solicitar cada um dos slots que ainda não foram preenchidos.

Vamos ver um exemplo disso: se temos uma conversa que vai mostrar quais são os hospitais da minha cidade, eu não posso prosseguir na conversa até que o slot contendo o nome da cidade esteja preenchido. Neste caso, o formulário vai olhar o slot, e se não estiver preenchido, vai disparar a frase “Em que cidade?” e esperar a pessoa digitar o nome da cidade.

Podemos validar o nome da cidade dentro do formulário, e caso não seja um nome válido, pedimos novamente. Somente depois que o usuário digitar uma cidade válida é que seguimos e fazemos a consulta num banco de dados para mostrar quais os hospitais cadastrados para aquela cidade.

Estória (ou Story): é a cola que junta todos esses pedaços. É uma sequência de intenções, respostas, formulários ou ações do chatbot que vai dar forma à conversa. A forma mais simples de uma estória é uma intenção e uma resposta, que vai criar o seguinte comportamento: se o usuário digitar determinada coisa, responde com tal coisa. 

Estórias mais complexas usam ações personalizadas e formulários para enriquecer a experiência do usuário. Todas essas informações ficam distribuídas em vários arquivos. Temos o arquivo de configuração, config.yml, onde ficam os parâmetros de treinamento, e qual a sequência de módulos que serão usados para interpretar o texto e treinar o modelo.

Temos o domain.yml contendo uma lista de todas as ações (ações personalizadas e respostas do chatbot), intenções, entidades e slots, além de todos os textos de respostas que o chatbot deve mostrar. Dentro de uma pasta chamada data colocamos as estórias e as frases de exemplo para o treinamento do chatbot, sendo que temos a opção de organizar melhor os arquivos, colocando em duas subpastas: data/core (para as estórias) e data/nlu (para as frases de exemplo).

Na Viceri desenvolvemos uma ferramenta para administrar o chatbot com mais facilidade, permitindo que através de uma aplicação web, você consiga gerenciar todas essas informações.

Depois de conhecer estes termos, nos próximos artigos vamos entrar mais nos detalhes da programação e dar exemplos mais detalhados de como se encaixa tudo isso.

Ficou interessado em saber mais sobre o assunto? O time da Viceri tem especialistas que podem ajudar você a encontrar as respostas que precisa. Entre em contato com a gente!

Formatos de dados necessários para treinar seu chatbot

Antes de começar a ler este artigo, é importante que você esteja familiarizado com alguns termos e explicações que demos em outros textos anteriormente. Por isso, leia também Integrando chatbot Rasa com outras aplicações e RASA: Conheça o software em python utilizado para criação de chatbots.

Neste artigo vamos começar a examinar os formatos de dados necessários para você treinar seu chatbot. Basicamente, o treino vai pegar informações de NLU (que é a compreensão de linguagem natural – Natural Language Understanding), dados de estórias (fluxos de conversa), e o arquivo de domínio (respostas do chatbot e organização das conversas) e vai aplicar o processo definido no arquivo de configuração. Então temos:

NLU + Estórias + Domínio -> Config -> Modelo

O RASA espera que os arquivos estejam organizados da seguinte forma: Domain.yml e config.yml na pasta “raiz”. NLU e estórias (com extensão .md) na subpasta “data”. Você também pode criar duas subpastas dentro de “data” (chamados “core” e “nlu”) e colocar os arquivos dentro das respectivas subpastas. Caso não for fazer isso, o arquivo com NLU deve se chamar nlu.md e o arquivo de estórias, story.md.

Se você separar nas subpastas “data/nlu” e “data/core”, pode dividir os exemplos e estórias por assunto e separar em vários arquivos, com qualquer nome desde que estejam nas pastas corretas.

Os arquivos Domain e Config são no formato yml e os arquivo de exemplo (nlu) e estórias (core) são no formato md (de markdown). Numa versão próxima do RASA provavelmente todos os arquivos serão no formato yml, mas aqui vamos ver o formato atual, md.

Para você começar com um conjunto de arquivos base, pode executar o comando “rasa init”, mas cuidado: isto vai limpar dados que já existirem na pasta onde você executar o comando.

O arquivo domain.yml

O arquivo domain é dividido em várias “seções”: Declaração de intenções; Declaração de ações; Declaração de entidades; Declaração de slots; Respostas do chatbot; Dados sobre seção do usuário.

Veja os exemplos de cada seção

Cada seção começa com uma linha com o nome da seção seguido de dois pontos. Vamos ver um exemplo da seção de intenções:

intents:
– saudação
– despedida
– feliz
– triste

Observe que cada nome de intenção começa com um – e um espaço. Isto tem de ser obrigatoriamente dessa forma. Todas as intenções que for usar nas conversas devem estar relacionadas aqui. Logo mais vamos ver melhor como define uma intenção, mas por enquanto basta saber que uma intenção é composta de um nome e vários exemplos. Aqui colocamos o NOME. Deve estar escrita exatamente da mesma forma que no arquivo NLU.

Para nomes de ações, intenções, slots e entidades, recomenda-se usar apenas as 26 letras do alfabeto (sem acentos) e números de 0 a 9 e o underscore (símbolo do sublinhado), sempre começando com uma letra. Use nomes que têm a ver com o assunto, como procura_hospital, escolher_filmes e assim por diante. Não há limite para o comprimento do nome, mas nomes compridos demais podem dificultar na hora de digitar o nome.

Depois de listar todas as intenções, vamos colocar as ações, que podem ser ações personalizadas ou então respostas do chatbot.

Um exemplo da seção de ações está abaixo:

actions:
– utter_saudacao
– utter_despedida
– utter_alegrar
– action_busca_hospital

Temos o nome da seção “action”, seguido de dois pontos, e cada uma das ações na sua linha, começando com hífen seguido de espaço. Repare como separamos as palavras com sublinhado (_). Os nomes não podem conter espaços, então use o sublinhado (_) para separar as palavras. Não junte tudo (comoAlgumaLinguagensDeProgramacaoFazem), e dê nomes que tem a ver com o que a ação faz.

Por padrão, uma resposta do chatbot começa com “utter” que quer dizer “falar” ou “expressar”. Pronuncia-se “a-ter”. A pronúncia correta é essencial. Se você for falar “u-ter” com qualquer estrangeiro, ele não vai entender do que está falando e provavelmente achar engraçado. Existem alguns nomes “padrões” para utter que veremos quando formos falar a respeito de formulários.

Assim como uma resposta do chatbot começa com “utter”, uma ação personalizada por padrão começa com “action”.

Depois de listar todas as ações do seu projeto, vamos definir as entidades e os slots.

Veja um exemplo de seção de entidades:

entities:
– grupo
– cor
– cidade

Entidades são informações que serão extraídas de frase. Um exemplo seria extrair a cor da frase “Estou procurando uma caixa verde”.

Na parte onde formos falar de NLU (exemplos para o chatbot) falaremos mais sobre entidades. Por enquanto, basta saber que você atribui um nome a uma entidade. Se não tiver nenhuma entidade a ser extraída de frases, não é necessário ter uma seção de entidades no domain.

Depois de declarar entidades, deve declarar os slots. Caso queira que o slot seja preenchido automaticamente por uma entidade, basta defini-lo com o mesmo nome.

Um exemplo de seção de slots:

slots:
nome:
type: unfeaturized
perfil:
type: categorical
values:
– anonimo
– basico
– vip
descricao:
type: unfeaturized

Na hora de declarar os slots, você precisa informar o tipo, que pode ser:

Text: irá guardar uma informação texto;
Boolean: irá guardar uma informação verdadeiro/falso;
Categorical: irá guardar a seleção entre uma lista de possibilidades (sexo masculino, feminino ou não informado);
Float: irá guardar uma informação numérica;
List: irá guardar uma lista de valores;
Unfeaturized: este é o ÚNICO tipo que não influencia no fluxo da conversa.

Para todos os tipos exceto unfeaturized, boolean e categorical, só é possível saber que há um valor no slot, mas não comparar com outros valores. O unfeaturized, por definição, não influencia no andamento da conversa. É possível verificar o valor de um slot categórico ou boolean e influenciar no andamento da conversa.

No domain também declaramos formulários da mesma forma:

forms:
– registro_form

A Viceri desenvolveu uma ferramenta que você pode usar para criar estes arquivos automaticamente, sem se preocupar com a formatação das informações. Basta preencher os exemplos com as frases que o chatbot irá falar, montar as conversas de uma forma interativa, e a partir de um painel administrativo solicitar para treinar um modelo.

Nos próximos artigos continuaremos vendo como declarar respostas ao usuário no arquivo domain.yml, e como são formatados os arquivos de exemplos (NLU) e estórias. Gostou?

Confira nossos próximos posts ou fale agora com o time da Viceri. Estamos sempre prontos para auxiliar você sempre que precisar.

Analista de dados: os objetivos e competências de um bom profissional

“Mas, após observação e análise, quando você achar que alguma coisa concorda com a razão e é condutora para o bem e benefício de todos, aceite-a e cumpra-a.”

Gautama Siddharta, também conhecido como Buda, 563-483 A.C.

Ciência de dados é um campo interdisciplinar que usa métodos científicos, processos, algoritmos e sistemas para extrair conhecimento e insights de dados. Como sabemos, ela lida com dados quantitativos e qualitativos, onde aplicamos essencialmente quatro tipos de análise: descritiva, diagnóstica, preditiva e prescritiva. O fato de ser interdisciplinar nos indica que ela envolve a combinação de mais de uma disciplina acadêmica dentro da mesma atividade. 

Por ser uma área extensa, permitiu a criação de várias especializações de carreiras existentes anteriormente. Muitos desconhecem que para cada tipo de tarefa temos profissionais com perfis e conhecimentos específicos. Nesse texto vamos focar no Analista de Dados, indicando quais são as competências esperadas e seu limite de atuação. Em uma publicação futura detalharemos cada uma das posições existentes dentro de um time focado em dados.

Quais as competências de cada profissional dentro de um time?  

Antes do profissional, vamos falar da análise de dados em si: as empresas tendem a coletar todos os dados possíveis relacionados ao seu negócio, já que as expectativas dos clientes são cada vez mais altas e a competição acirrada continua em crescimento. A análise desses dados podem contribuir para que essas organizações possam ser proativas, antecipando as necessidades, otimizando a experiência de seus usuários e entregando produtos e funcionalidades relevantes, os quais podem permitir a construção de um relacionamento entre a marca/produto e seus clientes. 

Baseado em fatos, podemos tomar decisões de negócio mais rápidas, ter consciência de riscos e capacidade de reação a mudanças do mercado, além de insights sobre o desempenho da empresa, reduzindo custos e aumentando lucros. Mas quais são os profissionais que, em termos de ciência de dados, podem auxiliar os tomadores de decisão a realizar essas análises em um curto espaço de tempo?

O primeiro profissional que sempre vem em mente é o cientista de dados, com domínio em machine learning, estatística e análise. Altamente qualificado, este profissional 3 em 1 tem alto custo, o qual muitas vezes não se justifica sem uma sólida estrutura e cultura de dados estabelecida nas organizações. Outros especialistas de domínios específicos podem ser essenciais para alcançarmos os objetivos desejados. Mas quais habilidades e competências eles devem ter? Existe uma tendência em procurar profissionais com expertise em inteligência artificial e machine learning, ou estatísticos, devido à sua longa reputação de rigor e superioridade matemática – ambos inegáveis. Mas e os analistas?

O que os menos envolvidos na área por vezes não entendem é que, apesar de estarem sob o mesmo guarda-chuva, esses profissionais são diferentes, mesmo utilizando os mesmos métodos algumas vezes. Cada um deve ser encorajado a dominar amplamente sua área de atuação. Estatísticos sempre prezam pelo rigor, engenheiros de machine learning pelo desempenho, e analistas pela velocidade. Os melhores analistas são velozes em vasculhar um dataset, identificando potenciais insights antes dos outros profissionais citados; isso não deve ser considerado como um demérito para eles já que, como citado, os objetivos são diferentes. 

Estatísticos, ao prezarem pelo rigor, garantem as conclusões obtidas de seus dados, não permitindo que você se engane. Não há espaço para inferências aqui: os métodos aplicados são os corretos para o problema apresentado. Engenheiros de machine learning, ao prezarem pelo desempenho, desenvolvem modelos resilientes, precisos e de rápida resposta aos seus acionamentos. O que ambos têm em comum é o fato de que são soluções de alto esforço para problemas específicos: se os problemas apresentados não valerem o custo de serem solucionados, a empresa acaba perdendo tempo e dinheiro.

O que faz um bom analista de dados? 

Bons analistas são um pré-requisito para sua empreitada com dados. Além da velocidade, eles têm a habilidade de identificar informações potencialmente úteis e apresentá-las em formato gráfico efetivo, revelando o antes desconhecido aos tomadores de decisão e inspirando-os a selecionar os problemas que valem a pena serem enviados aos estatísticos e engenheiros de machine learning. Os bons analistas podem ser considerados então como contadores de histórias dos dados.

Um ponto de destaque em relação aos analistas de dados é a sua regra de ouro: não chegue a conclusões através de seus dados. Apesar de soar estranho, essa regra deixa claro que o resultado de seu trabalho deve inspirar os interessados a explorar todas as possibilidades de interpretação de cada insight, elaborando hipóteses que possam ser testadas pelos estatísticos. Outro aspecto interessante dessa regra é que ela indica que a comunicação do resultado do trabalho realizado pelos analistas deve ser clara o suficiente para que não entendam um insight como uma conclusão.

O domínio de negócio também é algo extremamente relevante para os analistas de dados, não sendo algo essencial para engenheiros de machine learning e estatísticos. Por causa dessa expertise, eles podem auxiliar a identificar padrões rapidamente em seus dados e explorar diversos ângulos do mesmo assunto, antes mesmo de levar as informações para os tomadores de decisão. 

Podemos dizer que, numa ordem de prioridade na montagem de um time de dados, o analista vem antes dos outros profissionais citados, gerando insumos para eles e tendo uma importante função junto aos tomadores de decisão.

Gostou da nossa explicação? A Viceri tem um time completo de especialistas sempre dispostos a ajudar sua empresa a chegar mais longe. Entre em contato com a gente

LGPD: O cenário de insegurança jurídica durante a pandemia

Fica muito difícil não relacionarmos este tempo pandêmico com um cenário de insegurança jurídica em torno da Lei Geral de Proteção de Dados,  a LGPD. No artigo anterior, já tínhamos abordado sobre a dificuldade das empresas nos processo de adequação. Não só aspectos econômicos em tempos de crise, mas também as preocupações técnicas em relação a prazos e sobre quais as medidas os governos e instituições de saúde têm tomado para tratar dados com segurança neste período. E para entendermos um pouco melhor este momento que o Brasil vive, precisamos compreender também o que está sendo debatido entre o Governo Federal e o Senado. 

Em agosto de 2018 tivemos a promulgação da Lei nº 13.709, a Lei Geral de Proteção de Dados, com previsão de vigência para agosto de 2020. Por conta do cenário de pandemia, o Senado recebeu o plano de Lei nº 1179/2020 com a sugestão de um regime emergencial. Na primeira votação os senadores decidiram pelo adiamento da vigência da LGPD para janeiro de 2021, com aplicabilidade de multas a partir de agosto do mesmo ano. 

Antes da conclusão e sanção do plano de Lei nº 1179/2020, o executivo editou a Medida Provisória 959/2020 que tratava também do adiamento da vigência da LGPD para maio de 2021. Essa medida provisória entrou em vigor em abril de 2020 e deve ser convertida em lei, após votação do Congresso Nacional, até 27 de agosto deste ano. Caso contrário, ela simplesmente deixa de existir. Porém, uma nova votação aconteceu na Câmara dos Deputados para o plano de Lei nº 1179/2020 que eliminou a tratativa da prorrogação da vigência da lei, mantendo apenas a prorrogação dos recursos punitivos para agosto de 2021. 

Que confusões essas mudanças podem causar? 

Então, diante de todas essas informações, podemos entender que a Medida Provisória nº 959/2020 precisa ser convertida em lei até 27 de agosto de 2020 para que a data de vigência inicial da LGPD seja postergada para maio de 2021. Ou então, voltamos à data inicial prevista antes da pandemia, 16 de agosto de 2020. Sabemos que esse assunto tão importante segue em discussão e não podemos deixar de mencionar os impactos que isso traz para todo o país. 

O certo é que a Lei Geral de Proteção de Dados é extremamente relevante para o Brasil, e é importante desde a sua promulgação, em 2018. Sua relevância demonstra que o país está preocupado em fazer um tratamento de dados dos titulares de forma transparente. Traz também a credibilidade no que diz respeitos aos direitos humanos e aos requisitos de segurança digital. 

Porém, o país tem um grande entrave, um grande gerador de insegurança jurídica: a ausência da criação da ANPD, a Autoridade Nacional de Proteção de Dados. Ela vai ser responsável, dentre várias funções, por fiscalizar e aplicar a lei. A nomeação ainda não ocorreu por conta de dependência da agenda do executivo e orçamento. Além da aprovação e indicação dos responsáveis. 

De acordo com Patrícia Peck, advogada especialista em Direito Digital e PHD em Direito Internacional e Propriedade Intelectual, não adianta prorrogar a vigência da lei sem que se tenha um compromisso de, nesse período de transição, criar a Autoridade Nacional de Proteção de Dados.

O país não pode simplesmente decidir uma vigência de lei e começar a aplicabilidade de multas na sequência, sem que se tenha a preocupação com o protocolo de conduta. A ANPD, antes da vigência da LGPD, precisa articular com as instituições e com a sociedade, estabelecer metodologias, promover campanhas educativas, responder a consultas públicas, regulamentar artigos que ainda ficaram abertos para discussão, para evitar que haja uma interpretação confusa da legislação.

Ou seja, é uma lei de alto impacto que precisa ser tratada com a sua devida importância. Alguns especialistas, inclusive, acreditam que vai ser preciso ao menos seis meses para que a ANPD tenha recursos suficientes para começar a sancionar. 

Quer saber mais sobre a nova Lei Geral de Proteção de Dados? Acesse o nosso whitepaper especial “Tudo sobre a LGPD” e confira vários conceitos e dicas para adequar o seu negócio à nova legislação!

O que vem pela frente? 

Estamos diante de uma mudança de vício de consentimento. A partir de agora tudo vai ter que ser muito mais claro, mais transparente, sem letras miúdas ou interpretações dúbias. Todo o tratamento de dados tem que ter um objetivo, um princípio. Por isso hoje mais de 120 países estão regulamentando as suas leis de privacidade. Além disso, estamos em tempo de cloud computing, o que torna a proteção e a confidencialidade dos dados muito mais importante.

As empresas precisam determinar quais serão os dados levados para nuvem, por exemplo. São dados pessoais? São dados pessoais sensíveis? A preocupação com os riscos e a segurança, desde a criptografia dos dados em movimento e armazenados, até com quem os acessa, deve ser base para adequação à lei. Mesmo que ainda haja discussão sobre data de vigência, sobre a criação da ANPD, sobre quando começar com os recursos punitivos, e sobre os impactos da pandemia na LGPD, o fato é que já estamos em tempo de lições aprendidas, em tempo de amadurecimento das práticas de governança de dados.

A aplicação da lei é necessária visto que o momento em que vivemos é de extremo risco para o vazamento de dados: home office, grande quantidade de dados em trânsito e uma maior quantidade de dados sensíveis do que em outros períodos. Quanto mais tempo protelarmos a aplicação da lei, mais estaremos sujeitos a vazamentos de informações.

A pandemia está nos mostrando o quão importante seria se a LGPD já estivesse em vigor. Uma lei que seria uma referência muito forte diante de todas as questões de saúde que estamos enfrentando, devido ao grau de conscientização da sociedade diante da  crise. Acredito que o futuro nos reserva instituições mais preparadas e consumidores mais conscientes dos seus direitos.

A Viceri tem um time de especialistas nas mais diversas áreas. Todos prontos para ajudar sua empresa a entrar em conformidade com a nova Lei Geral de Proteção de Dados. Fale com a gente!

Métricas de performance e funções de perda para Machine Learning

O processo de treinamento de um modelo supervisionado requer um feedback que consiste em realizar medições de performance e ajustar hiperparâmetros do modelo até que um estado ótimo seja atingido, para que a generalização seja a melhor possível.

Para isso ocorrer, é necessário utilizar métricas para se maximizar a qualidade e minimizar o erro. Veja alguns conceitos utilizados nesta área de aprendizado de máquina:

Underfitting: acontece quando o modelo é muito simples e não é capaz de gerar bons resultados sobre os dados conhecidos (os de treinamento), e muito menos de generalizar bem (sobre dados desconhecidos). Imagine um gráfico 2D onde este modelo representa uma função linear (uma reta), e os dados são vários pontos nesse gráfico, onde muitos deles não são cobertos pela reta.

Por outro lado, se o modelo é muito complexo e possui uma função extremamente fiel aos dados de treino, ele também não vai conseguir generalizar bem. Nesse caso ocorreu um Overfitting. Como exemplos disso podemos ter uma árvore de decisão com muitos nós, ou uma rede neural com mais neurônios do que o necessário. Isso é muito ruim porque o modelo memoriza a entrada de treino ao invés de aprender características dela.

Outro conceito é o Erro Empírico (ou erro de treino): definido como o erro do modelo sobre os dados de treino, que tende a aumentar naturalmente com o tamanho da base de treinamento, até atingir uma estabilização a um nível aceitável. Já o Erro de Validação é o erro do modelo sobre os dados de validação. Tem um comportamento espelhado com relação ao erro empírico, ou seja, tende a diminuir com o aumento da base de treino.

A partir de uma grande base de treinamento, se estas duas medidas de erro estiverem bem acima do erro aceitável (ou desejado), então ocorreu um underfitting, e dizemos que o modelo neste caso ficou com um alto viés – ou bias. Ao contrário, se apenas a medida de erro empírico estiver bem abaixo do erro aceitável, mas a medida do erro de validação estiver bem acima do aceitável, então ocorreu um overfitting e o modelo ficou com alta variância, ou seja, baixo poder de generalização. Nenhum dos dois casos é bom!

Com relação ao aumento da complexidade do modelo, temos que o erro empírico sempre vai diminuindo, porém o erro de validação tende a diminuir até um certo ponto, mas pode começar a aumentar novamente se houver superajuste do modelo. Nota-se, portanto, que é necessário encontrar um ponto ótimo, também chamado de bias-trade-off, onde o erro de validação é o mínimo possível. Durante o treino de um modelo, o objetivo é minimizar o erro de validação e não o erro de treinamento (o empírico), porque deseja-se que o modelo seja capaz de generalizar, e não de se superajustar aos dados de entrada – já conhecidos.

Depois dos conceitos, vamos às medidas de avaliação

É nesse contexto de se encontrar o equilíbrio, que se faz uso de medidas de avaliação e análise da função de perda. A maioria das medidas de avaliação derivam de uma tabela chamada de Matriz de Confusão, que contém a quantidade de classificações corretas versus as classificações preditas para cada classe sobre um conjunto de exemplos, ou seja, ela indica os erros e acertos do modelo comparando com os resultados esperados. Para cada classe é realizada a extração de quatro variáveis:

  • Verdadeiro positivo;

  • Verdadeiro negativo;  

  • Falso positivo;

  • Falso negativo.

A partir destas quatro variáveis definem-se várias métricas de avaliação. Algumas delas são:

A acurácia: representando a porcentagem de elementos classificados corretamente (positivos ou negativos), indica uma performance geral do modelo, porém pode haver situações em que ela é enganosa, no caso de identificação de fraudes em cartões de crédito, as ocorrências são naturalmente bem menores do que a quantidade de casos consideradas legais;

A acurácia por classe: a média das acurácias individuais para cada classe, minimizando o problema de desbalanceamento, como o citado anteriormente;

A precisão: que define, dentre os exemplos classificados como positivos (pelo modelo), quantos eram realmente verdadeiros. Ela é utilizada onde os falsos positivos são considerados mais prejudiciais que os falsos negativos. Por exemplo: é pior classificar um investimento ruim como bom, do que classificar um investimento bom como ruim;

A revocação ou recall: que define, dentre todas as situações de classe positiva (dos valores esperados), quantas foram classificadas como verdadeiras. Ela é utilizada onde os falsos negativos são considerados mais prejudiciais que os falsos positivos. Por exemplo: é bem pior classificar uma pessoa doente como saudável, do que classificar uma pessoa saudável como doente, considerando doente igual a positivo;

A especificidade: que é a porcentagem de amostras negativas identificadas corretamente sobre o total de amostras negativas;

E o F-Score ou F-Measure: que representa a média ponderada de precisão e revocação.

Podemos citar duas métricas que não utilizam as variáveis da matriz de confusão: a “Log-Loss” que depende da probabilidade retornada da classificação, e a “Hamming-loss” que depende da distância média entre o previsto e a classe original.

Então qual métrica é melhor? 

Cada métrica tem suas particularidades que devem ser levadas em consideração na escolha de como o modelo de classificação será avaliado. De maneira geral, não existe uma melhor ou pior que a outra, depende muito da análise do problema.

A outra parte da análise de performance de um modelo, tem relação com as funções de perda que devem ser minimizadas, ao contrário das medidas de avaliação vistas anteriormente que buscamos sempre aumentar.

De modo simplificado, uma função de perda, representa a distância entre o previsto e o real. Como exemplos podemos citar as seguintes funções:

Perda quadrática (ou squared loss): onde o resultado é elevado ao quadrado para que as distâncias negativas não se cancelem no somatório. É mais utilizada para regressões lineares;

Perda de articulação (ou hinge loss): utiliza o conceito de “margem máxima” buscando obter fronteiras com a maior distância dos dados, onde chamamos de margem, a diferença entre o “score” da classe correta e de uma outra classe;

Perda de entropia cruzada (ou cross-entropy loss): muito usada em regressões lineares multivariadas e principalmente em redes profundas. Para se buscar o valor mínimo da função de perda, é utilizado o cálculo de um vetor de derivadas parciais chamado de gradiente, em que este deve ser igualado a zero. O gradiente representa o quão rápido varia a função de perda, e esta se reduz conforme se segue no sentido contrário ao gradiente. Com o gradiente igual a zero, tem-se que a função de perda não sofre mais variação.

Podemos citar (em ordem de importância) algumas técnicas para cálculo e otimização do gradiente:

  • Método do gradiente estocástico descendente (ou SGD): que calcula o gradiente através de um batch aleatório de dados;

  • Método da propagação retrógrada (ou backpropagation): que calcula o gradiente do final para o início usando a regra da cadeia para a determinação das derivadas;

  • Método do momento: que consegue chegar ao mínimo da função de forma muito mais rápida se comparada ao zig-zag do SGD;

  • Método do momento de Nesterov (ou NAG): que é uma variante do método acima, porém mais rápido;

  •  Método RMSProp: que ajusta os valores de gradiente pelo inverso de uma média móvel;

  • Método do gradiente adaptativo (ou ADAGRAD): que é semelhante ao RMSProp, porém utiliza a soma acumulada dos quadrados dos gradientes;

  • Método da estimação do momento adaptativo (ou ADAM): que é o mais utilizado em redes neurais profundas, e reúne a técnica do RMSProp com a técnica do momento.

Sobre a base dados, de forma resumida, deve-se separar uma porção maior chamada de dados de treino, e uma parte menor chamada de dados de teste. Esta parte menor será utilizada apenas após o treinamento para verificações. Não se deve treinar o modelo com dados de teste! 

A fim de se obter as métricas mencionadas anteriormente, é muito comum uma subdivisão nos dados de treino em uma pequena parte chamada de dados de validação. E para se evitar um possível viés no treinamento, pode-se utilizar a técnica K-Fold de validação cruzada (ou cross-validation), onde deve-se definir um hiperparâmetro K, como sendo o número de folds que serão alternados durante o treinamento, ocorrendo várias trocas entre os dados de treino e de validação.

Gostou das nossas dicas e quer saber mais sobre métricas de performance e funções de perda para Machine Learning? Então fale com nosso time. Entre em contato com a Viceri!

As classificações dos algoritmos de Machine Learning

O machine learning, ou aprendizado de máquina, é um ramo da inteligência artificial que se baseia na ideia de que sistemas podem aprender com dados, identificar padrões e tomar decisões com pouca intervenção humana. De tempos para cá o machine learning se tornou essencial na tecnologia e, consequentemente, nas nossas vidas. Este tipo de conhecimento explora a construção de algoritmos que aprendem com seus erros e fazem previsões sobre dados a partir  de diferentes abordagens. 

Diante de um problema onde a solução esteja num aprendizado de máquina, deve-se escolher, dentro deste universo de técnicas, por qual caminho iniciar. Assim, os algoritmos de aprendizado de máquina podem ser classificados em três grandes grupos: Aprendizado Supervisionado, Aprendizado Não-Supervisionado e Aprendizado por Reforço. Abaixo você vai entender cada uma delas.

Aprendizado supervisionado

Nesta abordagem o modelo aprende a executar uma tarefa a partir de exemplos rotulados, ou seja, a partir das respostas corretas, que de alguma forma devem ser passadas para o modelo. Mas como fazer isso? Vejamos com estes dois exemplos: 

  • No primeiro, poderíamos ter um conjunto de imagens separadas por diferentes tipos de veículos (carros, motos, caminhões, ônibus) mapeados cada um com o nome do tipo que representa; 

  • Num segundo exemplo, poderíamos ter uma tabela com valores históricos de demanda num supermercado para servir de exemplo no aprendizado necessário para generalizar uma demanda futura.

Este aprendizado é iterativo e é realizado até que uma condição seja atingida, geralmente uma porcentagem aceitável de acertos, ou seja, a ideia é sempre de minimizar os erros que a inteligência artificial produz. Essa condição de parada com base na acurácia máxima é possível pois se trata de aprendizado com resultado conhecido.

Neste grupo, se encaixa também o aprendizado semi-supervisionado que é quando se tem alguns exemplos rotulados e muitos não-rotulados. A ideia aqui é encontrar padrões semelhantes entre os exemplos e também fazer uso dos rótulos existentes. O Aprendizado Supervisionado consiste em duas classes de algoritmos: Classificação e Regressão, dos quais falaremos mais adiante.

Aprendizado Não-Supervisionado

Em alguns casos, apesar de existir o objetivo da tarefa desejada, os resultados finais não são conhecidos e, portanto, não se tem os rótulos para passar ao modelo. Por exemplo: dada uma coleção de artigos, deseja-se agrupá-los automaticamente de acordo com a frequência de algumas palavras ou contagem de páginas. Não se sabe quantos grupos serão formados.

É nesse contexto que se apresenta o aprendizado não-supervisionado. Este modelo aprende a executar uma tarefa a partir de dados não-rotulados (sem um resultado conhecido), apenas com base em suas características e padrões semelhantes, ou seja, o modelo deduz estruturas a partir de uma amostra do problema; bem utilizado em situações com muitas observações e muitas features como: áudios, imagens e vídeos.

Para isso, existem algumas técnicas que utilizam regras de associação e clusterização, como veremos um pouco mais adiante. Essas técnicas podem ser aplicadas na fase de pré-processamento (ou mineração de dados), para se encontrar anomalias nos dados (os outliers), realizar redução de dimensionalidade em features, etc. Elas podem ser aplicadas também sobre amostras de um problema durante um processo de agrupamento de instâncias.

Alguns exemplos: um sistema que seleciona candidatos para uma vaga, ou que separa turmas de alunos para um determinado trabalho, através de técnicas de agrupamento baseadas em determinadas características que são semelhantes entre essas pessoas.

Mas para qualquer tipo de algoritmo, vale ressaltar um cuidado especial para que a inteligência artificial não faça predições preconceituosas quando se trata de seleção de pessoas, dependendo das features o sistema pode apresentar um viés racista ou sexista. Um exemplo disso é a seleção apenas de homens para vagas de engenharia, por isso o dataset deve ser cuidadosamente balanceado. 

Aprendizado por Reforço

No Aprendizado por Reforço o modelo aprende executando ações e avaliando recompensas. Em resumo, este tipo de algoritmo funciona da seguinte maneira: O agente realiza uma ação num dado ambiente, alterando seu estado inicial, o que gera uma recompensa ao agente. De forma cíclica, o agente avalia esta recompensa (que pode ser positiva ou negativa) e age novamente no ambiente, gerando o aprendizado.

Neste tipo de aprendizado muda-se um pouco o paradigma com relação aos outros dois. Geralmente é aplicada quando se conhece as regras, mas não se sabe a melhor sequência de ações que devem ser executadas, elas são iterativamente aprendidas, como num jogo de xadrez ou num videogame, onde o fundamental são as ações tomadas pelo jogador (ou pela máquina). A robótica é outro campo onde se aplica este aprendizado. Alguns algoritmos: Multi-Armed Bandits, Contextual Bandits e k-Armed Bandits.

Bem, a partir do problema em questão, podemos identificar agora qual o tipo de aprendizado utilizar. Em seguida devemos escolher uma classe de algoritmo para este tipo de aprendizado.

Se for Aprendizado Supervisionado, temos basicamente duas classes de algoritmos:

  •  Classificação;

  • Regressão

Na classificação, o objetivo é identificar a qual categoria pertence uma determinada amostra do problema. Se um e-mail é SPAM ou não; se uma mensagem tem um sentimento positivo, negativo ou neutro; se um vídeo possui conteúdo adulto; ou quais são os animais que aparecem numa determinada imagem, assim por diante.

Exemplos de técnicas de classificação são: Árvores de Decisão (onde os nós internos são rotulados com uma feature de entrada, e os nós folhas são rotulados com a classe a ser preterida), Algoritmo de Naïve Bayes (que é um classificador que trabalha com probabilidades de ocorrência de cada classe para cada valor de atributo, supondo que as variáveis são independentes), temos as Redes Neurais (baseadas em redes de neurônios artificiais interconectados – os perceptrons, onde os pesos das camadas ocultas são ajustados a cada iteração), dentre outros.

Diferentemente da classificação, na regressão, a ideia é prever um valor numérico; ou em outros termos: identificar uma categoria em escala contínua (pode ser até uma probabilidade). Neste caso, o modelo pode aprender uma função para prever o preço de um imóvel, uma demanda de venda, probabilidade de superlotação de um estoque, o tempo que levará para uma máquina apresentar defeito, uma nota de um cliente para aumentar seu limite de crédito, ou qualquer outro valor quantitativo.

Alguns exemplos de técnicas de regressão são: regressão linear, regressão logística e as redes neurais (que também podem resultar valores contínuos).

Agora, no Aprendizado Não-Supervisionado, destacam-se duas técnicas:

  •  Associação;

  • Clusterização.

A associação: permite o descobrimento de regras e correlações, identificando conjuntos de itens que frequentemente ocorrem juntos. Os varejistas costumam usar esta análise em carrinhos de compras, para descobrir itens frequentemente comprados em conjunto, desenvolvendo assim estratégias mais eficazes de marketing e merchandising.

Na clusterização (ou agrupamento): o conjunto todo em análise sofre segmentações em vários grupos, com base nas semelhanças encontradas. É uma técnica que permite dividir automaticamente um conjunto de dados em grupos de acordo com medidas de similaridade ou de distância. Existem diversas fórmulas para se obter medidas de similaridade, dentre elas podemos destacar o método do cosseno e a correlação de Pearson.

Dentre os métodos de clusterização podemos citar: o baseado em particionamento, baseado em densidade, o hierárquico aglomerativo e hierárquico divisório.

Para o Aprendizado por Reforço podemos citar os algoritmos:

  • Q-Learning;

  • Aproximação por função com atualização por gradiente; 

  • Multi-Armed Bandits;

  • Contextual Bandits;

  • k-Armed Bandits

Quer saber mais sobre algoritmos de Machine Learning? Entre em contato com a Viceri. Nós temos um time de especialistas sempre prontos para te ajudar!

Como reduzir custos com a AWS

Veja como a nuvem pode deixar sua infraestrutura mais enxuta e fazer você economizar

Reduzir custo na infraestrutura de um sistema é essencial, sobretudo em um momento como este em que qualquer corte de gastos é muito bem-vindo. Neste cenário, a nuvem entra como uma forma de deixar a sua infraestrutura mais enxuta, desde mecanismos de monitoramento, passando pela possibilidade de desligar o equipamento em momentos ociosos, até reservar máquinas para conseguir descontos. 

A AWS, Amazon Web Services, oferece uma infraestrutura sob demanda, para  que você pague apenas pelo que consumir. Isso quer dizer que você tem uma redução de custos a longo prazo e economiza uma quantidade dinheiro que pode ser usado para investimento em inovação e novas oportunidades.

Pague apenas o que usar

A AWS oferece algumas modalidades de virtualização de máquina. Dentre essas modalidades existe on-demand  que, como o próprio nome já diz, é a modalidade sobre demanda. Isso significa que você vai pagar somente o que tiver utilizando efetivamente. 

Se a sua aplicação precisar de uma visita apenas durante os dias de semana, você pode deixar a sua máquina parada durante o final de semana. Considerando um mês de trinta dias e quatro finais de semana, teríamos oito dias com a máquina parada sem gerar custo. Isso equivaleria a uma economia de aproximadamente 25%. Agora, imagine se sua aplicação ficar online apenas em horário comercial, o desconto seria muito maior e poderia chegar a 70%.

Tabela de redução segundo a AWS. Fonte: aws.amazon.com/pt/economics

Calculadoras de custo total de propriedade da AWS

A calculadora de TCO, Custo Total de Propriedade, da AWS permite que você faça uma estimativa sobre a redução de custo ao usar a plataforma. A AWS oferece relatórios detalhados inclusive para apresentações executivas. A calculadora permite modificações e suposições de acordo com suas necessidades da sua empresa. Neste ambiente você pode comparar o custo da execução das aplicações ou de hospedagem tradicional com o custo da execução na AWS. 

Processo automatizado 

É possível realizar o agendamento de parada e inicialização de recursos automaticamente, sem a necessidade de intervenção manual para realizar o procedimento todos os dias, evitando mão de obra e dando garantias de sempre acontecer, removendo os riscos de possíveis esquecimentos humanos. 

Uma das possibilidades é utilizar o CloudWatch como gatilho, criando uma regra em determinado horário para uma função lambda. Essa função lambda, por sua vez, consome SDK da AWS e oferece todos os comandos para você desligar o EC2 ou RDS. É uma solução bem utilizada e fácil de implementar.

Outra forma, ainda mais fácil, é utilizar uma solução já existente: o AWS Instance Scheduler. Ela facilita as paradas tanto das máquinas EC2 quanto RDS. Internamente o uso não é diferente da função anterior, ele usa o CloudWatch e a lambda, além disso, para armazenar alguns valores ele utiliza o DynamoDB. É uma boa solução caso você não queira fazer sua própria função lambda. Porém, vale ressaltar que você é responsável pelo pagamento de cada serviço utilizado na solução, então haverá aumento de consumo nos serviços mencionados acima.

Uma terceira possibilidade é configurar a instância na hora de criar a máquina dentro de um auto scaling group. Isso dará a possibilidade de configurar a quantidade de instância desejável em um determinado horário. Na hora de configurar você pode usar uma fórmula de cronograma como os usados no gatilho do CloudWatch e determinar dia e horário.

Cuidado para não perder seus dados! 

Alguns cuidados precisam ser tomados ao utilizar um processo automático de desligamento de máquinas EC2. Podem surgir problemas quando aplicações críticas estão rodando algum processo long-running em background e são paradas abruptamente. Se a sua aplicação mantém algum tipo de estado não persistido (deixado em memória, por exemplo), você fatalmente perderá essas informações. Se a sua aplicação não estiver tratando operações como atômicas, ou seja, transacionando no banco de dados, pode acabar gerando inconsistência na base.

Se a sua aplicação usa algum meio de persistência local como o próprio EBS, é importante que você apenas pare a aplicação e não a finalize. Quando você finaliza, acaba perdendo todas as informações do disco local. 

◼️ Leia também: O manual da segurança de dados na AWS e as responsabilidades compartilhadas

Atenção ao limite de dias para parar sua instância RDS

Atualmente existe um limite máximo de sete dias que você pode manter seu banco de dados parado, depois disso ele automaticamente irá iniciar novamente. Como já falamos, quando ele está parado não há cobrança, mas há limitações: no banco de dados postgres, ao usar um banco read replica não é possível parar o banco primário até que seja excluído o banco de réplica. Isso significa um aumento expressivo no tempo de inicialização nestes casos.

Apesar do tempo de inicialização ser maior, financeiramente pode valer a pena. O tempo de inicialização irá aumentar porque será preciso recriar o banco sempre que iniciá-lo novamente. Pode levar dez, vinte minutos, mas caso seu banco fique ocioso durante um longo período, financeiramente pode ser muito vantajoso

Outras formas de reduzir custos com a AWS também são possíveis. Vamos considerar um serviço que roda em background e que a cada 5 horas realização uma operação no banco de dados. Isso significa que ele ficará ocioso por 5 horas, depois irá trabalhar durante alguns segundos, para ficar ocioso novamente durante outras 5 horas.

Considerando a atividade descrita acima, é válida a criação de uma AWS lambda, onde você será cobrado apenas pelo tempo que executar o processamento da rotina.Uma solução bem interessante quando se tem vários serviços que rodam de tempos em tempos.

Presença global por um preço acessível ao bolso

A AWS tem uma presença global que permite repassar a economia para quem compra esse serviço de maneira contínua. São diversas opções de pacotes e serviços que podem oferecer economia de 75% a 90% das taxas sob demanda se for escolhida a capacidade pré-adquirida ou capacidade reserva.

Como já falamos anteriormente, na AWS não é preciso fazer compromissos com gastos mínimos ou contratos de longa duração. Você pode substituir as despesas iniciais por pagamentos que se aplicam apenas àquilo que você necessita. Nada de contratos ou modelos complexos que dificultam seu dia a dia. 

Ficou interessado? A Viceri tem uma equipe pronta para fazer a migração do seu banco e colaborar em tudo que você precisar durante o processo. Fale com a gente!

Como transformar seu monolito em microsserviço

Transformar uma aplicação monolítica em microsserviços poder ser uma tarefa muito complexa. Conheça alguns caminhos possíveis de se seguir quando estiver refatorando sua aplicação monolítica

Transformar uma aplicação monolítica em microsserviços é uma forma de modernizar a aplicação.

E se você trabalha com tecnologia, deve saber que o processo de transformar uma aplicação monolítica em microsserviços é uma tarefa muito complexa e delicada. Exige tempo e paciência de todos os envolvidos. 

A arquitetura monolítica é uma arquitetura tradicional de desenvolvimento de sistema de software.

Ela se baseia no princípio de que todos os processos dentro de uma mesma solução estão ligados. Isso quer dizer que são acoplados, que estão dentro de uma base de dados similar e executam seus processos como um único serviço. 

Já a arquitetura de microsserviços veio para solucionar problemas enfrentados pela arquitetura monolítica.

É um modelo que desenvolve pequenos serviços que realizam funções independentes.

Por serem independentes, podem atender demandas específicas em uma solução maior. É um processo menos tradicional que a arquitetura monolítica. 

Primeiros passos para refatorar uma aplicação 

Para que a migração de uma para a outra se torne uma tarefa mais simplificada, existem alguns caminhos possíveis de se seguir quando estiver refatorando sua aplicação monolítica.

A primeira dica é não fazer uma reescrita total da sua aplicação. Ou seja, esqueça a ideia de direcionar todos os esforços do time para reescrever a aplicação do zero.

Isso é extremamente arriscado e geralmente resulta em problemas que acabam levando mais tempo que o planejado. 

Vá devagar! O mais recomendado é refatorar aos poucos sua aplicação monolítica. Construa uma aplicação de forma incremental, rodando cada novo microsserviço em conjunto da aplicação original.

Com o passar do tempo, a quantidade de funcionalidades implementadas em microsserviços vai mostrar que o monolito encolheu tanto que em algum momento ele deixará de existir.

Quando sua aplicação monolítica se tornar ingerenciável, deve-se parar de tornar seu monolito maior.

Se você tiver de implementar uma nova funcionalidade, não adicione esse código ao monolito. Ao invés disso, a melhor estratégia é colocar o novo código em um microsserviço próprio para isso.

Glue Code

É neste cenário que surge o Glue Code, que são as dependências responsáveis pelo acesso aos dados.

Geralmente o serviço usará bibliotecas e componentes de acesso a dados da sua aplicação original.

O glue code  é chamado também de camada anti-corrupção, já evita que o microsserviço seja poluído com problemas da aplicação legada.

Desenvolver uma camada anti-corrupção não é algo muito comum, mas é essencial quando se quer manter uma aplicação confiável.

Com isso em mente, esse Glue Code pode seguir três estratégias:

– Invocar uma API remota, fornecida pelo monolito;

– Acessar a base de dados do monolito diretamente;

– Manter sua própria cópia da base com parte dos dados necessários para o microsserviço, que estará sincronizada com a base do monolito. 

E o que acontece ao implementarmos novas estratégias? 

Implementar novas funcionalidades como um microsserviço tem uma série de benefícios.

Essa estratégia impede que seu monolito se torne cada vez mais ingerenciável, ao mesmo tempo que permite que o serviço possa ser desenvolvido, implantado e escalado de maneira independente do monolito.

A cada novo serviço criado, será experimentado um pouco mais dos benefícios desta arquitetura.

Entretanto, essa abordagem não acaba com todos os problemas do monolito. Para tentar consertar esses problemas, é necessário quebrar o monolito em partes cada vez menores.

Outra estratégia que ajuda a encolher a aplicação monolítica é separar a sua camada de apresentação da lógica de negócio e do acesso a dados.

Geralmente existe uma separação muito clara entre a camada de apresentação e as camadas de regras de negócio e dados.  E isto é o que permite fazer a separação do seu monolito em duas aplicações menores.

Uma aplicação será o frontend, e a outra o backend. Uma vez separados, o frontend fará chamadas independentes ao backend.

Separar um monolito dessa maneira permite que o time desenvolva, implante e escale duas aplicações de maneira independente.

Essa estratégia, no entanto, é somente uma solução parcial. É bem comum que você troque um problema enorme por dois problemas menores, mas que no contexto geral ainda são um problemão a ser resolvido.

Você terá de usar uma outra estratégia para eliminar os monolitos restantes.

Essa outra estratégia é transformar os módulos existentes dentro de um monolito em microsserviços.

Cada vez que você extrai um módulo e o transforma em um serviço, o monolito encolhe. Uma vez que tenha sido convertido muitos módulos, o monolito deixará de ser um problema. Ou ele irá sumir ou vai acabar virando um microsserviço.

Converter um módulo em microsserviço requer tempo e paciência 

Uma aplicação monolítica grande geralmente terá dezenas ou centenas de módulos, todos dispostos a serem extraídos.

Saber quais módulos converter primeiro pode ser desafiador. Uma boa abordagem é começar com alguns módulos que são fáceis de extrair.

Converter um módulo em um microsserviço é algo que requer tempo. Uma dica é priorizar módulos que mudam com frequência.

Isto trará experiência com arquitetura de microsserviços e com o processo de extração.

Depois que você extrair esses módulos mais fáceis, poderá partir para os mais complexos.

Uma vez que você tenha convertido um módulo desses para um serviço, você pode desenvolver e implantar ele de maneira independente do monolito, o que vai acelerar o desenvolvimento.

Outra abordagem interessante é extrair os módulos que possuem requisitos diferentes do resto da aplicação.

Por exemplo, pegar aquele módulo que utiliza recursos específicos do servidor como muita memória ou CPU. Conforme você vai extraindo estes módulos específicos, você vai ver como se tornará mais fácil escalar os microsserviços.

O primeiro passo ao extrair um módulo é definir a interface entre o módulo e o monolito.

Geralmente será um contrato bidirecional, pois é comum o monolito precisar de dados do microsserviço e vice-versa.

Se a lógica de negócio do monolito estiver muito acoplada, talvez seja difícil de extrair apenas o necessário para o microsserviço, então é possível que uma refatoração interna no monolito seja necessária para continuar avançando com essa extração.

Uma vez que você tenha extraído um módulo, é mais um serviço que permite ao time desenvolver, implantar e escalar mais facilmente do restante do monolito.

Sendo possível, inclusive, reescrever este serviço do zero mais tarde, uma vez que o módulo já foi isolado.

Cada vez que você extrair um novo serviço, estará um passo mais perto de ter uma aplicação 100% em microsserviços.

Com o passar do tempo, seu monolito encolherá e a virada de chave entre as arquiteturas se tornará algo natural.

Quer saber mais como sua empresa pode aplicar isso na prática? A Viceri conta com especialistas que podem te ajudar. Fale com a gente!