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.394 ]

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

Rundeck - Um Poderoso Agendador de Tarefas

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

Instalando Apache, PHP e PostgreSQL no Slackware 12 (compilando)

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

Monitoramento de Comunicação - Blackbox Exporter(ICMP) + Prometheus + Grafana

Leitura recomendada

Python - Uma linguagem orientada a objetos

Port Scanner com Python

PEP 8 - Guia de estilo para código Python

Gerar Códigos QRCode com Python

Varredura de PING Utilizando o Python

  
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