Machine Learning… Já tinha ouvido falar, mas, nunca pesquisei ou busquei ler sobre o tema, então, no final do ano passado tive a oportunidade de assistir uma breve palestra sobre machine learning e fiquei bastante interessado. Posteriormente, participei do Microsoft Ignite e tive a oportunidade de acompanhar mais algumas palestras sobre o tema e isso despertou ainda mais meu interesse.
Em todas essas palestras vi exemplos com um framework de machine learning da Microsoft, o ML.NET, e desde então vinha aguardando ter algum tempo para poder ler mais a respeito e poder implementar alguns exemplos, afim de ver o framework em funcionamento e aprender mais sobre o tema.
Machine Learning
Em uma tradução literal significa simplesmente “aprendizado de máquina”.
Mas, o que isso quer dizer na prática?
Na prática isso significa que podemos ensinar uma máquina a realizar uma tarefa ou ação de forma autônoma com base em sua experiência.
E, como fazemos uma máquina ganhar experiência para poder realizar uma ação ou tomar alguma decisão?
Através de algoritmos que identificam padrões em conjuntos de dados e que são construídos sob a ótica de um determinado problema. São esses algoritmos que usamos para ensinar a máquina a agir de acordo com sua análise. Existem algoritmos para identificação de objetos em imagens, detecção de fraudes, previsões de preços ou estoque e vários outros tipos.
Diferença entre inteligência artificial e machine learning
Constantemente machine learning e inteligência artificial são confundidos, mas, para simplificar, inteligência artificial é um ramo da computação que busca treinar computadores para realizar ações que normalmente necessitariam de inteligência humana para serem realizadas, já o machine learning é um ramo da inteligência artificial que ensina os computadores a encontrar padrões em conjuntos de dados para que possa realizar ações com base nelas.
ML.NET
O ML.NET é um framework da Microsoft que nasceu com o objetivo de levar o machine learning para aplicações .NET. Ele permite o treinamento e construção de modelos usando C# ou F# e uma vez que esses modelos estejam prontos podem ser facilmente integrados a uma aplicação.
Muito mais sobre o ML.NET pode ser visto aqui.
Ciclo de vida do machine learning
O ciclo do vida do machine learning é um processo cíclico que define os passos que devem ser seguidos para extrair o melhor do machine learning e agregar valor ao negócio da companhia. A maioria das literaturas fala que esse ciclo é constituído por 5 a 7 passos, porém, vou me ater ao modelo que a Microsoft usa em suas apresentações que possui 5 passos:
- Faça a pergunta correta - Para solucionar um problema precisamos entender completamente com o que estamos lidando. Isso influenciará na preparação dos dados e na escolha do algoritmo.
- Prepare os dados - Em um cenário realista provavelmente o analista precisará buscar informações de várias bases de dados e sistemas para conseguir formar uma massa de dados consistente. Esse etapa é de grande importância, pois, é essa massa de dados que será utilizada no treinamento do modelo.
- Escolha o algoritmo (modelo) - O machine learning possui uma série de algoritmos para resolver vários problemas, e, por vezes, mais de um algoritmo pode resolver o mesmo tipo de problema. Nessa etapa, pode ser necessário realizar testes com mais de um para determinar qual algoritmo é melhor para solucionar seu problema.
- Treine o modelo - Com os dados preparados e o modelo selecionado, é hora do treinamento. Aqui os dados são inseridos no modelo para que ele possa "aprender" com os dados que já temos.
- Teste o modelo - Agora com o modelo já treinado basta testar e analisar seus resultados. Esse pode ser o momento de considerar o teste de outro algoritmo ou refinar seus dados caso os resultados sejam muito discrepantes.
Implementação
Para meu cenário parti da seguinte questão: Com base nas minhas vendas dos últimos anos, quanto vou vender nos próximos 12 meses?
Como estou realizando testes e aprendendo a usar o ML.NET em um cenário controlado, a preparação de dados não existe, simplesmente criei uma massa de dados em um formato que possa ser facilmente utilizada para treinamento do modelo.
Para isso usei MySQL rodando no Docker. Já falei um pouco sobre Docker e como usar o MySQL no Docker no artigo “Logando queries do Entity Framework com Serilog”., então, se quiser entender com fazer isso basta dar uma lida lá.
Seguindo, simplesmente criei um schema para receber o valor mensal total das vendas, o mês e ano da venda.
E criei uma procedure para popular essa tabela com valores aleatórios, dado um período:
Resolvi criar uma massa de três anos, 2017 a 2019. Basta executar a procedure para popularmos a base:
Com a base de dados pronta, podemos partir pro código .NET. Pra começar criei uma aplicação do tipo console e adicionei os pacotes NuGet que vamos precisar:
- MySql.Data - Será necessário para a conexão com a base MySQL.
- Microsoft.ML - Carrega o coração do framework de machine learning.
- Microsoft.ML.TimeSeries - Contém o algoritmo que usaremos para nosso estudo.
Com a instalação dos pacotes necessários feita podemos começar a codificar. Eu montei meu código dentro do Main mesmo.
O primeiro passo é criar um MLContext, ele é o ponto de entrada de todas as operações com o ML.NET bem como é usado para a criação e uso dos modelos.
Com o contexto criado, vamos carregar nossos dados, primeiramente, criei um objeto para receber os dados:
Com esse objeto criado, basta carregar os dados para o contexto. Note que na query que é executada trazemos as colunas com exatamente o mesmo nome das propriedades do objeto:
Agora que já temos os dados carregados em nosso contexto podemos treinar o modelo, nessa etapa é de grande importância ficar atento aos valores que estamos fornecendo aos parâmetros de treino, pois, esses parâmetros contém coisas como o windowSize, seriesLength e trainSize que se utilizados de forma equivocada podem gerar resultados completamente inesperados. Como quero fazer uma previsão mais linear ao longo de um período de tempo, optei por usar o algoritmo SSA (single spectrum analysis) que combina elementos comuns de análise ao longo de um período de tempo com análises estatísticas e decomposições. Existem outros algoritmos que poderiam ajudar a resolver esse mesmo problema mas vou optar por implementar esse primeiro.
Um pouco sobre cada um desses parâmetros:
- outputColumnName - Nome da propriedade no objeto de saída que será preenchida com as previsões.
- inputColumnName - Nome da propriedade do objeto de entrada que contém os dados sobre os quais a previsão será feita.
- windowSize - É o parâmetro mais importante. Esse parâmetro é usado para definir a janela de tempo que deverá ser utilizada pelo algoritmo para decompor os dados. Normalmente, usa-se com a maior janela de tempo possível e que faça sentido para seu negócio/cenário. Por exemplo, se seu negócio possui um ciclo com períodos semanais ou mensais (7 ou 30 dias) e a coleta de dados é feita diariamente, a janela de tempo deve ser 30 para representar a maior janela possível no seu ciclo de negócio. No nosso caso, nossa base de dados está em meses e com uma coleta de dados mensal, não em dias, portando usaremos o tamanho 12.
- seriesLength - Quantidade de itens que será usada para realizar a previsão.
- trainSize - Quantidade de itens que será usada para realizar o treino do modelo.
- horizon - Indica o número de períodos para realizar a previsão. No nosso caso queremos 12 meses, usaremos 12.
- confidenceLevel - Indica o nível de confiança da previsão, o valor deve estar entre 0 e 1 e quanto maior o valor maior será a diferença entre os limites inferiores e superiores.
- confidenceLowerBoundColumn - Propriedade do objeto de saída que receberá o valor de previsão de pior cenário.
- confidenceUpperBoundColumn - Propriedade do objeto de saída que receberá o valor de previsão de melhor cenário
Finalmente podemos treinar o modelo:
Com o modelo devidamente treinado podemos agora criar o mecanismo de previsão. Mas, primeiro, precisamos de um objeto para receber os dados das previsões. Para isso criei a classe OutputModel:
E agora criamos o mecanismo:
Com o mecanismo criado, podemos gravar seu modelo para que seja utilizado em outra aplicação:
E para utilizar o modelo armazenado basta fazer dessa forma:
Lembrando que esses passos de armazenar um modelo e carregar um modelo pré existente são opcionais.
Agora vamos testar nosso modelo, para isso criei um outro método, pois, achei que tudo junto no Main ficaria muito confuso:
Basicamente, o que fiz nesse método foi realizar a previsão usando o método Predict e gerar um comparativo no console mostrando como foram as vendas nos anos anteriores e qual é a previsão para os próximos 12 meses. Lembrando que gerei uma base aleatória de dados, portanto, para cada nova carga da base outras previsões serão geradas.
Todo o código está disponível no meu git.
Conclusão
O machine learning já é uma realidade há algum tempo e está cada vez mais presente nas empresas e em nosso cotidiano (ainda que a gente muitas vezes nem faça ideia disso) e o ML.NET fornece meios de trazê-lo ao universo Microsoft de forma acessível. Ele foi construído com os desenvolvedores e aplicações .NET em mente, permitindo que façamos uso de todo conhecimento que já temos aliado às bibliotecas que já conhecemos para que possamos integrar o machine learning em nossas aplicações de forma rápida.
Espero que tenham gostado e muito porvavelmente voltarei a falar do assunto por aqui, já que ainda há muito o que ser explorado.
Esse post foi útil pra você?