Utilização de modelos de classificação com Flask

Ferdinando de Melo
5 min readAug 6, 2021

--

Já pensou em utilizar o seu modelo de predição com uma API simples? É possível e bem fácil…

Modelos de classificação

Um modelo de classificação é simplesmente um modelo matemático que a partir da entradas de dados, é possível rotular esses dados com labels previamente treinadas pelo algoritmo utilizado. Para este artigo utilizaremos os modelos XGBoost e RandomForest

Eu ensino como criar os modelos utilizados nesse artigo e quais dados serão necessários para a predição aqui. Esses modelos indicam se um paciente possui ou não Diabetes através de alguns dados informados.

Organização da entrada de dados

Para uma melhor organização da entrada de dados, criaremos uma função que calcula os dados faltantes para o modelo e retira os dados desnecessários informados. Essa função retornará uma “Exception” se algo não estiver como o esperado ou um dicionário com os dados prontos para utilização do modelo desejado.

Como os dados foram criados com a base de medidas Imperial, é necessário a conversão de alguns dados e outros são informados para criação de outras entradas. Como é o caso do campo “Altura”, ela é utilizada para criação do campo “IMC” que indica a massa corpórea do paciente.

def resquest_conversors(dic: dict) -> Union[Type[Exception], dict]:
"""Realiza a conversão dos parâmetros de entrada para a mesma unidade utilizada no modelo
>>> resquest_conversors({'colesterol_ruim': 193, 'glucose': 400, 'colesterol_bom': 49, 'idade': 19, 'peso': 119, 'altura': 1.55, 'pressao_arterial': '118x70', 'cintura': 81.28})
{'colesterol_ruim': 193, 'glucose': 400, 'colesterol_bom': 49, 'idade': 19, 'peso': 262, 'cintura': 32.0, 'imc': 49.5, 'pressão_sistolica': 118, 'pressão_diastolica': 70}
>>> resquest_conversors({'colesterol_ruim': 193, 'glucose': 77})
<class 'Exception'>"""
KEYS = ['colesterol_ruim', 'glucose', 'colesterol_bom', 'idade', 'peso', 'pressao_arterial', 'cintura'] for key in KEYS:
if key not in dic.keys():
return Exception

"""Calcula IMC"""
dic['imc'] = round(dic['peso'] / (dic['altura'] ** 2), 1)

"""Converte kilos para libras"""
dic['peso'] = int(float(dic['peso']) * 2.20462262185)

"""Retira altura"""
try:
dic.pop('altura')
except:
return Exception

"""Converte a pressão arterial em sistólica e diastólica além de retirar o campo do dicionário original"""
if 'X' in dic['pressao_arterial']:
pressao_list = str(dic['pressao_arterial']).split("X")
else:
pressao_list = str(dic['pressao_arterial']).split("x")
try:
dic.pop('pressao_arterial')
dic['pressão_sistolica'] = int(pressao_list[0])
dic['pressão_diastolica'] = int(pressao_list[1])
except:
return Exception

"""Converte a cintura de centimetros para inches"""
dic['cintura'] = round(dic['cintura'] / 2.54, 0)

"""Reorganizar o dicionário recebido para ficar igual ao DataFrame do modelo"""
response_dict = {'colesterol_ruim': dic['colesterol_ruim'], 'glucose': dic['glucose'],
'colesterol_bom': dic['colesterol_bom'], 'idade': dic['idade'], 'peso': dic['peso'],
'cintura': dic['cintura'], 'imc': dic['imc'], 'pressão_sistolica': dic['pressão_sistolica'],
'pressão_diastolica': dic['pressão_diastolica']}
return response_dict

Construindo com Flask

Para usar o Flask é simples, só necessário instala-lo em seu ambiente virtual com “pip install Flask”.

Com o Flask instalado, a sua aplicação só precisa indicar as rotas de entrada e essas rotas serão funções que devolverá o que for designado.

Primeiro, vamos criar uma rota que indica quais são os modelos disponíveis para o cliente e instaciar o Flask para utilização dessas rotas. Como falado anteriormente, iremos usar os modelos criados no artigo anterior: XGBoost e RandomForest.

from flask import Flask, request, jsonify
import pandas as pd
from werkzeug.exceptions import abort
MODELOS = ['xgboost', 'rdf']"""Instância do Flask"""
app = Flask(__name__)
"""Possíveis Erros"""
@app.errorhandler(404)
def resource_not_found(e):
return jsonify(error=str(e)), 404
@app.errorhandler(500)
def internal_error(error):
return {"erro": "Dados invalidos"}
@app.route('/modelos', methods=['GET'])
def get_models():
return {'modelos': MODELOS}

Agora, todos que acessarem a sua URL no contexto “/modelos” irá receber uma lista com os modelos disponíveis. E eles poderão chamar cada modelo pelo nome passado nessa resposta.

Para configurar as rotas para os modelos disponíveis também é simples, basta indicar o modelo no decorator “@app.route()” e setar o que cada modelo deve responder.

# Rota para o modelo XGBoost
@app.route(f'/{MODELOS[0]}', methods=['POST'])
def xgboost():
try:
content = request.json
content_convertido = resquest_conversors(dict(content))
print(content_convertido)
pred_test = str(xgb.predict(pd.DataFrame.from_dict([content_convertido]))[0])
if pred_test == "1":
json_resp = {"diabetes": "sim", "code": 1}
else:
json_resp = {"diabetes": "nao", "code": 0}
json_resp['estimator'] = "XGBoost Classifier"
print(json_resp)
return json_resp
except:
abort(500)

# Rota para o modelo RandomForest
@app.route(f'/{MODELOS[1]}', methods=['POST'])
def random_forest_classifier():
try:
content = request.json
content_convertido = resquest_conversors(dict(content))
print(content_convertido)
pred_test = str(rdf.predict(pd.DataFrame.from_dict([content_convertido]))[0])
if pred_test == "1":
json_resp = {"diabetes": "sim", "code": 1}
else:
json_resp = {"diabetes": "nao", "code": 0}
json_resp['estimator'] = "Random Forest Classifier"
print(json_resp)
return json_resp
except:
abort(500)

Nos casos acima, se o modelo devolver “1” nos dados do array de resposta, o nosso programa irá montar um JSON com os seguintes dados “{“diabetes”: “sim”, “code”: 1}”. A aplicação que está utilizando o serviço pode decidir qual campo da resposta irá usar para informar o usuário.

Tudo pronto, agora só precisa indicar como o Flask será executado no seu ambiente. Por default, o Flask roda na porta 5000

# Inclua no final do seu código para configurar a aplicação Flask
if __name__ == "__main__":
app.run(host='0.0.0.0')

Consumindo a API

Para utilização dessa “API”, criei uma aplicação mobile simples que poderia ser um formulário em aplicação desktop ou em uma página web.

Na primeira tela da aplicação, é verificado quais são os modelos disponíveis.

Tela com os modelos disponíveis

Selecionando o modelo desejado, o usuário é levado para uma formulário para preencher os dados necessários para a predição.

Formulário para preenchimento
Formulário preenchido

Com os dados preenchidos, é enviado uma solicitação para verificação se o paciente possui ou não Diabetes conforme resposta do modelo.

Resultado com a resposta do modelo

Conclusão

Com a construção de end-point como o demonstrado aqui, fica simples incluir mais opções de modelos e tratar a resposta no front-end.

Nesse caso foram utilizados modelos previamente construídos para classificação de pacientes com Diabetes, mas seria possível a utilização desse conceito para verificação de crédito, estimativa de valores ou qualquer outro tipo de problema preditivo com Machine Learning.

Você pode encontrar o código completo em:

Aplicação Back-End Flask = https://github.com/feoc10/DiagnosticoDiabetes

Aplicação Front-end Android= https://github.com/feoc10/DiagnosticoDiabetesAppAndroid

--

--

Ferdinando de Melo
Ferdinando de Melo

Written by Ferdinando de Melo

Python enthusiast and a data scientist lover

No responses yet