class: center, middle, title-slide .title[ # Máquinas de vetores de suporte (SVM) ] .subtitle[ ## Em regressão ] .author[ ### Jaime Utria ] .institute[ ### Departamento de EstatÃstica - UFF ] --- <!-- macro comandos matemáticos Latex --> <script type="text/x-mathjax-config"> MathJax.Hub.Config({ TeX: { Macros: { vet: ["{\\mathbf #1}",1], prodint: ["\\langle #1, #2 \\rangle",2], posto: ["{\\mathrm{posto} (#1)}",1], tr: ["{\\mathrm{tr} (#1)}",1] } } }); </script> ## SVM regressor - O classificador obtido pelo *SVM*, é comumente denominado de *support vector classifier* (*SVC*). O *SVM* também pode ser utilizado em problemas de regressão, neste caso o preditor resultante é chamado de *support vector regressor* (*SVR*). - A ideia do *SVR* é similar à do *SVC*: encontrar o hiperplano ótimo (no espaço caracterÃstico, induzido pelo *kernel*) que tenha boa generalização usando as variáveis originais. - No entanto, o *SVR*, ao contrário do *SVC*, procura manter dentro da **margem** o máximo número de observações possÃveis, enquanto "penaliza" as observações que violam a margem (aquelas que ficam fora). - A largura da margem é controlada por um hiperparâmetro `\(\varepsilon > 0\)`. --- ## *SVR* caso linear .center[ <img src="data:image/png;base64,#svr.png" width="853" /> **Fonte:** Geron, A. ] --- ## *SVR*: Detalhes - Em problemas de regressão tipicamente, usamos a função de perda quadrática, ou seja, uma função da soma dos resÃduos ao quadrado. - Vapnik (1995) sugere uma função de perda chamadada `\(\varepsilon\)`-insensitiva, de modo que o erro é nulo se a diferença entre a previsão `\(f(\mathbf x)\)` e o valor real `\(y\)` em valor absoluto for menor que `\(\varepsilon > 0\)`, mais especificamente, consideramos: `$$L_{\varepsilon}[f(\mathbf x, y)] = (|f(\mathbf{x}) - y| - \varepsilon) I\{|f(\mathbf{x}) - y| > \varepsilon\}$$` - Em palavras, se `\((\mathbf x, y)\)` é tal que `\(|f(\mathbf x) - y| \leq \varepsilon\)`, então a perda é zero; se, por outro lado, `\(|f(\mathbf x) - y| > \varepsilon\)`, então a perda é `\(|f(\mathbf{x}) - y| - \varepsilon\)`. - Quando `\(f(\mathbf x) = \beta_0 + \boldsymbol{\beta}^\top \mathbf{x}\)`, temos o caso linear. --- ## *SVR* como um problema de otimização convexa `$$\begin{align} \min_{\beta_0, \beta_1, \ldots, \beta_p, \xi_1, \ldots, \xi_n} \frac{1}{2} ||\boldsymbol{\beta}||^2 + C\sum_{i=1}^n (\xi_i + \xi_i')\\ \text{s.a. } y_i - (\beta _0 + \boldsymbol{\beta}^\top \mathbf{x}_i) \leq \varepsilon + \xi_i',\\ (\beta_0 +\boldsymbol{\beta}^\top \mathbf{x}_i) -y_i\leq \varepsilon + \xi_i,\\ \xi_i \ge 0, \xi_i' \ge 0, i = 1, \ldots, n.\end{align}$$` - O hiperparâmetro `\(C > 0\)` tem como objetivo equilibar a planura (*flatness*) de `\(f\)`. - As variáveis de folga, neste caso são `\(\xi_i = y_i - f(\mathbf x) - \varepsilon \geq 0\)` se `\((\mathbf x_i, y_i)\)` fica acima da faixa, ou `\(\xi_i' = f(\mathbf x) - \varepsilon - y_i \ge 0\)` se `\((\mathbf x_i, y_i)\)` fica abaixo da faixa; já pontos que ficam dentro da faixa têm valores das variáveis de folga igual a zero. --- ## Prevendo o salário dos jogadores da MLB ``` r library(dplyr) library(caret) library(e1071) ``` ``` r # Carregando os dados mlb <- read.csv("mlb.txt") # Removendo os nomes dos jogadores mlb <- mlb[,-18] # Renomeando as vars indicadoras names(mlb)[c(14,15,16,17)] <- c("FAE","FA","AE","A") ``` --- ## Treinamento do modelo: caso linear ``` r set.seed(12345) index_train <- createDataPartition(y = mlb$Salary, p =0.75, list = FALSE) training <- mlb[index_train,] testing <- mlb[-index_train,] ``` ``` r svr_linear <- svm(Salary ~., data = training, type = "eps-regression", # para epsilon-regressão kernel = "linear") ``` --- ## Avaliando o desempenho do modelo com kernel linear ``` r predictions <- predict(svr_linear, testing) postResample(predictions, testing$Salary) ``` ``` ## RMSE Rsquared MAE ## 805.6197506 0.5929792 557.1195116 ``` --- ## *SVR*: caso não linear .center[ <img src="data:image/png;base64,#svr_poly2.png" width="853" /> **Fonte:** Geron, A. ] --- ## Treinamento do modelo com kernel polinomial ``` r svr_poly <- svm(Salary ~., data = training, type = "eps-regression", kernel = "polynomial", degree = 3, gamma = 1, coef0 = 0, cost = 4) ``` --- ## Avaliando o desempenho do modelo com kernel polinomial ``` r predictions <- predict(svr_poly, testing) postResample(predictions, testing$Salary) ``` ``` ## RMSE Rsquared MAE ## 1868.4299751 0.2413661 1112.6782709 ``` --- ## Treinamento do modelo com kernel radial (Gaussiano) ``` r svr_radial <- svm(Salary ~., data = training, type = "eps-regression", kernel = "radial", gamma = 0.1, cost = 100) ``` --- ## Avaliando o desempenho do modelo com kernel radial ``` r predictions <- predict(svr_radial, testing) postResample(predictions, testing$Salary) ``` ``` ## RMSE Rsquared MAE ## 848.2067255 0.5627633 562.2413760 ``` --- ## Ajuste de hiperparâmetros ``` r # usando a função tune de e1071 tuned_svr <- tune(svm, Salary ~., data = training, type = "eps-regression", kernel = "radial", ranges = list( epsilon = seq(0, 0.2, 0.01), cost = 2^(2:9) ) ) ``` --- ``` r tuned_svr$best.parameters ``` ``` ## epsilon cost ## 8 0.07 4 ``` ``` r # ajustar mehlor modelo melhor_svr_model <- tuned_svr$best.model tuned_predictions <- predict(melhor_svr_model, newdata = testing) postResample(tuned_predictions, testing$Salary) ``` ``` ## RMSE Rsquared MAE ## 757.115836 0.644853 481.171735 ```