Compreendendo os hiperparâmetros do SVM

Compreendendo os hiperparâmetros do SVM

Introdução

Este guia é a segunda parte de três guias sobre Support Vector Machines (SVMs). Neste guia, continuaremos trabalhando no caso de uso de notas bancárias falsificadas, entenderemos quais parâmetros SVM já estão sendo definidos pelo Scikit-learn, o que são hiperparâmetros C e Gamma e como ajustá-los usando validação cruzada e pesquisa de grade.

Na série completa de guias SVM, além dos hiperparâmetros SVM, você também aprenderá sobre SVM simples, um conceito chamado de truque do kernele explore outros tipos de SVMs.

Se você deseja ler todos os guias, dê uma olhada no primeiro guia, ou veja quais lhe interessam mais, segue abaixo a tabela de tópicos abordados em cada guia:

  1. Implementando SVM e Kernel SVM com Scikit-Learn do Python
  • Caso de uso: esqueça notas bancárias
  • Histórico de SVMs
  • Modelo SVM Simples (Linear)
    • Sobre o conjunto de dados
    • Importando o conjunto de dados
    • Explorando o conjunto de dados
  • Implementando SVM com Scikit-Learn
    • Dividindo dados em conjuntos de treinamento/teste
    • Treinando o modelo
    • Fazendo previsões
    • Avaliando o Modelo
    • Interpretando os resultados

2. Compreendendo os hiperparâmetros SVM

  • O Hiperparâmetro C
  • O Hiperparâmetro Gama

3. Implementando outros tipos de SVM com Scikit-Learn do Python (em breve!)

  • A ideia geral de SVMs (uma recapitulação)
  • Kernel (truque) SVM
  • Implementando kernel não linear SVM com Scikit-Learn
  • Importando bibliotecas
    • Importando o conjunto de dados
    • Dividindo dados em recursos (X) e alvo (y)
    • Dividindo dados em conjuntos de treinamento/teste
    • Treinando o Algoritmo
  • núcleo polinomial
    • Fazendo previsões
    • Avaliando o Algoritmo
  • Kernel gaussiano
    • Previsão e avaliação
  • Núcleo Sigmoide
    • Previsão e avaliação
  • Comparação de Desempenhos de Kernel Não Lineares

Vamos aprender como implementar a validação cruzada e realizar um ajuste de hiperparâmetros.

Hiperparâmetros SVM

Para ver todos os parâmetros do modelo que já foram definidos pelo Scikit-learn e seus valores padrão, podemos usar o get_params() método:

svc.get_params()

Este método exibe:

{'C': 1.0, 'break_ties': False, 'cache_size': 200, 'class_weight': None, 'coef0': 0.0, 'decision_function_shape': 'ovr', 'degree': 3, 'gamma': 'scale', 'kernel': 'linear', 'max_iter': -1, 'probability': False, 'random_state': None, 'shrinking': True, 'tol': 0.001, 'verbose': False}

Observe que há um total de 15 hiperparâmetros já sendo configurados, isso acontece porque o algoritmo SVM possui muitas variações. Usamos o kernel linear para obter uma função linear, mas também existem kernels que descrevem outros tipos de funções e esses kernels são parametrizados de maneiras diferentes.

Essas variações tornam o modelo mais flexível e adequado para encontrar uma separação entre diferentes formas de dados. Se pudermos traçar uma linha para separar nossas classes, então kernel linear será uma boa opção, se precisarmos de uma curva, então uma polinomial kernel pode ser a melhor escolha, se nossos dados tiverem formas circulares, então um Função de base radial or RBF kernel se adequará melhor aos dados, se houver valores acima e abaixo de um limite, um sigmóide kernel pode separar melhor as classes. Pelo que exploramos em nossos dados, parece que um RBF ou um kernel polinomial seria mais adequado do que um kernel linear.

Agora que temos uma ideia de que existem 4 tipos diferentes de funções do kernel, podemos voltar aos parâmetros. Quando o algoritmo SVM tenta encontrar uma separação entre as classes, já entendemos que ele traça uma classificação margem entre os vetores de suporte e a linha (ou curva) de separação.

Essa margem é, de certa forma, como um buffer entre a linha de separação e os pontos. O tamanho da margem pode variar, quando a margem é menor, há menos espaço para pontos que ficam fora da margem, tornando mais clara a separação entre as classes, então mais amostras estão sendo classificado corretamente, inversamente, quando a margem é Maior, a separação entre as classes é menos clara e mais amostras podem ser mal classificado. Em outras palavras, uma margem menor significa amostras mais corretamente classificadas, e também uma rígido classificador, enquanto uma margem maior, denota mais amostras mal classificadas, mas um flexível classificador.

Quando essas margens são escolhidas, o parâmetro que as determina é o C parâmetro.

O Hiperparâmetro C

A C parâmetro é inversamente proporcional ao tamanho da margem, isso significa que o Maior o valor de C, menor a margem e, inversamente, o menor o valor de C, Maior A margem. O C parâmetro pode ser usado junto com qualquer kernel, ele informa ao algoritmo o quanto evitar a classificação incorreta de cada amostra de treinamento, por isso também é conhecido como regularização. Nosso kernel linear SVM usou um C de 1.0, que é um grande valor e dá um margem menor.

Compreendendo os hiperparâmetros SVM PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Podemos experimentar um menor valor de 'C' e entenda na prática o que acontece com um margem maior. Para fazer isso, vamos criar um novo classificador, svc_c, e altere apenas o valor de C para 0.0001. Vamos também repetir o fit e predict passos:

svc_c = SVC(kernel='linear', C=0.0001)
svc_c.fit(X_train, y_train)
y_pred_c = svc_c.predict(X_test)

Agora podemos ver os resultados dos dados de teste:

print(classification_report(y_test, y_pred_c)) cm_c = confusion_matrix(y_test, y_pred_c)
sns.heatmap(cm_c, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with C=0.0001')

Isso resulta em:

 precision recall f1-score support 0 0.82 0.96 0.88 148 1 0.94 0.76 0.84 127 accuracy 0.87 275 macro avg 0.88 0.86 0.86 275
weighted avg 0.88 0.87 0.86 275

Compreendendo os hiperparâmetros SVM PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Ao usar um menor C e obtendo uma margem maior, o classificador ficou mais flexível e com mais erros de classificação. No relatório de classificação, podemos ver que o f1-score, anteriormente 0.99 para ambas as classes, baixou para 0.88 para a classe 0 e para 0.84 para a classe 1. Na matriz de confusão, o modelo passou de 2 para 6 falsos positivos e de 2 para 31 falsos negativos.

Também podemos repetir o predict passo e observe os resultados para verificar se ainda há um overfit ao usar os dados do trem:

y_pred_ct = svc_c.predict(X_train) cm_ct = confusion_matrix(y_train, y_pred_ct)
sns.heatmap(cm_ct, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with C=0.0001 and train data') print(classification_report(y_train, y_pred_ct))

Isto resulta em:

 precision recall f1-score support 0 0.88 0.96 0.92 614 1 0.94 0.84 0.88 483 accuracy 0.90 1097 macro avg 0.91 0.90 0.90 1097
weighted avg 0.91 0.90 0.90 1097

Compreendendo os hiperparâmetros SVM PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Olhando para os resultados com um menor C e dados do trem, podemos ver que houve uma melhora no overfit, mas como a maioria das métricas ainda é maior para os dados do trem, parece que o overfit não foi resolvido. Então, basta mudar o C parâmetro não foi suficiente para tornar o modelo mais flexível e melhorar sua generalização.

Note: Tentar encontrar o equilíbrio entre uma função que está muito longe dos dados, sendo muito fixa ou tendo alto viés ou é o contrário, uma função que se aproxime dos dados, seja muito flexível, ou tenha alta variação é geralmente referido como o trade-off de variância de viés. Encontrar esse equilíbrio não é trivial, mas quando é alcançado, não há subajuste ou superajuste do modelo aos dados. Como forma de reduzir a variância e evitar o overfitting, os dados podem ser reduzidos uniformemente para serem mais regulares e simplificados ao obter uma função que os descreva. É isso que o parâmetro C faz quando é usado no SVM, por isso também é chamado Regularização L2 or Regressão do cume.

Até aqui, entendemos sobre as margens no SVM e como elas impactam o resultado geral do algoritmo, mas e a linha (ou curva) que separa as classes? esta linha é a limite de decisão. Então, já sabemos que as margens têm impacto na flexibilidade do limite de decisão em relação a erros, podemos agora dar uma olhada em outro parâmetro que também afeta o limite de decisão.

Confira nosso guia prático e prático para aprender Git, com práticas recomendadas, padrões aceitos pelo setor e folha de dicas incluída. Pare de pesquisar comandos Git no Google e realmente aprender -lo!

Note: O limite de decisão também pode ser chamado de hiperplano. Um hiperplano é um conceito geométrico para se referir ao número de dimensões de um espaço menos um (dims-1). Se o espaço for bidimensional, como um plano com coordenadas x e y, as linhas unidimensionais (ou curvas) são os hiperplanos. No contexto de aprendizado de máquina, como o número de colunas usadas no modelo são suas dimensões planas, quando trabalhamos com 2 colunas e um classificador SVM, encontramos um hiperplano tridimensional que separa as classes.

O Hiperparâmetro Gama

Limites de decisão infinitos podem ser escolhidos, alguns desses limites irão separar as classes e outros não. Ao escolher um limite de decisão efetivo, os primeiros 10 pontos mais próximos de cada classe devem ser considerados? Ou devem ser considerados mais pontos, incluindo os pontos que estão distantes? No SVM, essa escolha de faixa é definida por outro hiperparâmetro, gamma.

Como C, gamma é um pouco inversamente proporcional à sua distância. O superior seu valor, o mais próximo são os pontos que são considerados para o limite de decisão, e o menor que o gamma, mais pontos também são considerados para a escolha do limite de decisão.

Compreendendo os hiperparâmetros SVM PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Outro impacto do gama é que quanto maior seu valor, mais o escopo do limite de decisão se aproxima dos pontos ao seu redor, tornando-o mais irregular e propenso a superajuste – e quanto menor o valor, mais suave e regular é o limite de decisão superfície fica, também, menos propensa a overfit. Isso é verdade para qualquer hiperplano, mas pode ser mais facilmente observado ao separar dados em dimensões superiores. Em algumas documentações, gamma também pode ser referido como sigma.

Compreendendo os hiperparâmetros SVM PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

No caso do nosso modelo, o valor padrão de gamma foi scale. Como pode ser visto no Documentação Scikit-learn SVC, significa que seu valor é:

$$
gama = (1/ texto{n_recursos} * X.var())
$$

or

$$
gama = (1/ texto{number_of_features} * texto{features_variance})
$$

No nosso caso, precisamos calcular a variância de X_train, multiplique por 4 e divida o resultado por 1. Podemos fazer isso com o seguinte código:

number_of_features = X_train.shape[1] features_variance = X_train.values.var()
gamma = 1/(number_of_features * features_variance)
print('gamma:', gamma)

Isso resulta em:

gamma: 0.013924748072859962

Há também outra maneira de ver o valor de gamma, acessando o objeto do classificador gamma parâmetro com ._gamma:

svc._gamma 

Podemos ver que o gamma usado em nosso classificador foi baixo, por isso também considerou pontos mais distantes.

Note: Como nós vimos, C e gamma são importantes para algumas definições do modelo. Outro hiperparâmetro, random_state, é frequentemente usado no Scikit Learn para garantir o embaralhamento de dados ou uma semente aleatória para modelos, então sempre temos os mesmos resultados, mas isso é um pouco diferente para SVM's. Particularmente, o random_state só tem implicações se outro hiperparâmetro, probability, é definido como verdadeiro. Isso ocorre porque ele embaralhará os dados para obter estimativas de probabilidade. Se não quisermos estimativas de probabilidade para nossas classes e a probabilidade for definida como falsa, os SVMs random_state parâmetro não tem implicações nos resultados do modelo.

Não há regra sobre como escolher valores para hiperparâmetros, como C e gama – vai depender de quanto tempo e quais recursos estão disponíveis para experimentar diferentes valores de hiperparâmetros, quais transformações podem ser feitas nos dados e quais resultados são esperados . A forma usual de buscar os valores dos hiperparâmetros é combinando cada um dos valores propostos através de um pesquisa de grade junto com um procedimento que aplica esses valores de hiperparâmetros e obtém métricas para diferentes partes dos dados chamados validação cruzada. No Scikit-learn, isso já está implementado como o GridSearchCV (CV da validação cruzada).

Para executar uma pesquisa de grade com validação cruzada, precisamos importar o GridSearchCV, defina um dicionário com os valores dos hiperparâmetros que serão experimentados, como o tipo de kernel, o intervalo para C, E para gamma, crie uma instância do SVC, Defina a score ou métrica será usada para avaliação (aqui, escolheremos otimizar a precisão e a recuperação, então usaremos f1-score), o número de divisões que serão feitas nos dados para executar a pesquisa em cv – o padrão é 5, mas é uma boa prática usar no mínimo 10 – aqui, usaremos 5 dobras de dados para ficar mais claro na comparação dos resultados.

A GridSearchCV tem um fit método que recebe nossos dados de treinamento e os divide em conjuntos de treinamento e teste para a validação cruzada. podemos definir return_train_score para true para comparar os resultados e garantir que não haja overfit.

Este é o código para a pesquisa de grade com validação cruzada:

from sklearn.model_selection import GridSearchCV parameters_dictionary = {'kernel':['linear', 'rbf'], 'C':[0.0001, 1, 10], 'gamma':[1, 10, 100]}
svc = SVC() grid_search = GridSearchCV(svc, parameters_dictionary, scoring = 'f1', return_train_score=True, cv = 5, verbose = 1) grid_search.fit(X_train, y_train)

Este código resulta em:

Fitting 5 folds for each of 18 candidates, totalling 90 fits
# and a clickable GridSeachCV object schema

Depois de fazer a pesquisa de hiperparâmetros, podemos usar o best_estimator_, best_params_ e best_score_ properties para obter o melhor modelo, valores de parâmetros e maior pontuação f1:

best_model = grid_search.best_estimator_
best_parameters = grid_search.best_params_
best_f1 = grid_search.best_score_ print('The best model was:', best_model)
print('The best parameter values were:', best_parameters)
print('The best f1-score was:', best_f1)

Isto resulta em:

The best model was: SVC(C=1, gamma=1)
The best parameter values were: {'C': 1, 'gamma': 1, 'kernel': 'rbf'}
The best f1-score was: 0.9979166666666666

Confirmando nossa suposição inicial de olhar para os dados, o melhor modelo não tem um kernel linear, mas um não linear, RBF.

Conselho: ao investigar mais, é interessante que você inclua mais kernels não lineares na pesquisa de grade.

Ambos C e gamma têm o valor de 1, e o f1-score é muito alto, 0.99. Como o valor é alto, vamos ver se houve um overfit olhando para as pontuações médias do teste e do trem que retornamos, dentro do cv_results_ objeto:

gs_mean_test_scores = grid_search.cv_results_['mean_test_score']
gs_mean_train_scores = grid_search.cv_results_['mean_train_score'] print("The mean test f1-scores were:", gs_mean_test_scores)
print("The mean train f1-scores were:", gs_mean_train_scores)

As pontuações médias foram:

The mean test f1-scores were: [0.78017291 0. 0.78017291 0. 0.78017291 0. 0.98865407 0.99791667 0.98865407 0.76553515 0.98865407 0.040291 0.98656 0.99791667 0.98656 0.79182565 0.98656 0.09443985] The mean train f1-scores were: [0.78443424 0. 0.78443424 0. 0.78443424 0. 0.98762683 1. 0.98762683 1. 0.98762683 1. 0.98942923 1. 0.98942923 1. 0.98942923 1. ]

Observando as pontuações médias, podemos ver que a mais alta, 0.99791667, aparece duas vezes e, em ambos os casos, a pontuação nos dados do trem foi 1. Isso indica que o overfit persiste. A partir daqui, seria interessante voltar à preparação dos dados e perceber se faz sentido normalizar os dados, fazer algum outro tipo de transformação de dados e também criar novas funcionalidades com engenharia de funcionalidades.

Acabamos de ver uma técnica para encontrar os hiperparâmetros do modelo e já mencionamos algo sobre separabilidade linear, vetores de suporte, limite de decisão, maximização de margens e truque do kernel. O SVM é um algoritmo complexo, geralmente com muitos conceitos matemáticos envolvidos e pequenas partes ajustáveis ​​que precisam ser ajustadas para se unirem como um todo.

Vamos combinar o que vimos até agora, fazer uma recapitulação de como todas as partes do SVM funcionam e, em seguida, dar uma olhada em algumas das outras implementações do kernel junto com seus resultados.

Conclusão

Neste artigo, entendemos os parâmetros padrão por trás da implementação SVM do Scikit-Learn. Entendemos o que são os parâmetros C e Gamma e como a alteração de cada um deles pode impactar o modelo SVM.

Também aprendemos sobre pesquisa de grade para procurar os melhores valores C e Gama e usar validação cruzada para generalizar melhor nossos resultados e garantir que não haja algum tipo de vazamento de dados.

Realizar um ajuste de hiperparâmetros com pesquisa de grade e validação cruzada é uma prática comum em ciência de dados, então eu sugiro fortemente que você implemente as técnicas, execute o código e veja os links entre os valores dos hiperparâmetros e as mudanças nas previsões do SVM.

Carimbo de hora:

Mais de Abuso de pilha