Dados multi-classe inclinados

10

Eu tenho um conjunto de dados que contém ~ 100.000 amostras de 50 classes. Eu tenho usado o SVM com um kernel RBF para treinar e prever novos dados. O problema, porém, é que o conjunto de dados é inclinado para diferentes classes.

Por exemplo, Classe 1 - 30 (~ 3% cada), Classe 31 - 45 (~ 0,6% cada), Classe 46 - 50 (~ 0,2% cada)

Vejo que o modelo tende a prever muito raramente as classes que ocorrem com menos frequência no conjunto de treinamento, mesmo que o conjunto de teste tenha a mesma distribuição de classe que o conjunto de treinamento.

Estou ciente de que existem técnicas como 'subamostragem' em que a classe majoritária é reduzida para a classe menor. No entanto, isso é aplicável aqui onde existem tantas classes diferentes? Existem outros métodos para ajudar a lidar com este caso?

mike1886
fonte

Respostas:

5

Eu sugiro que você use libsvm, que já possui pesos de classe ajustáveis ​​implementados. Em vez de replicar as amostras de treinamento, modifica-se o parâmetro C para diferentes classes na otimização do SVM. Por exemplo, se seus dados tiverem 2 classes e a primeira classe for apenas 10% dos dados, você escolheria pesos de classe 10 e 1 para as classes 1 e 2, respectivamente. Portanto, violações de margem da primeira classe custariam 10 vezes mais do que as violações de margem da segunda classe, e as precisões por classe seriam mais equilibradas.

magicharp
fonte
obrigado pelo conselho, você sabe se a libsvm faz isso automaticamente ou preciso passar manualmente os pesos da classe?
mike1886
Você precisa passar manualmente os pesos da classe. A maneira de fazer isso é diferente com base na interface que você está usando (python, java, matlab, c). Está bem documentado nos arquivos leia-me se você fizer o download da ferramenta em csie.ntu.edu.tw/~cjlin/libsvm . Além disso, seu tamanho de dados parece ser grande e a implementação padrão da libsvm em várias classes usará a classificação um contra um, o que pode levar muito tempo para ser executado. Você pode tentar treinar 50 classificadores binários de um para todos, especificando os pesos adequadamente.
11265 magicharp
2

Eu não sou uma exportação no uso de SVMs, mas geralmente (se você estiver usando uma biblioteca de aprendizado de máquina como Python scikit-learnou R libsvm, existe o class_weightparâmetro ou class.weights, respectivamente.

Ou, se você usasse um classificador Bayes, levaria em conta esse "desvio" pelas "probabilidades anteriores (de classe)" P (ω j )


fonte
1

Com relação à abordagem, o SVM com um kernel RBF faz um bom trabalho, mas os SVMs podem ser lentificados com grandes tamanhos de objeto, a menos que você esteja empregando CV com, por exemplo, um décimo dos dados atribuídos aleatoriamente a cada dobra. No entanto, você se perguntou por que está empregando SVMs em primeiro lugar?

Você já tentou de regressão linear múltipla, , onde cada registro de é codificado se o th objeto está em classe e caso contrário? Se a precisão da classificação for sensivelmente alta usando a regressão linear, seus dados serão separáveis ​​linearmente e não serão necessários métodos mais complexos, como SVMs e ANNs. O passo 2 seria mostrar que o vizinho mais próximo k, Bayes ingênuo, análise discriminante linear (Fisher), regressão logística politômica, etc., quebram e falham.Y=XβYyij=+1ijyij=1

Para terminologia, você pode abordar a questão de ter mais pesos de classe no contexto de "proporções mais baixas de objetos em determinadas classes" ou "tamanho de classe quase zero". A inclinação tende a ser usada para descrever a distribuição dos valores de um recurso, como a inclinação, caudas gordas etc.

Quantos recursos você tem? Você tentou agrupar não supervisionado (descoberta de classe) nos 100.000 objetos antes de tentar a classificação supervisionada (previsão de classe) com o SVM? Talvez os 100.000 objetos possam ser agrupados em menos classes que 50, para as quais a nova associação de classe possa ser usada como classe de destino durante a análise de classificação. Isso pode aliviar o problema de ter tamanho de classe próximo de zero.


fonte
1

Eu já enfrentei esse problema várias vezes ao usar o SVM com o kernel Rbf. Usar o kernel Linear em vez do Rbf resolveu meu problema, mas lidei com um menor número de classes. Os resultados foram menos distorcidos e mais precisos com o kernel linear. Espero que isso resolva seu problema.

Edit: Enquanto escrevia a resposta original, fui ingênuo o suficiente para não considerar o peso das aulas, como uma delas respondeu corretamente. Além disso, ao usar o rbf kernel, é importante garantir que o parâmetro de penalidade ou o valor 'C' conforme o módulo svm do sklearn seja muito genérico. Acho que o valor padrão de C = 1 é muito genérico na maioria das vezes e normalmente acabo com um valor de C = 10000. Espero que isso ajude outras pessoas que obtêm resultados distorcidos com o svm (rbf), apesar de ter uma boa distribuição de classes nos dados.

user776193
fonte
Obrigado pela resposta! Na verdade, eu tentei vários outros algoritmos / kernels e ainda tenho o mesmo tipo de problema. Então, eu estou procurando mais uma abordagem como subamostragem ou alguma maneira de nivelar as classes.
mike1886
Ok, você também pode tentar replicar linhas para classes que contêm dados esparsos, embora seja útil apenas se os recursos dos dados esparsos forem realmente bons.
user776193