Spaces:
Sleeping
Sleeping
File size: 5,962 Bytes
42d0bac |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
import streamlit as st
import pandas as pd
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
class SVR_st:
def __init__(self, database, test_size=0.2):
self.database = database
self.test_size = test_size
self.desc = r'''
# **SVR (Support Vector Regression)**
El objetivo es encontrar la funci贸n $f(x)$ que produzca el valor $y$ con una distancia no m谩s lejana que $\epsilon$ para cada uno de los puntos de entrenamiento $x$.
**Linear SVM Regression: Primal Formula**
Supongamos que estamos trabajando con un set de datos X (multivariable) y con una variable dependiente y.
Entonces la funci贸n lineal seria:
$$
f(X) = X^{T}\beta + b
$$
Luego, para asegurar que los par谩metros $\beta$ sean lo m谩s chicos (flat) posibles es que se busca minimizar:
$$
J(\beta) = \frac{1}{2}\beta^{T}\beta
$$
Restringido bajo las siguientes condiciones:
$$
|y_{n} - (X_{n}^{T}\beta + b)| \leq \epsilon \quad \forall n \in N
$$
Como es posible que no exista una funci贸n $f(x)$ que pueda satisfacer estas condiciones se introduce los t茅rminos $鈩嘷{n}$ y $鈩嘷{n}^{*}$ las cuales vienen a representar algo as铆 como variables de holgura.
As铆, luego nuestra funci贸n objetivo cambia a:
$$
J(\beta) = \frac{1}{2}\beta^{T}\beta + C\sum_{n=1}^{N} (鈩嘷{n} + 鈩嘷{n}^{*})
$$
Sujeto a:
$$
y_{n} - (X_{n}^{T} \beta +b) \leq \epsilon + 鈩嘷{n} \quad \forall n \in N
$$
$$
(X_{n}^{T} \beta +b) - y_{n}\leq \epsilon + 鈩嘷{n}^{*} \quad \forall n \in N
$$
$$
鈩嘷{n}^{*} \geq 0 \quad \forall n \in N
$$
$$
鈩嘷{n} \geq 0 \quad \forall n \in N
$$
**Nota**: $C$ Son un conjunto de valores todos positivos que tiene por funci贸n penalizar las observaciones que se escapen del margen $\epsilon$
**Nonlinear SVM Regression**
En caso de que el problema no se pueda adaptar bien utilizando un modelo lineal, podemos adaptar todo este desarrollo cambiando el producto punto $X_{i}^{T}X_{j}$ por $G(X_{i}, X_{j})$.
| Kernel Name | Kernel Function |
|-------------|-----------------|
|Linear (dot product)| $G(X_{i}, X_{j}) = X_{i}^{T}X_{j}$|
|Gaussian|$G(X_{i}, X_{j}) = e^{-\lvert \rvert X_{i} - X_{j}^{2} \lvert \rvert}$|
|Polynomial|$G(X_{i}, X_{j}) = (1 + X_{i}^{T}X_{j})^{q}$|
**Nota:** $q$ es el grado del polinomio
**Fuente**: https://www.mathworks.com/help/stats/understanding-support-vector-machine-regression.html
'''
def params(self):
self.selected_kernel = st.selectbox('Tipo de kernel:', options=['linear', 'poly', 'rbf', 'sigmoid'])
if self.selected_kernel == 'poly': self.degree = st.slider('Grados del polinomio', 1, 6, 3)
min = float(np.min([0, np.min(self.database.target)]))/2
max = float(np.max(self.database.target))/2
mean = float(np.mean(self.database.target))/2
self.C = st.slider('Parametro de penalizacion C:', 1.0, 4*max, 4*mean)
self.epsilon = st.slider('Epsilon: ', min, max, mean)
def solve(self):
self.X, self.y = self.database.data, self.database.target
X_train, X_test, y_train, y_test = train_test_split(self.X, self.y, test_size=self.test_size, random_state=1234)
if self.selected_kernel == 'poly': self.sklearn_regr = SVR(kernel=self.selected_kernel,
degree=self.degree,
C=self.C,
epsilon=self.epsilon)
else: self.sklearn_regr = SVR(kernel=self.selected_kernel,
C=self.C,
epsilon=self.epsilon)
self.sklearn_regr.fit(X_train, y_train)
y_pred = self.sklearn_regr.predict(X_test)
acc = mean_squared_error(y_pred, y_test)
st.metric('MSE (Mean Square Error)', value=f'{np.round(acc, 2)}')
def visualization(self):
n_features = int(self.database.data.shape[1])
self.x_feature = st.slider('Variable en eje x', 1, n_features, 1)
self.X = self.database.data[:, self.x_feature-1:self.x_feature]
self.y = self.database.target
X_train, X_test, y_train, y_test = train_test_split(self.X, self.y, test_size=self.test_size, random_state=1234)
if self.selected_kernel == 'poly': self.sklearn_regr = SVR(kernel=self.selected_kernel,
degree=self.degree,
C=self.C,
epsilon=self.epsilon)
else: self.sklearn_regr = SVR(kernel=self.selected_kernel,
C=self.C,
epsilon=self.epsilon)
self.sklearn_regr.fit(X_train, y_train)
x1_min = self.X.min()
x1_max = self.X.max()
x_pred = np.linspace(x1_min, x1_max, 100).reshape([100, 1])
y_pred = self.sklearn_regr.predict(x_pred)
y_pred_up = [i+self.epsilon for i in y_pred]
y_pred_down = [i-self.epsilon for i in y_pred]
plt.figure(1, figsize=(12, 8))
plt.scatter(self.X, self.y, edgecolors='k', cmap=plt.cm.Paired)
plt.plot(x_pred, y_pred, color='red') # linea de prediccion
plt.plot(x_pred, y_pred_up, linestyle='--', color='green')
plt.plot(x_pred, y_pred_down, linestyle='--', color='green')
return plt.gcf()
|