(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como criar amostras temporais para treino/teste em Python para dados

João Barros 13 de October de 2026 4 min de leitura

Aprende a criar amostras temporais para treino/teste em Python para dados — uma tarefa essencial para modelação de séries temporais que evita data leakage e garante validação realista. A técnica é útil para prever vendas, métricas web ou qualquer série em que a ordem cronológica seja importante.

Pré-requisitos

  • Python 3.8+ instalado
  • Pacotes: pandas, scikit-learn, numpy (instalar com pip se necessário)
  • Noções básicas de pandas e de treino/teste em machine learning

Passo 1: Porquê fazer a divisão temporal em vez de shuffle

Em dados temporais, embaralhar (shuffle) pode causar data leakage: informações do futuro entram no treino e inflacionam a métrica. A divisão temporal preserva a ordem cronológica — treino com dados mais antigos e teste com dados mais recentes.

Passo 2: Estrutura mínima de dados

Vamos começar com um DataFrame simples que tem uma coluna de datas e uma variável alvo. Garantimos que a coluna de datas está em datetime e ordenamos por ela.

import pandas as pd
import numpy as np

# Exemplo mínimo
np.random.seed(42)
dates = pd.date_range('2022-01-01', periods=100, freq='D')
value = np.random.randn(100).cumsum() + 50

df = pd.DataFrame({'date': dates, 'value': value})
# Converter e ordenar
df['date'] = pd.to_datetime(df['date'])
df = df.sort_values('date').reset_index(drop=True)
print(df.head())

Passo 3: Divisão simples treino/teste temporais (holdout)

Uma abordagem comum é usar uma percentagem final como teste (por exemplo, últimos 20%). Isto é simples e evita mistura temporal.

# Proporção de teste
test_size = 0.2
n = len(df)
split = int(n * (1 - test_size))

train = df.iloc[:split].reset_index(drop=True)
test = df.iloc[split:].reset_index(drop=True)

print('Train:', train['date'].min(), '->', train['date'].max())
print('Test:', test['date'].min(), '->', test['date'].max())

Passo 4: Validação temporal com rolling windows

Para avaliar a estabilidade do modelo, usamos cross-validation temporal (rolling/expanding window). Aqui criamos splits sequenciais em que cada fold treina em dados até um ponto t e testa num bloco futuro.

from sklearn.model_selection import TimeSeriesSplit

# Exemplo com TimeSeriesSplit (k folds)
X = df[['value']].copy()  # features fictícias
y = df['value']

tscv = TimeSeriesSplit(n_splits=5)
for i, (train_idx, test_idx) in enumerate(tscv.split(X)):
    print(f'Fold {i+1}: train {train_idx[0]}-{train_idx[-1]}, test {test_idx[0]}-{test_idx[-1]}')

Passo 5: Janela com avanço (walk-forward) e blocos de teste fixos

Se precisares de prever um horizonte fixo (p.ex. 7 dias), cria um gerador que devolve janelas em que o teste tem comprimento fixo e o treino expande ou desliza.

def rolling_windows(df, train_size, test_size, step=1):
    n = len(df)
    start = 0
    while True:
        train_end = start + train_size
        test_end = train_end + test_size
        if test_end > n:
            break
        yield df.iloc[start:train_end].reset_index(drop=True), df.iloc[train_end:test_end].reset_index(drop=True)
        start += step

# Exemplo
for i, (tr, te) in enumerate(rolling_windows(df, train_size=60, test_size=7, step=7)):
    print(f'Window {i+1}: train {tr.date.min().date()}->{tr.date.max().date()}, test {te.date.min().date()}->{te.date.max().date()}')

Passo 6: Evitar leaks com características baseadas no futuro

Ao criar características (lags, rolling means) garante que só usas informações até t-1 para prever t. Usa shift() em pandas para criar lags e evita funções que agreguem valores do futuro.

# Exemplo de lags e média móvel sem data leakage
df['lag_1'] = df['value'].shift(1)
df['rolling_7'] = df['value'].shift(1).rolling(window=7, min_periods=1).mean()
# Remover primeiras linhas com NaN resultantes
df_feat = df.dropna().reset_index(drop=True)
print(df_feat.head())

Verificar o resultado

Confirma que as datas do treino são sempre anteriores às do teste e que as características do treino não contêm valores do futuro. Verifica o tamanho dos conjuntos e imprime uma amostra das primeiras linhas depois de criar lags/rolling.

# Verificações rápidas
assert train['date'].max() < test['date'].min(), 'Data leakage: sobreposição temporal!'
print('Tamanhos: ', len(train), len(test))
print(df_feat[['date','value','lag_1','rolling_7']].head())

Conclusão

Dividir séries temporais corretamente é crítico para evitar data leakage e obter métricas realistas. Usa holdout temporal para testes simples, TimeSeriesSplit para validação mais robusta e rolling windows para avaliar a estabilidade ao longo do tempo. Próximo passo: treinar um modelo simples (ex.: RandomForest, XGBoost) usando os lags e validar com os splits temporais. Dica: visualiza sempre as datas e as janelas para garantir que não houve sobreposição.