Scikit Learn: Projetando o futuro de suas APIs e aplicativos usando machine learning

O FutureCast é um script em Python que utiliza regressão linear do Scikit-Learn para projetar valores futuros de APIs e aplicativos a partir de um banco de dados SQLite, permitindo uma melhor tomada de decisões e planejamento de operações.

[ Hits: 3.397 ]

Por: Leonardo Berbert Gomes em 16/04/2023 | Blog: https://www.linkedin.com/in/leoberbert


Projetando dados futuros



O primeiro bloco do código importa bibliotecas importantes para o script, como a biblioteca sqlite3 para se conectar ao banco de dados, a biblioteca pandas para manipular os dados, a biblioteca scikit-learn para realizar a regressão linear e a biblioteca logging para registrar eventos e erros.

Em seguida, o script configura o logger para criar logs das atividades da aplicação. Para isso, é criado um objeto logger e é definido o nível do logger como logging.INFO para indicar que o registro deve ser feito apenas em nível de informação. Em seguida, é verificado se a pasta logs já existe e, se não existir, é criada. O nome do arquivo de log é baseado no nome do script e é criado um manipulador de arquivos rotativos para o log, que é configurado para armazenar as mensagens de log diariamente. Por fim, o manipulador de arquivos é adicionado ao logger.

Em seguida, o script se conecta ao banco de dados usando o sqlite3.connect e cria a tabela api_projection se ela ainda não existir. Além disso, são criados índices na tabela api_projection para melhorar a performance das consultas futuras. Em seguida, é feita uma verificação para garantir que a tabela foi criada com sucesso. Se a tabela não existir, o script exibirá uma mensagem de erro e encerrará a execução.

O script itera sobre as 24 horas do dia e faz uma busca na tabela api_summary para realizar a projeção. Para cada hora, é feita uma consulta no banco de dados para obter todos os dados da tabela api_summary que correspondem à hora atual. Se não houver dados para a hora atual, o script exibe uma mensagem de aviso e passa para a próxima hora.

Caso haja dados disponíveis, o script converte a coluna "data" em um objeto datetime e cria uma coluna "valor" para armazenar o valor numérico do campo "total". Em seguida, os dados são agrupados por API, aplicação e a média horária dos valores é calculada para cada API e aplicação. Depois disso, são criadas colunas para o dia da semana e a hora do dia.

O próximo passo é ajustar um modelo de regressão linear para cada API e aplicação e prever os valores futuros para cada API e aplicação. As projeções são armazenadas em um dicionário e, em seguida, inseridas na tabela api_projection do banco de dados.

Por fim, o script fecha a conexão com o banco de dados e registra uma mensagem indicando que a aplicação foi concluída com sucesso. Se ocorrer algum erro ao estabelecer a conexão com o banco de dados, o script exibirá uma mensagem de erro e encerrará a execução.

Código fonte:

import warnings,sqlite3,os,datetime,logging,sys
warnings.filterwarnings('ignore', message='X does not have valid feature names')
import pandas as pd
from sklearn.linear_model import LinearRegression
from logging.handlers import TimedRotatingFileHandler

# Configurar o logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# Criar a pasta de logs, caso ela não exista
if not os.path.exists('logs'):
    os.mkdir('logs')

# Definir o nome do arquivo de log, baseado no nome do script
log_file = os.path.join('logs', os.path.splitext(os.path.basename(__file__))[0] + '.log')

# Configurar o manipulador de arquivos rotativos por dia
file_handler = TimedRotatingFileHandler(log_file, when='d', interval=1, backupCount=30, encoding='utf-8')
file_handler.setLevel(logging.INFO)

# Configurar o formato da mensagem de log
formatter = logging.Formatter('%(asctime)s - PID=%(process)d - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)

# Adicionar o manipulador de arquivos ao logger
logger.addHandler(file_handler)

# Conectar-se ao banco de dados
try:
    conn = sqlite3.connect('api_data.db')
    logger.info(f'Iniciando a conexão com o banco de dados ...')
    # Criar tabela api_projection
    conn.execute('''CREATE TABLE IF NOT EXISTS api_projection (
                        data TEXT,
                        application TEXT,
                        api TEXT,
                        total INTEGER
                    )''')
    conn.execute('''
    CREATE INDEX IF NOT EXISTS idx_data_projection ON api_projection (data)
    ''')

    conn.execute('''
    CREATE INDEX IF NOT EXISTS idx_api_projection ON api_projection (api)
    ''')

    conn.execute('''
    CREATE INDEX IF NOT EXISTS idx_application_projection ON api_projection (application)
    ''')
    cursor = conn.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='api_projection';")
    table_exists = cursor.fetchone() is not None
    if not table_exists:
        logger.error("Não foi possível criar a tabela api_projection.")
        sys.exit(1)

    # Iterar sobre todas as horas do dia
    logger.info("Realizando busca na tabela api_summary para realizar a projeção...")
    for hour in range(24):
        # Selecionar os dados da tabela de transações para a próxima hora
        query = f"""SELECT strftime('%Y-%m-%d %H:%M', data) as data, application, api, total
                    FROM api_summary
                    WHERE strftime('%H', data) = '{hour:02}'"""

        df = pd.read_sql_query(query, conn)

        # Verificar se o DataFrame está vazio
        if df.empty:
            logger.warning(f'Não existem dados para realizar a projeção para a hora {hour:02}:00:00.')
            continue

        # Converter a coluna "data" em um objeto datetime e criar uma coluna "valor" para armazenar o valor numérico do "total"
        df['data'] = pd.to_datetime(df['data'], format='%Y-%m-%d %H:%M')
        df['valor'] = pd.to_numeric(df['total'])

        # Agrupar os dados por API, aplicação e calcular a média horária dos valores para cada API e aplicação
        df_por_api_e_aplicacao = df.groupby(['api', 'application', 'data'])['valor'].mean().reset_index()

        # Criar colunas para o dia da semana e hora do dia
        df_por_api_e_aplicacao['dia_da_semana'] = df_por_api_e_aplicacao['data'].dt.dayofweek
        df_por_api_e_aplicacao['hora_do_dia'] = df_por_api_e_aplicacao['data'].dt.hour

        # Ajustar um modelo de regressão linear para cada API e aplicação e prever os valores futuros para cada API e aplicação
        projecoes = {}
        for api in df_por_api_e_aplicacao['api'].unique():
            for application in df_por_api_e_aplicacao['application'].unique():
                df_api_e_aplicacao = df_por_api_e_aplicacao[(df_por_api_e_aplicacao['api'] == api) & (df_por_api_e_aplicacao['application'] == application)]
                if not df_api_e_aplicacao.empty:
                    regressor = LinearRegression()
                    X = df_api_e_aplicacao[['hora_do_dia', 'dia_da_semana']]
                    y = df_api_e_aplicacao['valor']
                    regressor.fit(X, y, sample_weight=None)
                    valor_projetado = regressor.predict([[hour, datetime.datetime.now().weekday()]])
                    projecoes[(api, application)] = valor_projetado[0]
    # Inserir as projeções na tabela api_projection do banco de dados
        logger.info(f'Inserindo informações na tabela api_projection para a hora: {hour}')
        cursor = conn.cursor()
        for api, application in projecoes.keys():
            valor_projetado_int = int(round(projecoes[(api, application)]))
            data_projecao = datetime.datetime.now().replace(hour=hour, minute=0, second=0, microsecond=0).strftime('%Y-%m-%d %H:%M')
            cursor.execute("INSERT INTO api_projection (data, application, api, total) VALUES (?, ?, ?, ?)", (data_projecao, application, api, valor_projetado_int))
            conn.commit()
    # Fechar a conexão com o banco de dados
    conn.close()
    logger.info(f'Aplicação finalizada com sucesso!!!')
except sqlite3.Error:
    logger.error("Não foi possível estabelecer a conexão com o banco de dados.")
    sys.exit(1)

Perceba que será criado um diretório chamado logs onde o script for executado. O log bem intuivo para ajudar no entendimento:

2023-04-14 14:03:07,740 - PID=20208 - INFO - Iniciando a conexão com o banco de dados ...
2023-04-14 14:03:07,742 - PID=20208 - INFO - Realizando busca na tabela api_summary para realizar a projeção...
2023-04-14 14:03:07,754 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 0
2023-04-14 14:03:07,766 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 1
2023-04-14 14:03:07,778 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 2
2023-04-14 14:03:07,790 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 3
2023-04-14 14:03:07,805 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 4
2023-04-14 14:03:07,817 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 5
2023-04-14 14:03:07,829 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 6
2023-04-14 14:03:07,841 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 7
2023-04-14 14:03:07,890 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 8
2023-04-14 14:03:07,911 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 9
2023-04-14 14:03:07,931 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 10
2023-04-14 14:03:07,965 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 11
2023-04-14 14:03:07,987 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 12
2023-04-14 14:03:08,002 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 13
2023-04-14 14:03:08,014 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 14
2023-04-14 14:03:08,048 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 15
2023-04-14 14:03:08,063 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 16
2023-04-14 14:03:08,075 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 17
2023-04-14 14:03:08,103 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 18
2023-04-14 14:03:08,118 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 19
2023-04-14 14:03:08,130 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 20
2023-04-14 14:03:08,141 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 21
2023-04-14 14:03:08,150 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 22
2023-04-14 14:03:08,160 - PID=20208 - INFO - Inserindo informações na tabela api_projection para a hora: 23
2023-04-14 14:03:08,163 - PID=20208 - INFO - Aplicação finalizada com sucesso!!!


Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Projetando dados futuros
   3. Validação dos dados
   4. Visualização dos Dados
Outros artigos deste autor

Centralizando logs com Promtail + Loki + Grafana

Gerando gráficos sem mistérios no MRTG (Debian)

Monitorando a saúde do Apache (Prometheus + Grafana)

Rundeck - Um Poderoso Agendador de Tarefas

Crie um bot para Telegram e gerencie a escala de plantonistas

Leitura recomendada

PEP 8 - Guia de estilo para código Python

Como baixar fotos e vídeos do Instagram com Python

Embutindo imagens nos scripts Python para aplicações Tkinter

Como isolar seus projetos Python com virtualenv (ambiente virtual)

Desenvolvendo aplicações GUI simples em Python & Glade (PyGTK) com banco de dados SQLite

  
Comentários
[1] Comentário enviado por taracena em 29/04/2023 - 03:35h


Thanks for the information.. https://www.caregiverconnect.net/

[2] Comentário enviado por maurixnovatrento em 14/05/2023 - 20:47h


Bom artigo.

___________________________________________________________
Conhecimento não se Leva para o Túmulo.
https://github.com/mxnt10


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts