Coleção aprendizado
Separar treino e teste
Divide as linhas em duas tabelas reprodutivelmente e pode preservar a proporção de cada classe.
O que o bloco faz
Divide as linhas em duas tabelas reprodutivelmente e pode preservar a proporção de cada classe.
Antes de continuar
Termos que esta página usa, em poucas palavras. As definições completas estão no glossário.
- Amostra
- A parte da população que é de fato observada. Quando é sorteada com probabilidades conhecidas, permite estimar características da população e medir a incerteza dessa estimativa.
- Estrato
- Um grupo da população definido antes do sorteio (região, porte, turno), dentro do qual se sorteia separadamente. Estratificar garante que todos os grupos apareçam na amostra e costuma reduzir a variância quando as unidades de um mesmo estrato se parecem.
- Treino e teste
- Dividir os dados em uma parte para ajustar o modelo (treino) e outra, guardada, para medir o desempenho (teste). O teste só é honesto se o modelo nunca o viu durante o ajuste.
- Validação cruzada
- Repetir a divisão treino/teste várias vezes, cada vez deixando uma parte diferente dos dados de fora, e fazer a média do desempenho. Dá uma estimativa mais estável do erro em dados novos do que uma única divisão.
- Vazamento de dados
- Quando informação que não estaria disponível na hora de prever entra no ajuste do modelo, por exemplo dados do conjunto de teste usados para padronizar variáveis. O desempenho medido fica melhor do que o real.
Quando usar
Reserve um conjunto de teste antes do ajuste para estimar desempenho em linhas não usadas no treino.
Pressupostos
A estratégia de divisão respeita a dependência entre linhas:
aleatoriasupõe linhas independentes; com medidas no tempo o teste deve ser todo posterior ao treino (temporal), e com várias linhas do mesmo indivíduo, lote ou área nenhum grupo pode cair dos dois lados (grupo). Senão o teste mede memorização, não generalização (Roberts et al. 2017).Se falhar: Troque
estrategiaparatemporal(comordem) ougrupo(comgrupo) e use a mesma noml/tune.Na divisão
temporal, o teste representa o futuro em que o modelo será usado: o corte no tempo cai onde a proporção pede, com instantes empatados todos do mesmo lado.Se falhar: Se houver mudança de regime depois do corte, o teste mede também essa mudança; leia o desempenho junto do período.
Na divisão
grupo,proporcaoé a fração dos grupos; com grupos de tamanhos muito diferentes, a fração das linhas pode se afastar dela, e a estratificação por classe não é feita.Verificar:Agrupar e resumir
Se falhar: Conte linhas e classes por lado no
data/group_summarise; se uma classe faltar no teste, mude a semente ou a proporção.As saídas levam a proveniência (atributo
tr_ml_origem: papel treino/teste, um id da divisão e as impressões digitais das linhas do teste, com a contagem de cópias): ajustar no teste, ou numa tabela que junta treino e teste, é recusado; prever o teste com um modelo que viu linhas dele no ajuste é recusado; avaliar o treino, ou um teste misturado a linhas de fora, exigepermitir_treino— o vazamento treino-teste de Kaufman et al. (2012) barrado por construção. A marca sobrevive ao cache, a filtros e a colunas novas.Se falhar: Faça a divisão sempre no
ml/split, antes de qualquer escolha.A marca não cobre: juntar com o teste à direita (
data/joincom o teste como segunda tabela), remodelar (pivot_longer/pivot_wider), recriar a tabela à mão, reescrever ou tirar colunas da divisão, e dividir fora doml/split. Nesses casos os blocos seguem como sem marca.Se falhar: Divida primeiro e transforme cada lado depois; se precisar de uma dessas operações, mantenha o teste longe dos ajustes você mesmo.
O resultado depende da semente: outra semente muda a divisão, os folds ou o próprio ajuste, e com poucos dados a diferença pode ser grande.
Se falhar: Repita com outras sementes e leia a variação; não escolha a semente pelo resultado.
Configuração
resposta identifica a resposta; proporcao define a fração aproximada de treino; estratificar mantém classes nos dois lados; seed reproduz a amostra. estrategia respeita a dependência entre linhas: aleatoria (padrão) sorteia linhas; temporal põe no treino tudo até o instante da linha ⌊n · proporção⌋ na ordem de ordem (instantes empatados ficam juntos) e no teste o que vem depois; grupo sorteia ⌊G · proporção⌋ grupos inteiros de grupo, de modo que nenhum indivíduo, lote ou área aparece dos dois lados. Nas duas últimas, estratificar é ignorado.
Exemplo
d <- trama.ml::tr_ml_example("iris_binaria")
s <- trama.ml::tr_ml_split(d, resposta = "Species", proporcao = 0.75, seed = 42)
nrow(s$treino); nrow(s$teste)
# Dados com tempo: todo o teste é posterior ao treino.
e <- data.frame(dia = rep(1:20, each = 3), y = factor(rep(c("a", "b"), 30)), x = 1:60)
t <- trama.ml::tr_ml_split(e, resposta = "y", proporcao = 0.7, estrategia = "temporal", ordem = "dia")
range(t$treino$dia); range(t$teste$dia) # 1-14 e 15-20
Como interpretar
As saídas treino e teste não duplicam nem perdem linhas. A proporção final pode variar por arredondamento em cada classe.
Proveniência: o teste fica isolado por construção
As duas saídas levam uma marca (atributo tr_ml_origem, com o papel treino/teste, um id da divisão e as impressões digitais das linhas do teste) que sobrevive ao cache e a filtros ou colunas novas. A impressão é um hash (xxHash64) do conteúdo de cada linha nas colunas da divisão, guardado com a contagem de cópias — assim uma linha repetida que o sorteio pôs dos dois lados não é confundida com uma linha do teste que voltou ao treino. Todo modelo guarda as impressões das suas linhas de treino. Com isso:
- ajustar um modelo, o
ml/tuneou oml/nested_cvna saídatesteé recusado (tr_ml_error_test_leak), e também numa tabela que junta treino e teste (rbind,bind_rows,data/bind_rows), mesmo que ela venha com a marca de treino; - o
ml/predictrecusa prever o teste com um modelo que viu linhas dele no ajuste — por exemplo, ajustado na tabela inteira antes de dividir, ou numa cópia do teste sem a marca (tr_ml_error_test_leak) — e o teste de outra divisão com um modelo ajustado no treino desta (tr_ml_error_split_mismatch); ml/evaluate,ml/confusion,ml/roceml/pr_curverecusam previsões das linhas detreino, e também uma tabela marcada como teste que traz linhas de fora dele (previsões do treino juntadas às do teste, ou o teste repetido) (tr_ml_error_train_eval), a menos que se liguepermitir_treino— aí o resultado sai com a nota “avaliação no treino é otimista”.
Custo: em 100 mil linhas, calcular as impressões leva cerca de 1 segundo e ocupa uns 7 MB no modelo; os folds internos do ml/tune não as recalculam.
O que a marca não cobre
A marca é um atributo: só viaja quando a operação copia os atributos da tabela que o leva, e a impressão só confere quando as colunas da divisão continuam lá com os mesmos valores. Ficam de fora, por construção:
- juntar com o teste à direita —
data/joinouleft_join(outra, teste)ficam com os atributos deoutra, sem marca; - remodelar —
pivot_longer/pivot_widermudam o que é uma linha e as colunas; - recriar à mão — copiar os valores para uma tabela nova, exportar para planilha e ler de volta;
- reescrever ou tirar colunas da divisão — arredondar, converter para texto,
selectque remove uma coluna: as impressões deixam de conferir e só a checagem de papel continua; - dividir fora do
ml/split.
Nesses casos os blocos seguem como sem marca: não têm como saber de onde vieram as linhas, e o isolamento fica com você. Divida primeiro, no ml/split, e só então transforme cada lado.
Implementação
trama.ml::tr_ml_split()versão 0.5.7Implementação própria: sorteio estratificado pela classe (aleatoria); corte no instante da linha floor(n·proporção) na ordem do tempo, todas as linhas até ele no treino (temporal); sorteio de floor(G·proporção) grupos inteiros (grupo); proveniência por atributo e impressões digitais xxHash64 das linhas do teste (cli).
No código O bloco chama trama.ml::tr_ml_split(), em trama.ml/R/workflow.R:30.
A conta é implementada pelo próprio trama, sem um pacote R de referência por trás.
Referências
Teoria
- Kaufman, S.; Rosset, S.; Perlich, C.; Stitelman, O. (2012). Leakage in data mining: Formulation, detection, and avoidance. ACM Transactions on Knowledge Discovery from Data, 6(4), 1-21. doi:10.1145/2382577.2382579
- Roberts, D. R.; Bahn, V.; Ciuti, S.; Boyce, M. S.; Elith, J.; Guillera-Arroita, G.; Hauenstein, S.; Lahoz-Monfort, J. J.; Schröder, B.; Thuiller, W.; Warton, D. I.; Wintle, B. A.; Hartig, F.; Dormann, C. F. (2017). Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure. Ecography, 40(8), 913-929. doi:10.1111/ecog.02881
- Tashman, L. J. (2000). Out-of-sample tests of forecasting accuracy: an analysis and review. International Journal of Forecasting, 16(4), 437-450. doi:10.1016/S0169-2070(00)00065-0
Livro-texto
- Hyndman, R. J.; Athanasopoulos, G. (2021). Forecasting: Principles and Practice. 3. ed. Melbourne: OTexts, sec. 5.10. https://otexts.com/fpp3/tscv.html
- James, G.; Witten, D.; Hastie, T.; Tibshirani, R. (2021). An Introduction to Statistical Learning: with Applications in R. 2. ed. New York: Springer. doi:10.1007/978-1-0716-1418-1
- Kuhn, M.; Johnson, K. (2013). Applied Predictive Modeling. New York: Springer. doi:10.1007/978-1-4614-6849-3