Este definitivamente é aquele tipo de post que eu gosto muito de escrever: bem técnico e sobre algo real (leia-se, com aplicação de mercado) que estamos produzindo aqui na Microsoft.
Se você me acompanha através deste site ou das minhas redes sociais deve saber, com certeza, que eu e alguns colegas aqui na Microsoft estamos desenvolvendo, já há alguns meses, uma solução open-source baseada em ASP.NET Core e microserviços chamada Arda. Já falei bastante sobre o Arda nesta série de posts e portanto, não o farei de maneira repetida aqui.
Na verdade, este post tem o objetivo de apresentar o processo de implementação de um novo microserviço que criamos recentemente para atender a uma demanda crescente para o Arda – recomendação de profissionais para atividades futuras. Estamos chamando este microserviço de “Arda Intelligence”. O código já está na íntegra no GitHub do DX Brasil e você pode acessá-lo seguindo este link.
O problema
Como você pode imaginar, utilizamos massivamente o Arda internamente para gerenciar os workloads de trabalho em nosso time. O Arda tem se tornado cada vez mais útil por aqui por algumas razões: dado o tamanho da equipe e a natureza operacional que temos, cada profissional envolvido com uma ampla gama de projetos de diferentes tipos, em diferentes áreas e com diferentes requisitos técnicos e tecnologias.
Uma das coisas que o Arda faz muito bem é gerenciar workloads que ainda serão executados no futuro (o que chamamos na ferramenta de “backlog”). Evidentemente que, conforme os projetos atuais vão sendo entregues na linha linha do tempo, outros novos são promovidos da lista de backlogs para a lista de workloads ativos.
Com estas informações cruzadas, não fica difícil identificar um problema emergente – dada a entrada de um novo workload para ser distribuído para o time, responder: como o manager pode saber quem é (ou são) o(s) profissional(is) do time que tem a maior afinidade com determinada atividade que precisará ser executada versus a(s) tecnologia(s) associadas? E ainda, quem desses profissionais tem maior banda para atender a demanda naquele momento?
Para endereçar esta demanda crescente criamos um novo microserviço para ser contectado à plataforma. Estamos chamando de Arda Intelligence e estamos adicionando em seu contexto uma primeira funcionalidade: “Intelligent Professional Recomendation (IPR)”, da qual falaremos exaustivamente daqui para frente.
Intelligent Professional Recomendation (IPR)
O IPR é uma ASP.NET Core Web API (wrapper) que se conecta a um experimento de machine learning no Microsoft Azure e, com base nas informações fornecidas por ele (profissionais mais recomendados para executar determinada tarefa com determinada tecnologia), ajusta a saída e a devolve em formato JSON simplificado para ser consumida por algum front-end (uma aplicação web ou aplicativo móvel, por exemplo). Nas sessões seguintes apresentarei com riqueza de detalhes todo o processo de criação até a publicação do serviço.
Etapa 1. Preparação dos dados
Nosso primeiro exercício no sentido de criar a solução foi o de estudar os dados que temos (aqueles coletados pela plataforma) em nossa base. As vezes temos ideias incríveis, inovadoras, entretanto, por vezes ocorre de a base de dados que temos não nos dar os insumos que precisamos para extrair as informações corretas para, posteriormente, abastecer recursos de inteligência (como é o caso do Azure Machine Learning, por exemplo).
Após passar algumas horas por todas as tabelas do banco fazendo um mapeamento de quais colunas seriam relevantes para nossa análise, chegamos a consulta apresentada pela Listagem 1.
Listagem 1. Selecionando as informações necessárias no banco de dados do Arda
Nosso raciocínio foi: precisamos encontrar todas as atividades desenvolvidas pelos profissionais dos times cruzando com as tecnologias em que eles comumente trabalham e claro, quem são estes profissionais. Isso tudo considerando o tipo de informação que temos. Concluímos portanto que precisávamos de basicamente três informações básicas: “Atividade”, “Tecnologia” e “Profissional”. Dessa maneira, rodando esta consulta, tivemos um resultado semelhante aquele apresentado pela Figura 1.
Figura 1. Porção de dados retornados pela consulta base
Com a verificação de que os dados estavam sendo retornados corretamente, criamos uma view baseada neste retorno para que o Azure Machine Learning pudesse consumir mais adiante (ver Listagem 2).
Listagem 2. Criando a view com base na consulta formatada
Outra informação de que precisávamos para dar a resposta de uma maneira que realmente fosse útil, era a “banda” de cada profissional. Por banda você deve entender “carga de trabalho” dos últimos sete dias de cada profissional recomendado. Para isso criamos uma nova view (nos mesmos moldes do que já fizemos com aquela apresentada pela Listagem 2). A Figura 2 apresenta esta nova view.
Figura 2. Estrutura da nova view
Pronto. Definimos as informações de que precisávamos para que o machine learning pudesse analisar e estabelecer os padrões. Como próximo passo, passamos para a configuração do machine learning. Este processo será descrito na etapa 2 a seguir.
Etapa 2 – Classificando os dados com Azure Machine Learning (ML)
De maneira resumida, podemos dizer que machine learning é o processo de, utilizando dados conhecidos pelo computador, fazer com que o computador seja capaz de “aprender” e posteriormente, tentar predizer (estabelecer um modelo), classificar, agrupar ou identificar algum fato, cenário ou circunstância. Por modelo, podemos entender como sendo a união dos dados analisados + algoritmos de ML.
O Azure Machine learning é um serviço PaaS (apesar de ser classificado por muitos como SaaS por conta do AzureML Studio) da Microsoft que oferece aprendizado de máquina (inteligência artificial) como um serviço. Rodando on top a este serviço, existe uma IDE online – o Azure Machine Learning Studio (conhecido por AzureML Studio), que possibilita ao usuário criar os processos de classificação para posterior predição de cenários. A Figura 3 apresenta a tela de entrada no Azure ML Studio.
Figura 3. Azure Machine Learning Studio, disponível em: https://studio.azureml.net/
Entretanto, antes de “colocar as mãos na massa com o Azure ML Studio”, se você não é um especialista em machine learning (assim como eu), é preciso estar atento a alguns conceitos básicos de inteligência artificial e ML para que seja possível criar algum modelo analítico que faça sentido. Vamos a eles?
Classes de problemas e algoritmos
A primeira coisa importante a ser entendida: existem basicamente duas maneiras distintas para que as máquinas possam “aprender”. Na verdade, me refiro aos modelos de execução dos algoritmos de aprendizagem. São os chamados métodos “supervisionados” e “não-supervisionados”.
Aprendizado supervisionado
Os algoritmos de aprendizado ditos “supervisionados” fazem previsões com base em um conjunto de exemplos. Por exemplo, as cotações históricas podem ser usadas para arriscar palpites em preços futuros. Cada exemplo usado para o treinamento é rotulado com o valor de seu interesse — neste caso, o preço da ação. Um algoritmo de aprendizado supervisionado procura por padrões nesses rótulos de valor. Ele pode usar qualquer informação que seja relevante — o dia da semana, a temporada, os dados financeiros da empresa, o tipo de setor, a presença de eventos geopolíticos — e cada algoritmo procura tipos diferentes de padrões. Depois que o algoritmo tiver encontrado o melhor padrão possível, usará esse padrão para fazer previsões para amanhã — como por exemplo, os preços de amanhã.
De posse dessa informação, podemos partir para as classes de problemas que os algoritmos de treinamento supervisionados estão incluídos. Muito embora existam vários sabores (tipos) de algoritmos, os mais comumente utilizados e que resolvem uma ampla gama de problemas são:
- Classificação. Comumente utilizado quando se pretende utilizar uma massa de dados para encontrar classes de respostas. Por exemplo: dada uma imagem, precisamos identificar se a mesma refere-se a um animal ou a uma pessoa ou ainda, dado um nome como entrada, precisamos saber se trata-se de um nome masculino ou feminino. Algoritmos de classificação são subdivididos em dois outros pilares: “classificação binomial” ou “duas classes” (quando apenas duas possibilidades são consideradas como resposta) ou “classificação multiclasse” (quando existem n possibilidades de saída).
Figura 4. Representação gráfica da resposta de um algoritmo de classificação binomial supervisionado
- Regressão. Lembra quando falamos acima sobre “predição de valores” de ações? Então, este é um caso clássico de algoritmo de regressão. Utilizado para se prever determinada situação mediante séries históricas.
Figura 5. Representação gráfica da resposta de um algoritmo de regressão linear
Como é possível verificar, no caso do exemplo apresentado pela Figura 5, através do algoritmo de regressão linear aplicado, uma linha é plotada entre a série histórica com o objetivo de encontrar o padrão de temperatura. Assim, seria possível prever com boa margem de acerto, a temperatura do dia seguinte. Vale observar entretanto que, muito embora a regressão linear seja um algoritmo viável e eficiente para vários cenários, ele é bem simplista, o que faz com que ele seja uma escolha ruim para cenários mais complexos.
- Recommenders. Como o próprio nome sugere, tratam-se de algoritmos que olham para as séries históricas e tentam recomendar algum comportamento. Por exemplo: Dado que um usuário está comprando um XBox One, baseado no histórico de compras de outros usuários, o que eu poderia recomendar para que ele compre junto? Um jogo talvez? Este tipo de algoritmo está muito presente em nossas vidas através de diversos serviços online, como por exemplo a recomendação de filmes do Netflix, a recomendação de produtos frequentemente comprados juntos em diversos e-commerces, além de muitos outros.
- Anomaly detection. Em determinadas situações pode ser muito útil identificar comportamentos anormais. Por exemplo, ao se projetar um sistema inteligente para detecção de fraudes bancárias, a detecção de transações fora do padrão pode ser um indício forte de que tais transações são ilegais e portanto, o sistema poderia automaticamente bloquear a origem das mesmas. Nesse sentido, os algoritmos de detecção de anomalias, como o próprio nome sugere, visam identificar aqueles pontos que são anormais, “fora da curva”, como diz a expressão popular.
Figura 6. Representação gráfica da resposta de um algoritmo de detecção de anomalias
Como é possível observar no gráfico apresentado pela Figura 6, o conjunto de pontos em amarelo indicam o comportamento padrão, enquanto os pontos representados em azul representam os comportamentos não usuais, podendo indicar fraudes ou outro aspecto que se queira analisar.
Aprendizado não supervisionado
No aprendizado “não supervisionado”, os pontos de dados não têm rótulos associados a eles. Em vez disso, a meta de um algoritmo de aprendizado sem supervisão é organizar ou agrupar os dados de alguma forma ou descrever sua estrutura. Isso pode significar agrupá-los em clusters ou encontrar diferentes maneiras de consultar dados complexos para que eles pareçam mais simples ou mais organizados.
Como escolher o melhor algoritmo e configurá-lo de maneira adequada?
Falamos há pouco sobre a importância de se conhecer as maneiras como máquina pode “aprender”. Falamos dos algoritmos mais utilizados e dos resultados que conseguimos obter com a aplicação dos mesmos. Entretanto, o sucesso de um experimento não está apenas na aplicação dos algoritmos. Em muitos casos, a configuração do processo de execução dos mesmos é tão ou mais importante que o algoritmo aplicado à massa de dados em si. Por isso mesmo, antes de partir para a construção do modelo de dados, é preciso entender de maneira mais clara quais são os fatores que realmente interferem na eficiência do algoritmo.
Evidente que, para quem está mexendo com machine learning pela primeira vez, responder à pergunta “Como escolher o melhor algoritmo?” não será e fácil e talvez a resposta inicial será: “tentativa e erro” :-). Entendo os motivos da resposta, entretanto, é claro que esta não é a melhor estratégia, certo? Além de uma enorme perda de tempo testando algoritmo por algoritmo, é fundamental saber o que está sendo feito para que o experimento que se está criando seja bem sucedido e se aproxime o máximo possível dos resultados esperados.
Felizmente não estamos no escuro quanto a nenhum dos dois pontos levantados acima. Tanto para o processo de configuração dos algoritmos quanto para a escolha do que melhor se adéqua as necessidades do sistema, existem ótimos textos elucidativos na documentação do Azure ML dando excelentes insights sobre ambos os processos. Existem aspectos que, se bem entendidos e executados, podem ser extremamente úteis durante o processo de escolha e aplicação dos algoritmos no experimento. São eles:
- Precisão;
- Tempo de treinamento da rede neural;
- Linearidade;
- Número de parâmetros;
- Número de recursos;
Ao invés de passar por cada um destes aspectos aqui neste artigo, vou recomendar que você faça um estudo cuidadoso do tema na documentação oficial do Azure ML. Os exemplos lá estão super claros e toda a explicação está em português. Para isso, basta seguir este link.
Adicionalmente, existe um fluxograma criado pelo time do Azure ML que pode ajudar bastante na escolha do melhor algoritmo. É importante deixar claro que, sem conhecer o modus operandi de cada algoritmo, este fluxograma não será lá muito útil a você, entretanto, assumindo que você leu a descrição dos principais algoritmos que descrevi neste post e ainda verificou mais informações na documentação oficial do Azure ML, sim, este documento poderá ser muito útil na criação de seus experimentos. Para ter acesso ao mesmo, basta seguir esse link.
Etapa 3 – Criando e formatando o experimento
De posse de todas as informações preliminares a respeito do Azure Machine Learning, passamos então para a criação de fato de nosso experimento. Para isso, como primeiro passo, você precisa criar o serviço de machine learning dentro de sua assinatura do Azure. Para isso, uma vez logado no portal, navegue até “New” > Digite “Machine learning” no campo de busca. No resultado da mesma, selecione “Machine Learning Workspace” e na blade que se abre, clique em “Create”. Preencha os dados solicitados na blade de configuração. Ao final, seu workspace deverá ser semelhante aquele apresentado pela Figura 7.
Figura 7. Workspace para o ArdaML
Você precisa necessariamente criar um Machine Learning Workspace (MLW) por alguns motivos. O primeiro deles: cobrança. As requisições ao serviço de machine learning são cobradas ao passarem pelo fabric de billing do Azure, dessa maneira, o serviço precisa ser alocado em sua subscription e isso é realizado através do MLW. Outra razão é que o MLW exige um storage account para guardar alguns arquivos de operação interna, datasets, logs, algoritmos personalizados e anotações que você por ventura venha criar no Azure ML Studio. Ao criar o workspace, este storage account já será criado e configurado para o serviço. Além disso, o acesso ao Azure ML Studio é concedido no momento em que cria o MLW.
Com o MLW criado, tínhamos então o que precisávamos para iniciar a construção do experimento de ML. Fomos então ao Azure ML Studio (disponível em https://studio.azureml.net), nos logamos e partimos para a criação do experimento. Iniciamos adicionando a conexão com a fonte de dados (lembra das views que criamos lá no início desse artigo?). Para isso, na interface do Studio, navegamos até a opção “+ New”, localizada à esquerda na barra inferior. Na blade que se abriu, clicamos em “Experiment”, em seguida “Blank experiment”. Ao final, visualizamos uma tela com o conteúdo central com o desenho de um fluxograma, sugerindo ao usuário a criação de seu fluxo analítico e à esquerda, um menu com diversas opções em termos de funcionalidades. Veja a Figura 8.
Figura 8. Um experimento recém criado através do Azure ML Studio
Com o experimento criado, iniciamos então a criação do nosso fluxo de análise adicionando um componente “Import Data” (disponível no menu “Data Input and Output”), para que a conexão com a base de dados pudesse ser estabelecida. O componente Import Data tem o poder de, a cada vez que o experimento é executado, se conectar a fonte primária de dados e importar as informações para o contexto do machine learning para análise. Em nosso caso, ele trará o conteúdo da view a cada execução. É dentro dele também que configuramos toda a conexão com a view, como é possível visualizar na Figura 9. Como a conexão é realizada diretamente com a fonte de dados de produção, os dados da análise estarão sempre atualizados em tempo experimento, é importante deixar claro.
Figura 9. Configurando a conexão do Import Data com o banco de produção onde as views foram criadas
A Figura 9 apresenta alguns elementos importantes. Do lado esquerdo temos o destaque em vermelho para o componente Import Data recém adicionado como primeiro elemento de nosso fluxo. Clicando sobre ele temos a exibição das opções apresentadas do lado direito da imagem, isto é, as informações de conexão ao banco de dados. Como trata-se de um SQL Azure Database, selecionamos esta opção e na sequência adicionamos informações de servidor, usuário, senha e a query que retorna os dados para serem importados. Simples, não?
Uma observação importante é: se seu experimento não precisa ser constantemente atualizado a cada ciclo de execução, você pode optar por fazer cache do dataset de entrada. Para isso, basta selecionar a opção “Use cached results”. Isso adiciona uma performance considerável em termos de tempo computacional do processo.
Para verificar se os dados estão sendo retornados corretamente, você deve clicar com o botão direito na saída do componente (localizada imediatamente abaixo do componente) e selecionar a opção “Visualize”, conforme ilustra a Figura 10. Esse é um procedimento padrão para que você visualize a saída dos elementos de seu fluxo de análise.
Figura 10. Visualizando o retorno da execução do componente
Em nosso caso, ao pedir para visualizar os dados retornados, tivemos o mesmo retorno do SQL, o que indica o sucesso do processo de importação. Primeiro passo de nosso fluxo concluído com sucesso ;-).
Os dados estão importados, entretanto, precisamos aplicar uma transformação nos mesmos antes de aplicarmos os algoritmos de ML neles. Isso porque precisamos remover as chamadas “informações ruidosas” que sempre estão presente em uma série de dados histórica. Para isso, adicionamos um componente chamado “Apply SQL Transformation”, disponível em “Data Transformation” > “Manipulation”. Basicamente você poderá escrever uma query SQL para limpar os dados retornados. Simples assim. Em nosso caso, como a série de dados é bem simples, precisamos apenas remover alguns usuários inativos do retorno da importação. Essa remoção fará com que as análises não sejam “viciadas” em dados inverídicos. A Figura 11 apresenta o elemento adicionado recebendo a entrada dos dados importados junto com a configuração do mesmo.
Figura 11. Aplicando a transformação nos dados retornados da importação
Pronto. Dados transformados. Para verificar se tudo está funcionando conforme o esperado, precisamos visualizar o retorno deste processo. A Figura 12 apresenta a visualização destes dados (o procedimento para isso já foi mencionado anteriormente).
Figura 12. Visualizando os dados transformados
Pesquisando um pouco sobre melhores práticas de criação de modelos de análises de dados, descobrimos que uma boa prática trata-se da normalização das colunas das massa de dados retornada para posterior treinamento dos algoritmos de machine learning. Nessa etapa, é possível ajustar os metadados retornados para que o algoritmo possa ter um melhor desempenho no processo de análise. Por exemplo, é possível converter um dado tipicamente inteiro para string, se isso fizer sentido para o processamento do algoritmo ou então, é possível dizer que uma determinado retorno deve ser considerado como uma “categoria” (sim, isso pode fazer com que o desempenho do algoritmo seja bem mais eficiente, especialmente se for um algoritmo de classificação).
Em nosso caso, estamos trabalhando justamente com algoritmo de classificação e portanto, houve a necessidade de fazer uma transformação do tipo categoria (veja o destaque na Figura 13) para todas as três colunas de nosso dataset, uma vez que os dados retornados vieram todos em formato de string. Para fazer isso, apenas selecionamos as colunas que queremos submeter para análise (clicando no botão “Launch column selector”), dispensamos qualquer transformação de metadata selecionando a opção Datatype como “Unchanged” e aí sim, para o parâmetro Categorical, selecionamos a opção “Make categorical”. A Figura 13 apresenta este processo de configuração.
Figura 13. Ajustando metadata dos dados antes da submissão do processo de análise
Ok. Já temos os processos de refino dos dados de que precisamos prontos (conhecido como Data Munging que, de forma geral, é o processo mais demorado e trabalhoso de um experimento de machine learning). Agora iremos iniciar o processo de “treino” de nossa árvore de decisão mas antes, precisamos fazer um “split” dos dados. Isso para que nós, humanos, em tempo de experimento, possamos verificar a eficiência dos resultados retornados pelo algoritmo. Este processo de split de dados para o treinamento é fundamental por um aspecto principal: como consigo validar se uma informação é verdadeira se não tenho parâmetro de comparação? Se submetermos 1oo% dos dados para treinamento, como seremos capazes de fazer a permutação dos resultados com uma base real? Este é o porque precisamos dividir.
Mas agora, para que isso seja possível, iremos utilizar um componente chamado “Split Data”, disponível em “Data Transformation” > “Sample and Split” > “Split Data”. A Figura 14 apresenta o elemento adicionado e configurado.
Figura 14. Adicionando e configurando o “Split Data”
Como o próprio nome sugere, o componente Split Data tem a finalidade de dividir os dados em duas saídas distintas. A primeira saída (representada pelo número 1 na Figura 14) servirá de entrada para o algoritmo que será escolhido. A segunda fração dos dados, servirá de entrada para o modelo de avaliação (veremos isso mais adiante neste post), representada pelo número 2 na Figura 14. Na configuração do componente, estamos fornecendo quatro informações super relevantes sobre o processo de split. São elas:
- Splitting mode: estamos dizendo que é para dividir a quantidade de linhas (Split Rows).
- Fraction of rows in the first output dataset: informamos o decimal 0.9, indicando 90% dos dados para o output de saída 1 com definição de “randomize” habilitada.
- Random seed: Um inteiro que representa a inicialização do algoritmo de randomização. Em termos computacionais, ele é o parâmetro útil para a eurística que divide os dados. O valor zero, em nosso caso, garante que a divisão será sempre linear.
- Stratified split: false. Isso porque para nosso caso específico a quantidade de dados divididos no output estão definidos em percentuais muito diferentes (90% e 10%).
Com a adição deste recurso, basicamente o que estamos fazendo é separar uma porção randômica de 90% dos dados do dataset para que estes sirvam como massa de treinamento da rede neural e, os outros 10%, para comparação com os resultados obtidos pelo processo de treinamento. Bacana, não?
Já temos todos os aparatos de que precisamos para fazer o treinamento de nossa rede neural e portanto, só nos resta partir para a execução do mesmo. Para isso, adicionamos um componente ao flow chamado “Train Model” (como o próprio nome sugere, tem a função de executar um modelo de treinamento para a rede neural). Como é possível observar na Figura 15, ele possui duas entradas entradas e uma saída, certo? Na entrada 1 (mais a esquerda) estamos adicionando o algoritmo de machine learning a que os dados serão submetidos pelo processo de treinamento. Na entrada 2 (mais a direita) estamos entrando com o dataset tratado (os 90% ao qual nos referimos anteriormente). O elemento circundado em vermelho à direita indica a saída “labelrizada” do processo de treinamento, isto é, dada uma “atividade” e uma “tecnologia”, quero saber quem é o “melhor profissional” para atender a esta demanda.
Figura 15. Adicionando um novo modelo de treinamento com suas entradas
Como é possível observar, o algoritmo que vamos utilizar em nosso experimento é “Multiclass Decision Forest”. Escolhemos este algoritmo por conta de três fatores básicos:
- Estamos tentando predizer categorias de dados, portanto, se encaixa perfeitamente no contexto de classificação (conforme já falamos anteriormente neste post) e ainda, no conceito de multiclass.
- Estamos buscando uma alta acuracidade da resposta.
- Estamos buscando performance nos testes.
Quando somados, estes aspectos dão os insumos de que precisamos para realizar o treinamento da rede neural. Para arrastar o componente que implementa o algoritmo, basta navegar até a opção “Machine Learning” > “Initialize Model” > “Classification” > “Multiclass Decision Forest”. Quando clicamos sobre o componente, podemos ver a configuração à direita, conforme apresenta a Figura 16.
Multiclass Decision Forest (ou simplesmente, MDF) é um algoritmo baseado em florestas de decisão com árvores menores dentro dela. Basicamente o que o algoritmo faz é, criar várias árvores menores dentro de uma “floresta mãe” e, através de um processo de votação, escolher aquela árvore que tem a saída de dados (classe) mais popular. Veja a Figura 17 para ter este conceito um pouco mais claro em sua cabeça.
Figura 17. O conceito por trás do Multiclass Decision Forest
Em termos de configuração do MDF, o componente traz requer basicamente seis parâmetros. São eles:
- Resampling method. Trata-se do método que o componente irá utilizar para criar as árvores de decisão dentro da floresta. Existem basicamente duas opções: Bagging e Replicate. Para saber mais detalhes sobre cada um destes métodos e o porque nossa escolha foi “Bagging”, por favor, siga este link com conteúdo em inglês.
- Create trainer mode. Trata-se da estratégia de treinamento para o algoritmo. Como você quer que o algoritmo seja treinado? Escolha entre “Single Parameter” e “Parameter Range”.
- Number of decision threes. Trata-se do número de árvores de decisões que serão criadas pelo algoritmo em tempo de execução. Quanto maior for o número de árvores de decisão criadas, maior a tende a ser a cobertura de testes em relação aos dados, entretanto, um preço computacional (lentidão) será pago.
- Maximum depth of the decision trees. Profundidade máxima em que o algoritmo fará a navegação. Importante observar que, quanto maior a profundidade da árvore de decisão, maior a precisão, entretanto, maior o tempo de resposta do algoritmo.
- Number of random splits per node. Quando os dados são distribuídos entre os nós da árvore de decisão, existe um threshold que determina a “randomicidade” na distribuição destes dados. Este parâmetro faz menção a isso.
- Minimum number of samples per leaf node. Este parâmetro diz respeito ao número mínimo de amostras que deve existir para que um nó seja criado na árvore de decisão.
Finalmente, adicionamos um elemento “Score Model” (veja a Figura 18).
Figura 18. Adicionando o Score Model ao fluxo do experimento
Como o próprio nome sugere, este elemento tem a função de “acumular” os resultados, tanto do processamento do MDF quanto dos 10% provenientes do Split Data (está lembrado?). Ele acumula essas duas entradas para que a comparação entre os resultados possa ser realizada pelo elemento seguinte (Evaluate Model). A Figura 19 apresenta o resultado do acumulo dessas informações.
Figura 19. Validando as informações devolvidas pelo Score Model
Agora que temos as entradas somadas e colocadas lado a lado, podemos finalmente avaliar nosso modelo. Para isso, adicionamos justamente um elemento final chamado “Evaluate Model”. Sua saída nos dará os insumos para realizar a comparação dos dados e posterior verificação de sucesso ou falha na execução do algoritmo. Pronto. Fluxo concluído.
Etapa 4 – Formatando a saída com Python
Esta é uma importante etapa do processo – a formatação da saída do resultado final. Se você é observador, já deve ter notado que as saídas oferecidas para os componentes são sempre datasets em formato de tabelas (veja as Figuras 19 e 12). O Azure ML Studio trabalha dessa maneira para que seja possível a ele efetuar as análises sobre os dados, entretanto, do ponto de vista de aplicação que irá consumir os dados gerados pelo machine learning, este nem sempre é o melhor modelo de retorno. As vezes, a aplicação deseja apenas exibir um resultado (como é o nosso caso) e portanto, precisamos formatar os dados de saída do machine learning.
Uma das vantagens do Azure Machine Learning é a flexibilidade. Ele entrega uma ampla gama de componentes built-in que já abstraem vários aspectos complexos de um experimento de ML (já utilizamos vários deles até aqui), entretanto, as vezes não existe algo que faça uma rotina específica de que precisamos no experimento e portanto, precisamos criar “nossos próprios” componentes. Felizmente o Azure Machine Learning dá suporte para isso e foi exatamente o que fizemos para formatar a saída de nossos dados. Veja a Figura 20.
Figura 20. Adicionando dois novos elementos no experimento preditivo
O que fizemos primeiro nesse sentido, foi remover o componente “Evaluate Model” (já que ele foi adicionado apenas para que pudéssemos realizar a comparação dos dados). Após isso, em seu lugar, adicionamos um componente chamado “Select Columns in Dataset” que, como o próprio nome sugere, tem a finalidade de oferecer a seleção de colunas no dataset de entrada (que neste caso, é o Score Model do qual já falamos anteriormente neste post). Olhando a configuração desse componente (Figura 21), vemos que temos 3 colunas selecionadas: activity, technology e Scored Labels, que é o resultado do processamento do algoritmo de fato (os percentuais de recomendação para cada cenário).
Figura 21. Colunas selecionadas para a próxima etapa do processo
Após isso, adicionamos um novo componente chamado “Execute Python Script” (ver Figura 22). O que este componente faz é nos dar o poder de, através de scripts Python, criar rotinas específicas para nosso experimento de machine learning. Ao clicar sobre o componente, você visualizará o script que criamos para formatar os dados (formato [profissional]:[taxa de recomendação]) e a possibilidade de selecionar a versão do framework Python disponível.
Figura 22. Adicionando o código Python que formata a saída dos dados
O código é bem simples. O único ponto aqui é entender um pouco o vocabulário do Python. Basicamente o algoritmo recebe o dataset de entrada, separa os dados e gera um array com os dados formatados e retorna este modelo ajustado. O código está disponível na íntegra através da Listagem 3.
Listagem 3. Algoritmo Python que formata a saída dos dados
Etapa 5 – Publicação do experimento (webservice)
Após verificar o correto funcionamento do experimento e ainda, formatarmos a saída, partimos então para a publicação do mesmo em ambiente produtivo através de uma API Rest. Esse processo também é realizado através do Azure ML Studio. A publicação é realizada em dois passos:
- Criar o experimento preditivo. Para isso, na tela do experimento que criamos, no menu inferior, clicamos na opção “Setup Web Service”, conforme apresenta a Figura abaixo.
Ao fazer isso, um submenu será exibido com duas opções: “Create predictive experiment” e “Retraining Web Service”. Selecione a primeira, para criar um novo experimento preditivo. Ao fazê-lo, você verá o Azure ML Studio criar uma nova aba chamada “Predictive Experiment”. Nesta nova aba, aparecerá um fluxo completo do experimento com entrada e saída de dados e, no menu inferior, a opção que antes era “Setup Web Service” agora é “Publish Web Service”. Este modelo novo criado, é o flow de produção que será executado cada vez que o serviço for requerido. Veja o experimento preditivo pronto para ser publicado na Figura 24.
Figura 24. O experimento preditivo IPR pronto para ser publicado
- Publicar o experimento preditivo. Uma vez que este processo foi concluído, partimos para a publicação do serviço clicando na opção “Deploy Web Service” no menu inferior da tela. Ao concluir esse processo, o Azure ML Studio publicou nossa API em um cloud service com Web Roles (ASM) pré-configuradas e nos deu uma tela com todas as informações sobre como consumir este serviço. Para visualizar esta tela, no menu principal à esquerda, navegue até a opção “Web Services”, representada pelo ícone do globo. Ao fazê-lo, você verá listados todos os experimentos produtivos já publicados. Basta clicar sobre o respectivo nome para visualizar as informações as quais nos referimos (veja a Figura 25).
Figura 25. Visualizando as informações
Todas as informações importantes estão nesta tela: endpoints, token de acesso, possibilidade de testes online, etc. Bacana não? Agora, é só criar um wrapper (se você quiser, é claro) para consumir a API. Dessa forma, a próxima seção deste artigo é justamente a construção deste wrapper.
Etapa 5 – Criando a IPR API
Chegou a hora do código :-). Como você já pôde constatar, o Azure ML Studio publica uma API REST para o experimento preditivo. Dessa maneira, o que fizemos foi criar um Web API baseado em ASP.NET Core 1.1 que se conecta na API do experimento preditivo passando os parâmetros que ela espera, obtém o resultado da API, faz o merge com as informações provenientes da view que calcula a disponibilidade de cada profissional (lembra quando a montamos no início do artigo?) o formata para JSON e na sequência, devolve para o chamador primário. Como a resposta será sempre em JSON, este conteúdo pode ser consumido por qualquer tipo de frontend, de aplicações para dispositivos móveis até aplicações Windows Form, etc. Bacana, não? O código da classe base pode ser visualizado através da Listagem 4.
Listagem 4. A classe “RecommenderController” que implementa as rotinas base do wrapper
Para visualizar os detalhes do código, por favor, visite o repositório do projeto no GitHub, disponível nesse endereço: https://github.com/DXBrazil/Arda.Intelligence. Após isso, publicamos este projeto ASP.NET Core que implementa o wrapper em um API App no Microsoft Azure. Este post irá assumir que você conheça este processo de publicação e não cobrirá o mesmo, entretanto, se este assunto é novo pra você, por favor, siga este link para iniciar seus estudos. Assim, podemos testar de maneira prática o funcionamento do recurso, via postman (ou outra ferramenta qualquer para teste de HTTP requests) ou Swagger.
Lembrando que você pode encontrar mais informações sobre a API, seguindo este link: http://ardaintelligenceapi.azurewebsites.net/.
E então? Gostou? Ajude-nos a evoluir tanto a API de inteligência quanto o Arda em sí. Fica o convite.
Até a próxima!
Facebook
Twitter
Instagram
LinkedIn
RSS