Formando uma amostra de dados de treinamento com mudança de distribuição

Aviso Legal: Este artigo é um produto traduzido de Max Halforda . A tradução não é limpa, mas adaptativa. De forma que haja entendimento em qualquer linha de conhecimento.







“Meus amigos e eu recentemente nos classificamos para a final do Data Science Game 2017. A primeira parte da competição foi o Kaggle com um conjunto de dados do Deezer (1). O problema consistia em resolver o problema da classificação binária: era necessário prever se o usuário iria passar a ouvir a composição que lhe era oferecida.



Como outras equipes, extraímos os recursos relevantes e treinamos o classificador XGBoost (2). No entanto, fizemos uma coisa especial, uma subamostra do conjunto de dados de treinamento, para que ele (o conjunto de dados de treinamento) se tornasse mais representativo do conjunto de teste. "




Um dos requisitos básicos para o processo de aprendizado para a operação bem-sucedida de um modelo de máquina é a mesma natureza das distribuições nos conjuntos de dados de treinamento e teste. Um exemplo aproximado: o modelo foi treinado em usuários de 20 anos de idade e, na amostra de teste, os usuários têm mais de 60 anos.



Aqui, é intuitivamente natural que, com a idade em que o modelo não foi treinado, ele não resista. Claro, tal exemplo é puramente sintético, mas na realidade, para diferenças significativas, é suficiente treinar o modelo para mais de 20 anos e tentar fazê-lo funcionar para mais de 30 anos. O resultado será semelhante.



Isso ocorre porque os modelos aprendem as distribuições (3) dos dados. Se as distribuições de um recurso nos conjuntos de treinamento e teste forem iguais, o modelo agradecerá.



Inserção do tradutor: Quando me sentei para traduzir, tive uma pergunta: por que o treinamento deveria ser adaptado ao teste, porque, na verdade , o teste reflete dados invisíveis que entrarão no modelo como entrada para a produção. Então dormi demais, reli e tudo passou. O truque é que, sob a influência de fatores, a retrospectiva pode se tornar irrelevante para o presente. Mais sobre isso posteriormente (exemplo ligeiramente readaptado).



O enviesamento nas distribuições de um recurso pode ocorrer por vários motivos. O exemplo mais intuitivo pode ser emprestado do Facebook.



Digamos que uma empresa foi treinada em um modelo baseado em um recurso (um recurso é o mesmo que um recurso) como um passatempo em minutos. Deixe-o prever sinteticamente o nível de lealdade do usuário em uma escala de dez pontos.



Quando ocorreu a divisão do aplicativo geral do Facebook na rede social principal (feed etc) e no sistema de mensagens, o tempo no aplicativo principal diminuiu, ou seja, os conjuntos de dados recebidos mudaram e não correspondiam mais à retrospectiva anterior.

Matematicamente, tendo em conta a característica de tempo, o modelo irá prever um nível de fidelização inferior, embora na realidade não seja o caso - a transferência de tempo foi simplesmente dividida em duas aplicações. Sai com tristeza.



Assim, uma mudança de distribuição ocorre quando a distribuição de dados históricos se torna irrelevante para prever novos dados.



No conjunto de dados do Deezer, a inconsistência das distribuições estava no recurso de medição do número de músicas ouvidas antes de resolver o problema de previsão. Em ambos os conjuntos de dados públicos e de teste, esse recurso teve uma distribuição exponencial (4). No entanto, no conjunto de dados de teste foi mais pronunciado, de modo que a média no conjunto de treinamento foi menor do que no conjunto de teste. Após reamostrar a distribuição do treinamento, conseguimos aumentar a métrica ROC-AUC (5) e subir a classificação em cerca de 20 pontos.



Abaixo está um exemplo da diferença de distribuição:



import numpy as np
import plotly.figure_factory as ff

train = np.random.exponential(2, size=100000)
test = np.random.exponential(1, size=10000)

distplot = ff.create_distplot([train, test], ['Train', 'Test'], bin_size=0.5)
distplot.update_layout(title_text=' Test, Train')


" "



A ideia de nivelar a mudança de distribuição é remodelar a amostra de treinamento para refletir a distribuição de teste.



Vamos imaginar que queremos criar um subconjunto de 50.000 observações de nosso conjunto de treinamento para ajustar a distribuição do conjunto de teste. O que você quer fazer intuitivamente?



Faça com que os objetos que são mais comuns no conjunto de dados de teste também sejam comuns no treinamento! Mas como você pode determinar quais objetos são mais necessários e quais com menos frequência?



Libra!



As etapas serão mais ou menos assim:



  • divida a linha reta numérica de distribuição em intervalos iguais (ou cestas (caixas)
  • conte o número de objetos em cada cesta (tamanho da caixa)
  • para cada observação na cesta, calcule seu peso igual a 1 / (tamanho da caixa)
  • crie uma subamostra de k com uma distribuição ponderada (objetos com um peso maior aparecerão na subamostra com mais frequência)


Transferindo para o código, realizamos as seguintes ações:



SAMPLE_SIZE = 50000
N_BINS = 300

#   ,       .
#        
step = 100 / N_BINS

test_percentiles = [
    np.percentile(test, q, axis=0)
    for q in np.arange(start=step, stop=100, step=step)
]

#     . 
#    ,    
train_bins = np.digitize(train, test_percentiles)

#          i   ,
#  0      , 1    1    i 
train_bin_counts = np.bincount(train_bins)

#    ,        
weights = 1 / np.array([train_bin_counts[x] for x in train_bins])

#   ,     
weights_norm = weights / np.sum(weights)

np.random.seed(0)

sample = np.random.choice(train, size=SAMPLE_SIZE, p=weights_norm, replace=False)

distplot_with_sample = ff.create_distplot([train, test, sample], ['Train', 'Test', 'New train'], bin_size=0.5)
distplot_with_sample.update_layout(title_text=' Test, Train, New train')


" " A



nova distribuição (verde) agora corresponde melhor à distribuição da amostra de teste (laranja). Usamos ações semelhantes na competição - o conjunto de dados original continha 3 milhões de linhas, geramos o tamanho da nova amostra a partir de 1,3 milhão de objetos. Os dados ficaram menores, mas a representatividade da distribuição melhorou a qualidade do treinamento.



Algumas notas da experiência pessoal do autor:



  • O número de cestas não desempenha um grande papel, mas quanto menos cestas, mais rápido o algoritmo aprende (tente alterar o número de cestas (N_BINS) para 3, 30 no exemplo e você verá que a diferença é realmente pequena)
  • , , , “” , , .

    ( , “” , “” . . , )



O algoritmo de remodelagem está no github do autor (pasta xam ). No futuro, o autor planeja analisar novos tópicos e compartilhá-los no blog.



Espero que a tradução e as notas tenham sido úteis e claras. Aguardo seu feedback em um formato construtivo. Obrigado pelo seu tempo.



Notas de rodapé:



1. Deezer é um serviço francês de streaming de música online. Como Spotify, Ya Music e você entendeu



2. XGBoost- algoritmo de aumento de gradiente extremo. Eu simplesmente amei chamá-lo de “aumento de gradiente com esteróides”. A ideia de boosting é treinar vários alunos fracos homogêneos, cada um dos quais forma notas com base na experiência de aprendizagem retrospectiva do anterior, prestando atenção nas aulas em que o algoritmo anterior mais tropeçou. A ideia por trás de um gradiente é, em uma palavra simples, minimizar os erros de aprendizagem. XGBoost, como um algoritmo, é uma configuração mais benéfica computacionalmente do Gradient Boosting



3. Distribuição aqui significa exatamente o que descreve a lei pela qual os números são espalhados em uma variável.



4. Na minha opinião pessoal, o estímulo mais compreensível para a visualização exponencialdistribuição na cabeça é sua definição como distribuição, com intensidade constante.



5. ROC-AUC (Área sob a curva característica de operação do receptor) - a área sob a curva “características de processamento do receptor” - um nome literal, já que a métrica veio da teoria do processamento de sinal. A curva ROC é muito íngreme - demonstra a relação entre o verdadeiro positivo e o falso positivo das respostas do modelo, pois o limite de probabilidade de atribuição a uma classe muda, formando um “arco”. Devido ao fato de que a proporção de TP e FP é visível, é possível selecionar o limite ótimo de probabilidades dependendo dos erros de 1o e 2o tipo.



No caso de considerar a precisão do modelo, não atentando para o limiar probabilístico das respostas, é utilizada a métrica ROC-AUC, que assume valores na faixa [0,1]. Para um modelo constante com um equilíbrio de classes, o ROC-AUC será aproximadamente igual a 0,5, portanto, os modelos abaixo não passam na verificação de sanidade (verificação de sanidade). Quanto mais próxima a área sob a curva ROC de um, melhor, mas para indexar a utilidade dos resultados em geral, é relevante comparar o AUC-ROC do modelo treinado com o AUC-ROC do modelo constante.



All Articles