Grandes modelos de linguagem como ChatGPT e Bard elevaram o aprendizado de máquina ao status de fenômeno. Seu uso para assistência de codificação rapidamente conquistou um lugar para essas ferramentas no kit de ferramentas do desenvolvedor. Outros casos de uso estão sendo explorados, desde a geração de imagens até a detecção de doenças.
As empresas de tecnologia estão investindo pesadamente em aprendizado de máquina, por isso saber treinar e trabalhar com modelos está se tornando essencial para os desenvolvedores.
Este artigo apresenta uma introdução ao aprendizado de máquina em Java. Você verá pela primeira vez como funciona o aprendizado de máquina, seguido de um breve guia para implementar e treinar um algoritmo de aprendizado de máquina. Vamos nos concentrar no aprendizado de máquina supervisionado, que é a abordagem mais comum para o desenvolvimento de aplicativos inteligentes.
Aprendizado de máquina e IA
O aprendizado de máquina evoluiu a partir do campo da inteligência artificial (IA), que busca produzir máquinas capazes de imitar a inteligência humana. Embora o aprendizado de máquina seja uma tendência em alta na ciência da computação, a IA não é um campo novo na ciência. O teste de Turing, desenvolvido por Alan Turing no início da década de 1950, foi um dos primeiros testes criados para determinar se um computador poderia ter inteligência real. De acordo com o teste de Turing, um computador poderia provar a inteligência humana enganando um humano fazendo-o acreditar que também era humano.
Muitas abordagens de aprendizado de máquina de última geração são baseadas em conceitos de décadas atrás. O que mudou na última década é que os computadores (e plataformas de computação distribuída) agora possuem o poder de processamento necessário para algoritmos de aprendizado de máquina. A maioria dos algoritmos de aprendizado de máquina exige um grande número de multiplicações de matrizes e outras operações matemáticas para serem processadas. A tecnologia computacional para gerenciar esses cálculos não existia há duas décadas, mas existe hoje. O processamento paralelo e os chips dedicados, bem como o big data, aumentaram radicalmente a capacidade das plataformas de aprendizagem automática.
O aprendizado de máquina permite que programas executem processos de melhoria de qualidade e ampliem suas capacidades sem envolvimento humano. Alguns programas desenvolvidos com aprendizado de máquina são até capazes de atualizar ou estender seu próprio código.
Como as máquinas aprendem
O aprendizado supervisionado e o aprendizado não supervisionado são as abordagens mais populares para o aprendizado de máquina. Ambos exigem alimentar a máquina com um grande número de registros de dados para correlacionar e aprender. Esses registros de dados coletados são comumente conhecidos como vetores de recursos. No caso de uma casa individual, um vetor de características pode consistir em características como o tamanho geral da casa, o número de cômodos e a idade da casa.
Aprendizagem supervisionada
Em aprendizagem supervisionada, um algoritmo de aprendizado de máquina é treinado para responder corretamente a questões relacionadas a vetores de recursos. Para treinar um algoritmo, a máquina recebe um conjunto de vetores de recursos e um rótulo associado. Os rótulos normalmente são fornecidos por um anotador humano e representam a resposta certa para uma determinada pergunta. O algoritmo de aprendizagem analisa vetores de recursos e seus rótulos corretos para encontrar estruturas internas e relacionamentos entre eles. Assim, a máquina aprende a responder corretamente às consultas.
Por exemplo, uma aplicação imobiliária inteligente pode ser treinada com vetores de características, incluindo o respectivo tamanho, número de quartos e idade de uma série de casas. Um rotulador humano rotularia cada casa com o preço correto com base nesses fatores. Ao analisar os dados, o aplicativo imobiliário seria treinado para responder à pergunta: “Quanto dinheiro eu poderia conseguir por esta casa?”
Após o término do processo de treinamento, os novos dados de entrada não são rotulados. A máquina é capaz de responder corretamente a novas consultas, mesmo para vetores de recursos não vistos e não rotulados.
Aprendizagem não supervisionada
Em aprendizagem não supervisionada, o algoritmo é programado para prever respostas sem rotulagem humana, ou mesmo perguntas. Em vez de predeterminar rótulos ou quais deveriam ser os resultados, o aprendizado não supervisionado aproveita enormes conjuntos de dados e poder de processamento para descobrir correlações anteriormente desconhecidas. No marketing de produtos de consumo, por exemplo, a aprendizagem não supervisionada poderia ser usada para identificar relações ocultas ou agrupamentos de consumidores, levando eventualmente a estratégias de marketing novas ou melhoradas.
Este artigo se concentra no aprendizado de máquina supervisionado, que atualmente é a abordagem mais comum para aprendizado de máquina.
Um projeto supervisionado de aprendizado de máquina
Vejamos agora um exemplo: um projeto de aprendizagem supervisionada para uma aplicação imobiliária.
Todo aprendizado de máquina é baseado em dados. Essencialmente, você insere muitas instâncias de dados e os resultados reais desses dados, e o algoritmo forma um modelo matemático baseado nessas entradas. A máquina eventualmente aprende a usar novos dados para prever resultados desconhecidos.
Para um projeto de aprendizado de máquina supervisionado, você precisará rotular os dados de maneira significativa para o resultado que procura. Na Tabela 1, observe que cada linha do registro da casa inclui um rótulo para “preço da casa”. Ao correlacionar os dados das linhas com a etiqueta de preço da casa, o algoritmo será eventualmente capaz de prever o preço de mercado de uma casa que não está no seu conjunto de dados (observe que o tamanho da casa é baseado em metros quadrados e o preço da casa é baseado em euros).
Tabela 1. Registros residenciais
RECURSO | RECURSO | RECURSO | RÓTULO |
Tamanho da casa | Número de quartos | Idade da Casa | Custo estimado |
90 metros2 / 295 pés |
2 | 23 anos |
249.000€ |
101 metros2 / 331 pés |
3 | N / D |
338.000 € |
1.330 m2/4.363 pés |
11 | 12 anos |
6.500.000€ |
Nos estágios iniciais, você provavelmente rotulará os registros de dados manualmente, mas poderá eventualmente treinar seu programa para automatizar esse processo. Você provavelmente já viu isso em aplicativos de e-mail, onde mover o e-mail para a pasta de spam resulta na consulta “Isso é spam?” Ao responder, você está treinando o programa para reconhecer mensagens que não deseja ver. O filtro de spam do aplicativo aprende a rotular e descartar mensagens futuras da mesma fonte ou que contenham conteúdo semelhante.
Conjuntos de dados rotulados são necessários apenas para fins de treinamento e teste. Após o término dessa fase, o modelo de aprendizado de máquina funciona em instâncias de dados não rotuladas. Por exemplo, você poderia alimentar o algoritmo de previsão com um novo registro de casa sem rótulo e ele preveria automaticamente o preço esperado da casa com base nos dados de treinamento.
Treinando um modelo de aprendizado de máquina
O desafio do aprendizado de máquina supervisionado é encontrar a função de previsão adequada para uma questão específica. Matematicamente, o desafio é encontrar a função de entrada/saída que leva a variável de entrada x e retorna o valor da previsão sim. Esse função de hipótese (hθ) é o resultado do processo de treinamento. Freqüentemente, a função de hipótese também é chamada alvo ou predição função.
Na maioria dos casos, x representa um ponto de dados múltiplos. No nosso exemplo, este poderia ser um ponto de dados bidimensional de uma casa individual definida pelo tamanho da casa valor e o número de quartos valor. A matriz desses valores é chamada de vetor de recurso. Dada uma função alvo concreta, a função pode ser usada para fazer uma previsão para cada vetor de características, x. Para prever o preço de uma casa individual, você poderia chamar a função alvo usando o vetor de características {101,0, 3,0}que contém o tamanho da casa e o número de quartos:
Listagem 1. Chamando a função alvo com um vetor de recursos
// target function h (which is the output of the learn process)
Function<Double(), Double> h = ...;
// set the feature vector with house size=101 and number-of-rooms=3
Double() x = new Double() { 101.0, 3.0 };
// and predicted the house price (label)
double y = h.apply(x);
Na Listagem 1, a variável array x o valor representa o vetor de características da casa. O sim o valor retornado pela função alvo é o preço previsto da casa.
O desafio do aprendizado de máquina é definir uma função alvo que funcione com a maior precisão possível para instâncias de dados desconhecidas e invisíveis. No aprendizado de máquina, a função alvo (hθ) às vezes é chamado de modelo. Este modelo é o resultado do processo de aprendizagem, também denominado treinamento de modelo.
Com base em exemplos de treinamento rotulados, o algoritmo de aprendizagem procura estruturas ou padrões nos dados de treinamento. Isso é feito por meio de um processo conhecido como retropropagação, onde os valores são modificados gradativamente para reduzir perdas. A partir destes, produz um modelo que é capaz de generalizar a partir desses dados.
Normalmente, o processo de aprendizagem é exploratório. Na maioria dos casos, o processo será executado múltiplas vezes usando diferentes variações de algoritmos e configurações de aprendizagem. Quando um modelo é definido, os dados também passam por ele muitas vezes. Essas iterações são conhecidas como épocas.
Eventualmente, todos os modelos serão avaliados com base em métricas de desempenho. O melhor será selecionado e usado para calcular previsões para futuras instâncias de dados não rotulados.
Regressão linear
Para treinar uma máquina para pensar, o primeiro passo é escolher o algoritmo de aprendizagem que você usará. Regressão linear é um dos algoritmos de aprendizagem supervisionada mais simples e populares. Este algoritmo assume que a relação entre os recursos de entrada e o rótulo de saída é linear. A função genérica de regressão linear na Figura 3 retorna o valor previsto resumindo cada elemento do vetor de recurso multiplicado por um parâmetro teta (θ). Os parâmetros teta são usados no processo de treinamento para adaptar ou “ajustar” a função de regressão com base nos dados de treinamento.
A regressão linear é um tipo simples de função de aprendizagem, mas fornece uma boa base para formas mais avançadas, como a descida gradiente, que é usada em redes neurais feed forward. Na função de regressão linear, os parâmetros teta e os parâmetros de recurso são enumerados por um número de assinatura. O número de assinatura indica a posição dos parâmetros teta (θ) e dos parâmetros de recurso (x) dentro do vetor. Observe que o recurso x0 é um termo de deslocamento constante definido com o valor 1 para fins computacionais. Como resultado, o índice de uma característica específica do domínio, como o tamanho da casa, começará com x1. Então, se x1 é definido para o primeiro valor do vetor de recursos da Casa, tamanho da casa, então x2 será definido para o próximo valor, número de quartos e assim por diante.
A Listagem 2 mostra uma implementação Java desta função de regressão linear, mostrada matematicamente como hθ(x). Para simplificar, o cálculo é feito usando o tipo de dados double
. Dentro do apply()
método, espera-se que o primeiro elemento da matriz tenha sido definido com um valor de 1,0 fora desta função.
Listagem 2. Regressão linear em Java
public class LinearRegressionFunction implements Function<Double(), Double> {
private final double() thetaVector;
LinearRegressionFunction(double() thetaVector) {
this.thetaVector = Arrays.copyOf(thetaVector, thetaVector.length);
}
public Double apply(Double() featureVector) {
// for computational reasons the first element has to be 1.0
assert featureVector(0) == 1.0;
// simple, sequential implementation
double prediction = 0;
for (int j = 0; j < thetaVector.length; j++) {
prediction += thetaVector(j) * featureVector(j);
}
return prediction;
}
public double() getThetas() {
return Arrays.copyOf(thetaVector, thetaVector.length);
}
}
Para criar uma nova instância do LinearRegressionFunction
, você deve definir o parâmetro theta. O parâmetro teta, ou vetor, é usado para adaptar a função de regressão genérica aos dados de treinamento subjacentes. Os parâmetros teta do programa serão ajustados durante o processo de aprendizagem, com base em exemplos de treinamento. A qualidade da função alvo treinada só pode ser tão boa quanto a qualidade dos dados de treinamento fornecidos.
No próximo exemplo, o LinearRegressionFunction
será instanciado para prever o preço da casa com base no tamanho da casa. Considerando que x0 tem que ter um valor constante de 1,0, a função de destino é instanciada usando dois parâmetros teta. Os parâmetros teta são o resultado de um processo de aprendizagem. Após a criação da nova instância, o preço de uma casa com área de 1.330 metros quadrados será previsto da seguinte forma:
// the theta vector used here was output of a train process
double() thetaVector = new double() { 1.004579, 5.286822 };
LinearRegressionFunction targetFunction = new LinearRegressionFunction(thetaVector);
// create the feature vector function with x0=1 (for computational reasons) and x1=house-size
Double() featureVector = new Double() { 1.0, 1330.0 };
// make the prediction
double predictedPrice = targetFunction.apply(featureVector);
A linha de previsão da função alvo é mostrada como uma linha azul na Figura 4. A linha foi calculada executando a função alvo para todos os valores do tamanho da casa. O gráfico também inclui os pares preço-tamanho usados para treinamento.