• João Ataide

Previsão de adoções de animais com Prophet


 

Uma coisa que sempre me interessou, foi preservação ambiental, em especial nossa fauna, houve tempos que fui vegetariano, e devido a alguns problemas que não vem ao caso, hoje ajudo de outras formas, conscientizar a preservação e alimentar e dar carinho para aqueles animais de rua.


Ao pensar nisso lembro da minha universidade, onde nossa pedagoga, Hortência Pessoa, com outros colaboradores administram o projeto Unidos Pelas Patinhas, tal projeto retira os animais das ruas, em especial cachorro e gatos, os vacinam e cuidam até conseguirem alguém que os adote.


Instigado por isso, quando vi o projeto prático da Escola de Data Science do Carlos Melo, não perdi tempo em aplicar ferramentas de Machine Learning em especial o Prophet framework do Facebook aplicado a prevenção de entradas e saídas de animais de institutos como este.


No entanto, a iniciativa Unidos Pelas Patinhas, não possuem um vasto banco de dados organizado, desta forma usarei o dataset da Austin Animal Center. Essa instituição americana provê os serviços públicos de controle dos animais de rua ou os que se perderam dos seus donos, disponibilizando água, abrigo e apoio veterinário para os animais, trabalho muito parecido com a ONG brasileira.


Os dados providos pela instituição do dia 30 de abril de 2020, onde ele contém 117K entradas e 12 variáveis. Estes dados podem ser baixados diretamente no City o Austin Open Data Portal.


Quanto ao modelo utilizado, o Prophet, como já disse é um framework usado nos problemas do Facebook para lidar com séries temporais. Ou seja, é muito forte para lidar com problemas que tenham características de dados de longos períodos (meses ou anos), e que possuam o maior detalhamento histórico possível, com sazonalidades fortes e destacadas e possuindo feriados ou datas especiais conhecidas e tendência de crescimento não linear, que se aproxima de um limite. O framework usa um modelo de séries temporal decomposto, com três componentes principais, sendo eles:

Desta maneira, podemos unir os dois e analisar dentre os animais que entraram na organização, quanto foram adotados ou retornaram aos seus donos. Mas primeiros vamos conhecer seu dicionário de variáveis:

  • Animal ID - Número de identificação do animal

  • Name - Nome do animal

  • DateTime - Data e hora de entrada do animal

  • MonthYear - Mês e ano de entrada do animal

  • Date of Birth - Data de aniversário do animal.

  • Outcome Type - Tipo de resultado

  • Outcome Subtype - Subtipo de resultado

  • Animal Type - Espécie do animal

  • Sex upon Outcome - Sexo do animal

  • Age Upon Outcome - Idade após o resultado.

  • Breed - Raça do animal.

  • Color - Cor do animal


Assim, podemos ver a cinco primeiras entradas.


Podemos ver então, que cada entrada simboliza um animal que passou na instituição, por exemplo, o Animal A794011 de nome Chunck é um gato macho de 2 anos de idades e entrou no dia oito de maio de 2019 sendo adotado.


Além de entender os dados, antes mesmo de começar a implementação Prophet, efetuei uma análise exploratória identificando a presença de muitos dados nulos, como podemos ver aqui abaixo:


Além disto, fiz uma contagem dos tipos de resultado prováveis (Outcome Type ).


Desta forma, identifiquei que dos 117.416 para esta data, 445 animais foram adotados e infelizmente 6.7% sofreram eutanásia. Então devido então ao maior número de casos de adoção, realizei as prevenções com o modelo para os casos dos animais adotados ou retornaram aos seus donos.


É possível salientar que estas representações poderão ser utilizadas quaisquer filtros temporais como dados semanais e diários. Porém, para melhor apresentação neste artigo somente mostrarei os dados semanais, se tiver interesse de observar o trabalho completo o notebook comentado apresenta tais análises.


Como é a distribuição temporal semanal dos dados?

#gráfico semanaris
fig,ax=plt.subplots(figsize=   (10,5))adoptions_dd.resample('W').sum().plot(ax=ax)plt.show()


Pude ver então, que os dados apresentam uma certa constância de distribuição temporal, mesmo sem fazer o treino para separar as partes da série temporal, já é possível deduzir que estes dados apresentam certa tendência e sazonalidade, com uma presença pequena de ruído.


Primeiro foi necessário adicionar as datas de feriados dos Estados Unidos.


#adicionando datas de feriados nacionais do Estado Unidos
modelo=Prophet()modelo2.add_country_holidays(country_name="US")modelo2.fit(prophet_dd)

E então determinar qual período que analisaremos, adotado o valor de 52, o número de semanas em um ano.


#determinar o período
val_fut = modelo.make_future_dataframe(periods=52)

Com parâmetros todos os prontos, realizei as previsões.


# realizar a previsão para o período
forest = modelo.predict(val_fut)

Dessa maneira, podemos ver nossas séries de previsões para os dados semanais, realizando o plot desta.


#Visualizando as previsões
modelo.plot(forest, xlabel="Data", ylabel = "Adoções")


Mesmo já tendo uma noção dos componentes do modelo, realizei a separação, tais componentes podem ser vistas abaixo respectivamente tendência, feriados, finais de semana e férias:


# separar os componentes do modelo
modelo.plot_components(forest2)

Os componentes apresentados, demonstram uma tendência alta, no entanto, com futuro comportamento a linearização no final de 2019, além disso, pude ver a distribuição anual dos feriados, finais de semana e férias, no qual apresentaram que ocorre mais adoções em feriados, com uma maior sazonalidade para os finais de semana e as férias de verão, que ocorrem para o hemisfério no mês de julho.


Para confirmar se o meu modelo funcionou bem, utilizei como métrica de desempenho a validação cruzada para 365 dias, a qual utiliza toda a base de dados, como amostra de teste e treino, particionando e treinando achada interação, como na figura abaixo:




Obtendo então a seguinte tabela, que indica a adaptação dos dados em relação ao tempo, para os cinco primeiros períodos.


from fbprophet.diagnostics import cross_validation
df_cross = cross_validation(modelo, horizon = '365 days')
df_cross.head()


Além disso, foi necessário calcular as métricas de desempenho, como podemos observar nos cinco primeiros períodos apresentados abaixo.


from fbprophet.diagnostics import performance_metrics
df_per = performance_metrics(df_cross)
df_per.head()

Assim foi possível notar que o modelo apresentou uma excelente adaptação aos dados, como pode constatar no gráfico da métrica MDAPE (Median Absolute Percentage Error) abaixo:


from fbprophet.plot import plot_cross_validation_metric
figura = plot_cross_validation_metric(df_cross,metric = 'mdape')


Tal gráfico acima demonstra a adaptação do modelo aos dados, indicando uma excelente atuação, mesmo sendo um teste inicial, demonstra efetivamente que modelos preditivos podem ser aplicados a qualquer categoria de base de dados.


Saliento que o presente projeto tem finalidade didática, tendo em vista que este foi uma prática do curso. Porém, tal projeto mostrou-se claramente a eficiência do uso de técnicas preditivas, aplicado a quaisquer dados, a exemplo de casas de acolhimento de animais, veja o projeto completo no notebook.


Agradeço por ler até aqui, se quiser mais informações sobre tal projeto, entrar em contato comigo. Gostou do trabalho? Se sim, compartilha com os amigos. :)