Estou tentando dar uma resposta simples e fácil de entender. Uma resposta completa provavelmente precisará cobrir tudo, desde o objetivo por trás dos SVMs até os detalhes mais precisos dos vetores de perda e suporte. Se você quiser aprofundar esses detalhes, pode ser necessário examinar, por exemplo, os capítulos sobre SVMs nos livros de aprendizado de máquina.
SVMs são grandes classificadores de margem . Isso significa que a separação (vamos assumir linear) entre amostras da classe preto e branco não é apenas uma possível, mas a melhor separação possível , definida pela obtenção da maior margem possível entre amostras das duas classes. Este seriaH3 na imagem de exemplo:
Se você pensar sobre isso por um momento que você vai concluir que a separação é derivado unicamente a partir dessas amostras que estão mais perto de "a outra classe", daí as pessoas próximas à margem (para ser exato: aqueles na margem). Na imagem de exemplo, essas são as amostras marcadas com as linhas cinza ortogonais aoH3. Esse comportamento causa um problema: com a quantidade de amostras usada para derivar a separação sendo amplamente um subconjunto, o ruído que afeta essas amostras provavelmente fará com que a separação seja abaixo do ideal para a maioria dos dados. Isso é o que todos conhecemos como sobreajuste: a separação seria ideal do ponto de vista da grande margem do treinamento usado, mas seria generalizada de maneira inadequada e, portanto, seria insatisfatória para outros / ainda não vistos dados.
O que falamos até agora é a "classificação das margens rígidas": não permitimos que nenhuma amostra esteja dentro da margem, pois é assim que a margem é definida até agora. Quando agora relaxamos essa propriedade difícil, acabamos fazendo "classificação de margem macia". A ideia por trás da margem permanece a mesma - mas agora podemos permitir que determinadas amostras estejam dentro da margem . O principal benefício é que, ao fazer isso, o ajuste geral do modelo aos dados pode muito bem ser melhor do que com a classificação de margem rígida ( reduza a variação ao custo de algum viés ).
Portanto, por um lado, ainda temos que resolver nosso problema simples de otimização (a melhor forma de ajustar o modelo = linha aos nossos dados). Por outro lado, não queremos ter todas / muitas amostras na margem - de alguma forma, queremos ajustar quantas amostras deixamos dentro da margem, para que a margem não se adapte completamente nem perca completamente sua propriedade de margem grande.
E é aqui que o Cparâmetro entra no palco. A ideia principal é simples: modificar o problema de optimização para optimizar tanto o ajuste da linha de dados e penalizar a quantidade de amostras no interior da margem, ao mesmo tempo, ondeCdefine o peso de quantas amostras dentro da margem contribuem para o erro geral. Consequentemente, comCvocê pode ajustar a rigidez ou a suavidade da classificação de margem grande . Com um baixoC, amostras dentro das margens são penalizadas menos do que com uma C. Com umCde 0, amostras dentro das margens não são mais penalizadas - que é o extremo possível de desativar a classificação de margem grande. Com um infinitoC você tem o outro extremo possível de margens rígidas.
Aqui está um pequeno exemplo visualizando o efeito causado pela alteração Cusando o conhecido conjunto de dados da íris (no R
e usando o caret
pacote, mas o mesmo se aplica libsvm
também, é claro). É assim que os dados originais se parecem (é um problema de classificação binária):
library(caret)
d <- iris[51:150,c(1,2,5)]
plot(d[,c(2,1)], pch = ifelse(d[,3]=='versicolor', 1, 2))
É assim que mudar C pode influenciar o desempenho do seu modelo:
m <- train(d[,1:2], factor(d[,3]), method = 'svmLinear', trControl = trainControl(method = 'repeatedcv', 10, 20), tuneGrid = expand.grid(C=3**(-7:7)))
plot(m, scales=list(x=list(log=3)))
E esta é a diferença na separação entre dois diferentes escolhidos C valores (observe que as linhas de separação têm inclinação diferente!):
m1 <- train(d[,1:2], factor(d[,3]), method = 'svmLinear', preProcess = c('center', 'scale'), trControl = trainControl(method = 'none'), tuneGrid = expand.grid(C=3**(-7)))
plot(m1$finalModel)
m2 <- train(d[,1:2], factor(d[,3]), method = 'svmLinear', preProcess = c('center', 'scale'), trControl = trainControl(method = 'none'), tuneGrid = expand.grid(C=3**(7)))
plot(m2$finalModel)
Portanto, praticamente, o que você provavelmente deseja fazer na configuração do ML é ajustar adequadamente C, por exemplo, usando uma grade de ajuste. Você pode considerar, por exemplo, esta publicação para obter mais detalhes. É do pessoal da LibSVM, e eles fornecem muitas informações úteis, desde explicar como os SVMs funcionam com bons exemplos até codificar trechos de como, por exemplo, usar grades de parâmetros com o LibSVM:
Hsu et al. (2003). "Um guia prático para apoiar a classificação vetorial." Departamento de Ciência da Computação e Engenharia da Informação, Universidade Nacional de Taiwan.
BTW: há uma pequena lista de coisas que as pessoas disseram sobre SVMs Cparâmetro, que também acho útil para entendê-lo: http://www.svms.org/parameters/