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?

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.


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 )


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.


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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.