Com a classe desequilibrada, tenho que usar a amostragem nos meus conjuntos de dados de validação / teste?

13

Sou iniciante em aprendizado de máquina e estou enfrentando uma situação. Estou trabalhando em um problema de lances em tempo real, com o conjunto de dados IPinYou e estou tentando fazer uma previsão de cliques.

O fato é que, como você deve saber, o conjunto de dados é muito desequilibrado: cerca de 1300 exemplos negativos (sem clique) para 1 exemplo positivo (clique).

Isto é o que eu faço:

  1. Carregar os dados
  2. Divida o conjunto de dados em três conjuntos de dados: A = Treinamento (60%) B = Validando (20%) C = Teste (20%)
  3. Para cada conjunto de dados (A, B, C), faça uma subamostragem em cada classe negativa para ter uma proporção de 5 (5 exemplos negativos para 1 exemplo positivo). Isso me deu três novos conjuntos de dados mais equilibrados: A 'B' C '

Em seguida, treino meu modelo com o conjunto de dados A 'e a regressão logística.

Minha pergunta é:

  1. Qual conjunto de dados eu tenho que usar para validação? B ou B '?

  2. Qual conjunto de dados eu tenho que usar para testar? C ou C '

  3. Quais métricas são as mais relevantes para avaliar meu modelo? O F1Score parece ser uma métrica bem usada. Mas aqui, devido à classe desequilibrada (se eu usar os conjuntos de dados B e C), a precisão é baixa (abaixo de 0,20) e o F1Score é muito influenciado por baixa recuperação / precisão. Seria mais preciso usar aucPR ou aucROC?

  4. Se eu quiser traçar a curva de aprendizado, quais métricas devo usar? (sabendo que o erro% não é relevante se eu usar o conjunto de dados B 'para validar)

Agradeço antecipadamente pelo seu tempo !

Saudações.

jmvllt
fonte

Respostas:

9

Ótima pergunta ... Aqui estão algumas respostas específicas para suas perguntas numeradas:

1)Você deve validar cruzadamente em B e não B`. Caso contrário, você não saberá o desempenho do seu equilíbrio de classes. Não faria mal cruzar a validação em B e B` e será útil com base na resposta a 4 abaixo.

2) Você deve testar em C e C` com base em 4 abaixo.

3)Eu ficaria com F1 e poderia ser útil usar o ROC-AUC e isso fornece uma boa verificação de sanidade. Ambos tendem a ser úteis com classes desequilibradas.

4)Isso fica realmente complicado. O problema é que o melhor método requer que você reinterprete como devem ser as curvas de aprendizado ou use os conjuntos de dados re-amostrados e originais.

A interpretação clássica das curvas de aprendizado é:

  • Overfit - As linhas não se encaixam ;
  • Roupa íntima - as linhas se juntam, mas com uma pontuação na F1 muito baixa;
  • Just Right - As linhas se juntam a uma pontuação razoável na F1.

Agora, se você estiver treinando em A` e testando em C, as linhas nunca se unirão completamente. Se você estiver treinando em A` e testando em C`, os resultados não serão significativos no contexto do problema original. Então, o que você faz?

A resposta é treinar em A` e testar em B`, mas também testar em B. Obtenha a pontuação F1 para B` onde você quer que seja, depois verifique a pontuação F1 em B. Depois faça seus testes e gere curvas de aprendizado para C. As curvas nunca se juntam, mas você terá uma noção do viés aceitável ... é a diferença entre F1 (B) e F1 (B`).

Agora, a nova interpretação de suas curvas de aprendizado é:

  • Superajuste - As linhas não se juntam e estão mais afastadas que F1 (B`) -F1 (B);
  • Underfit - As linhas não se juntam, mas a diferença é menor que F1 (B`) -F1 (B) e a pontuação F1 (C) está abaixo de F1 (B);
  • Correto - as linhas não se juntam, mas a diferença é menor que F1 (B`) -F1 (B) com uma pontuação de F1 (C) semelhante a F1 (B).

Geral : sugiro enfaticamente que, para as classes desequilibradas, você primeiro tente ajustar o peso da sua classe no seu algoritmo de aprendizado, em vez de sobre / sub-amostragem, pois evita todo o rigor moral que descrevemos acima. É muito fácil em bibliotecas como o scikit-learn e muito fácil de manusear código em qualquer coisa que use uma função sigmóide ou uma votação majoritária.

Espero que isto ajude!

AN6U5
fonte
Muito obrigado @ AN605. Isso é tão agradável de você ! Tenho algumas perguntas: Para o 4) - Quando você diz "treinar em A 'e testar em B'", você quer dizer validar? - "gerar curvas de aprendizado para C" e "a pontuação F1 (C) está abaixo / semelhante a F1 (B)". Eu acho que, para a curva de aprendizado, tivemos que plotar a métrica de erro para o conjunto de treinamento (A ou A 'aqui) e a métrica de erro apenas para o conjunto de validação (B ou B'). Você não está "validando" em C aqui?
jmvllt
Sobre o uso dos "pesos da classe", corrija-me se eu estiver errado (acabei de dar uma olhada rápida), mas esse truque envolve "modificar" a função de custo adicionando um coeficiente / peso "k" na frente do classe desequilibrada, certo? : 􏲏 Custo (h (x), y) = -y * k * log (h (x)) - (1-y) * log ((h (x)) Assim, o algoritmo deve considerar uma classificação incorreta da classe positiva como mais importante. Mas o problema é que "tenho que" usar o Apache Spark & ​​MLlib para criar todo o meu modelo. E não tenho certeza de que possa modificar facilmente minha função de custo com o spark. De qualquer forma, obrigado por seu tempo!
jmvllt
5

Para 1)e 2)você deseja

1) choose a model that performs well on data distributed as you 
   expect the real data will be 
2) evaluate the model on data distributed the same way

Portanto, para esses conjuntos de dados, você não precisa equilibrar as classes.

Você também pode tentar usar pesos de classe em vez de sub / superamostragem, pois isso cuida dessa decisão.

Pois 3)você provavelmente deseja otimizar usando qualquer métrica em que será pontuada (se for uma competição). Mas se isso não for considerado, todos esses modelos são boas escolhas. F1 pode ser influenciado pela baixa precisão, mas você deseja que isso seja capturado. É precisamente quando os modelos ingênuos (como adivinhar a classe majoritária) podem pontuar bem por algumas métricas que pontuações como F1 são relevantes.

Quanto a, 4)não há nada errado em mostrar a métrica em que você acaba otimizando.

jamesmf
fonte
Oi @jamesmf, obrigado por essa resposta legal. Para o F1Score, o problema que tive é que talvez eu queira me concentrar mais em eliminar o falso positivo mais do que o falso negativo. Seria correto adicionar um "peso" diferente para FP e FN na computação de precisão e recall?
jmvllt
Isso faz sentido para mim. Também sua descrição de ponderação de classe está correto, e eu não vê-lo implementado em MLIB, mas pode valer a pena um pedido de recurso
jamesmf
Ok, obrigado James! Atualmente, estou tentando fazer isso sozinho estendendo a classe LogisticGradient e substituindo o método de computação. Avisarei se isso me der bons resultados. Tenha um bom dia.
Jmvllt