Estou tendo muitos problemas para entender como funciona o class_weight
parâmetro na regressão logística do scikit-learn.
A situação
Quero usar a regressão logística para fazer a classificação binária em um conjunto de dados muito desequilibrado. As classes são rotuladas 0 (negativo) e 1 (positivo) e os dados observados estão em uma proporção de cerca de 19: 1 com a maioria das amostras tendo resultado negativo.
Primeira tentativa: preparando manualmente os dados de treinamento
Divido os dados que tinha em conjuntos separados para treinamento e teste (cerca de 80/20). Em seguida, fiz uma amostra aleatória dos dados de treinamento à mão para obter dados de treinamento em proporções diferentes de 19: 1; de 2: 1 -> 16: 1.
Em seguida, treinei a regressão logística nesses diferentes subconjuntos de dados de treinamento e a recordação plotada (= TP / (TP + FN)) como uma função das diferentes proporções de treinamento. Claro, o recall foi calculado nas amostras de TESTE disjuntas que tinham as proporções observadas de 19: 1. Observe que, embora eu tenha treinado os diferentes modelos em dados de treinamento diferentes, calculei a recuperação de todos eles nos mesmos dados de teste (separados).
Os resultados foram os esperados: o recall foi de cerca de 60% nas proporções de treinamento de 2: 1 e caiu bem rápido quando chegou a 16: 1. Havia várias proporções 2: 1 -> 6: 1 onde o recall estava decentemente acima de 5%.
Segunda tentativa: Pesquisa de grade
Em seguida, eu queria testar diferentes parâmetros de regularização e então usei GridSearchCV e fiz uma grade de vários valores do C
parâmetro, bem como do class_weight
parâmetro. Para traduzir minhas proporções n: m de amostras de treinamento negativo: positivo para a linguagem do dicionário, class_weight
pensei que apenas especificaria vários dicionários da seguinte forma:
{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 } #expected 4:1
e eu também incluí None
e auto
.
Desta vez, os resultados foram totalmente malucos. Todas as minhas recuperações foram mínimas (<0,05) para cada valor de class_weight
exceto auto
. Portanto, só posso supor que meu entendimento de como definir o class_weight
dicionário está errado. Curiosamente, o class_weight
valor de 'auto' na pesquisa de grade foi em torno de 59% para todos os valores de C
, e imaginei que equilibra para 1: 1?
Minhas perguntas
Como você usa adequadamente
class_weight
para obter balanços diferentes nos dados de treinamento do que você realmente fornece? Especificamente, que dicionário devoclass_weight
usar para usar proporções n: m de amostras de treinamento negativas: positivas?Se você passar vários
class_weight
dicionários para o GridSearchCV, durante a validação cruzada ele irá reequilibrar os dados da dobra de treinamento de acordo com o dicionário, mas usar as verdadeiras proporções de amostra fornecidas para calcular minha função de pontuação na dobra de teste? Isso é crítico, pois qualquer métrica só é útil para mim se vier de dados nas proporções observadas.O que o
auto
valor declass_weight
faz em relação às proporções? Eu li a documentação e presumo que "equilibra os dados inversamente proporcionais à sua frequência" significa apenas 1: 1. Isso está correto? Se não, alguém pode esclarecer?