Introducción a los Modelos de Regresión en R

Programación de ejercicio práctico en RStudio

A partir de esta entrega y a lo largo de varios artículos relacionados, presentaré una serie de sesiones prácticas de programación en R en donde veremos implementaciones básicas de distintos algoritmos fundamentales dentro de la Ciencia de Datos y el Machine Learning.

Introducción

En esta oportunidad, realizaremos una introducción básica a uno de los modelos predictivos más sencillos existentes en el ámbito del Machine Learning, como lo es la Regresión Lineal Simple, y luego abordaremos otros modelos ligeramente más complejos como la Regresión Polinomial, la Regresión con Vectores de Soporte o SVR, los Áboles de Decisión (Decision Trees), así como los Bosques Aleatorios o Random Forests. A lo largo de la práctica mostraremos cómo se implementan dichos modelos en R, y analizaremos los resultados de predicción sobre un par de conjuntos de datos de prueba. Entonces, comencemos…

Regresión Lineal Simple (Simple Linear Regression)

La Regresión Lineal Simple es un modelo de regresión en donde una función lineal representa la relación existente entre una variable dependiente y su respectiva variable independiente. Es decir, la ecuación que describe el modelo adopta la forma y = ax+b, en donde y es la variable dependiente, x es la variable independiente, y a, b son los coeficientes de la recta (pendiente y punto de corte, respectivamente) que, bajo algún criterio de minimización como el de mínimos cuadrados, ofrece el mejor ajuste a los datos de entrada. A efectos de entender más claramente el modelo, apliquemos la Regresión Lineal Simple a un conjunto de datos adecuado para ello.

En primer lugar, vamos a establecer el directorio de trabajo, y cargar el conjunto de datos tanto de entrenamiento como de validación:

setwd("D:/ProgramasR/Practicas/ModelosRegresion")
train <- read.csv("train.csv")
test <- read.csv("test.csv")

Haciendo uso de la función str, podemos explorar la estructura del dataframe que contiene ambos conjuntos:

str(train)
## 'data.frame':    700 obs. of  2 variables:
## $ x: int 24 50 15 38 87 36 12 81 25 5 ...
## $ y: num 21.5 47.5 17.2 36.6 87.3 ...
str(test)
## 'data.frame':    300 obs. of  2 variables:
## $ x: int 77 21 22 20 36 15 62 95 20 5 ...
## $ y: num 79.8 23.2 25.6 17.9 41.8 ...

Como podemos ver, el conjunto train contiene 700 observaciones, mientras que el conjunto test tiene 300 observaciones, ambas con solo 2 variables. En este sentido, usaremos el conjunto de entrenamiento para entrenar nuestro modelo de regresión, y luego se empleará el conjunto de validación para probar la calidad del modelo construido.

A fin de tener una idea más clara de la forma de los datos, vamos a graficar el conjunto de entrenamiento. Para ello hagamos uso de la función ggplot de la librería ggplot2:

library(ggplot2)
ggplot() + geom_point(data = train, aes(x = x, y = y)) +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Conjunto de Entrenamiento (train)")

Como podemos ver, el conjunto de datos está formado por una serie de puntos que, claramente, tiene una dependencia lineal entre ellos (estos datos fueron creados de manera artificial por Vahe Andonians y están disponibles en Kaggle).

Aplicar una regresión sobre estos datos implica obtener la línea recta que mejor ajuste la relación existente entre la variable independiente y la variable dependiente. Para ello, vamos a crear un regresor haciendo uso de la función lm del paquete stats:

set.seed(1234)
regresor <- lm(y ~ x, data = train)

Como primer argumento de lm se coloca la fórmula variable dependiente ~ variable independiente. Como segundo argumento se indica el conjunto de datos que se usará para construir el modelo.

Una vez creado el regresor, podemos explorar los resultados y calidad del ajuste haciendo uso de la función summary:

summary(regresor)
## 
## Call:
## lm(formula = y ~ x, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.1485 -2.0200 0.0446 1.8619 8.9172
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.097162 0.211703 -0.459 0.646
## x 1.000516 0.003666 272.887 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.808 on 698 degrees of freedom
## Multiple R-squared: 0.9907, Adjusted R-squared: 0.9907
## F-statistic: 7.447e+04 on 1 and 698 DF, p-value: < 2.2e-16

Entre los datos de interés que ofrece la función summary están la estadística de los residuales (es decir, las distancias que existen entre los valores de las variables y del conjunto de datos y sus proyecciones con la curva que los ajusta), los valores de los coeficientes obtenidos, el p-value (relevancia estadística de la variable independiente como elemento predictivo, y que aparece representado en el reporte como Pr(>|t|)), así como los valores de calidad del ajuste R^2, que en nuestro caso es de 0.9907.

Ya que tenemos el modelo construido, vamos a crear un vector de predicciones basado en el propio conjunto de entrenamiento, y con este vector podremos visualizar la curva de ajuste de los datos. Para obtener las predicciones, hacemos uso de la función predict:

y_predict <- predict(regresor, train)

Luego, construimos la gráfica adecuada:

ggplot() + geom_point(data = train, aes(x = x, y = y), size = 0.9) +
geom_line(aes( x = train$x, y = y_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento")

En efecto, se observa que la curva producida reproduce el comportamiento lineal de los datos de entrenamiento y que la cantidad de puntos tanto por encima como por debajo de esta es semejante, lo que refleja la calidad del ajuste.

Ahora, ya que contamos con nuestro regresor, vamos a realizar predicciones sobre el conjunto de validación, el cual contiene puntos que no fueron usados durante el entrenamiento:

y_test_predict <- predict(regresor, test)

Grafiquemos entonces tanto el conjunto de validación como la curva de ajuste:

ggplot() + geom_point(data = test, aes(x = x, y = y), size = 0.9) + 
geom_line(aes( x = test$x, y = y_test_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Validación")

Y veamos la correlación existente entre los valores y del conjunto de entrenamiento, y los valores predichos para dicho conjunto. Para ello, usamos la función cor:

cor(test$y, y_test_predict)
## [1] 0.9945453

El valor de 0.9945 indica una alta correlación y, por lo tanto, un buen ajuste a los datos por parte del modelo obtenido.

Por último, ya que tenemos nuestro modelo regresor listo, si deseáramos tener una predicción predicción particular para un valor cualquiera de x, podemos hacerlo de la siguiente manera:

predict_value <- predict(regresor, data.frame(x = c(58.7)))
predict_value
##        1 
## 58.63313

En este punto es importante mencionar que la función predict espera como argumento de la variable independiente un dataframe, por lo que es necesario convertir el valor 58.7 seleccionado a tal tipo de dato como se observa en el código anterior.

¡Felicidades, con apenas unas cuantas líneas de código, hemos implementado nuestro primer modelo de regresión!

Regresión Polinomial (Polynomial Regression)

A efectos de la implementación de la regresión polinomial, así como de los próximos modelos de regresión, vamos a utilizar un nuevo conjunto de datos que no tiene características lineales como el anterior (y que fueron generados de manera artificial a partir de ecuaciones matemáticas específicas). A partir de estos datos, crearemos los conjuntos de entrenamiento y validación a ser aplicados al modelo. En primer lugar, carguemos el nuevo conjunto y observemos su estructura:

dataset <- read.csv("nldataset.csv")
str(dataset)
## 'data.frame':    100 obs. of  2 variables:
## $ x: int 1 2 3 4 5 6 7 8 9 10 ...
## $ y: num 8.58 8.5 8.68 7.5 8.03 ...

Como puede verse, este nuevo conjunto está compuesto por 100 observaciones. Visualicemos la forma de este dataset:

ggplot() + geom_point(data = dataset, aes(x = x, y = y)) + 
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Conjunto de Datos No Lineales (dataset)")

Claramente se observa que, en este caso, la relación entre las variables no es lineal, por lo que la Regresión Lineal Simple no será, de entrada, el modelo adecuado a aplicar. Pero al inspeccionar la gráfica vemos que los datos parecen seguir un comportamiento polinomial. Cuando se habla de Regresión Polinomial, se busca el producir entonces una ecuación de ajuste de las variables dependiente — independiente que tenga la forma y=a+bx+cx^2+…+Nx^n, en donde n es el grado del polinomio. Es decir, se introducen al modelo términos polinomiales de la variable independiente hasta lograr el mejor ajuste a los datos.

Ahora bien, antes de crear el modelo de regresión, vamos a generar, a partir del dataset, los conjuntos de entrenamiento y validación. Para ello vamos a seleccionar observaciones al azar dentro del dataset y asignaremos una porción como nltrain y el resto como nltest.

Para ello, utilizaremos la función sample.split del paquete caTools:

library(caTools)
split = sample.split(dataset$y, SplitRatio = 0.7)
nltrain = subset(dataset, split == TRUE)
nltest = subset(dataset, split == FALSE)

El argumento SplitRatio refleja la proporción entre de elementos a seleccionar entre entrenamiento / validación, que en este caso colocamos en 0.7 de modo que 70 observaciones correspondan a entrenamiento y las 30 restantes a validación.

Ahora bien, ya que los conjuntos de datos están creados, para realizar la regresión polinomial, vamos a introducir, en primer lugar, un término de segundo grado a nuestros datos de entrenamiento a fin de que el regresor pueda ser polinomial:

nltrain$x2 <- nltrain$x^2

Al inspeccionar de nuevo el conjunto de entrenamiento:

str(nltrain)
## 'data.frame':    70 obs. of  3 variables:
## $ x : int 1 3 7 8 10 12 13 15 17 18 ...
## $ y : num 8.58 8.68 7.63 9.56 8.2 ...
## $ x2: num 1 9 49 64 100 144 169 225 289 324 ...

Vemos que al dataframe se le incorporó una columna que representa el cuadrado de la variable independiente x.

Ahora, podemos construir nuestro modelo de regresión polinomial:

set.seed(1234)
regresor_poly <- lm(y ~ x + x2, data = nltrain)

Como puede verse, en este caso la fórmula del primer argumento y ~ x + x2 incluye la nueva columna.

Al aplicar la función summary a nuestro nuevo regresor tenemos:

summary(regresor_poly)
## 
## Call:
## lm(formula = y ~ x + x2, data = nltrain)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.5675 -1.4549 -0.2921 1.6128 3.9087
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 11.2920413 0.7719547 14.628 < 2e-16 ***
## x -0.2052973 0.0341121 -6.018 8.24e-08 ***
## x2 0.0095546 0.0003188 29.969 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.904 on 67 degrees of freedom
## Multiple R-squared: 0.9937, Adjusted R-squared: 0.9935
## F-statistic: 5273 on 2 and 67 DF, p-value: < 2.2e-16

Como puede verse, tanto la variable x como la variable x2 son relevantes a efectos de la predicción (valores pequeños del p-value) y se obtiene un R^2 de 0.9946.

Obtengamos las predicciones para el conjunto de entrenamiento y elaboremos la gráfica del modelo obtenido:

y_poly_predict <- predict(regresor_poly, nltrain)
ggplot() + geom_point(data = nltrain, aes(x = x, y = y), size = 0.9) + 
geom_line(aes( x = nltrain$x, y = y_poly_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

En efecto, vemos que la curva de ajuste producida por la regresión sigue la forma no lineal de los datos de entrenamiento.

Ahora, ¿qué ocurre si incorporamos más órdenes al polinomio? Hagamos la prueba:

nltrain$x3 <- nltrain$x^3
regresor_poly <- lm(y ~ x + x2 + x3, data = nltrain)
summary(regresor_poly)
## 
## Call:
## lm(formula = y ~ x + x2 + x3, data = nltrain)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.81697 -0.69354 0.08194 0.75634 2.28105
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.948e+00 5.914e-01 10.059 5.96e-15 ***
## x 3.508e-01 4.732e-02 7.414 2.96e-10 ***
## x2 -3.636e-03 1.048e-03 -3.470 0.000922 ***
## x3 8.541e-05 6.692e-06 12.764 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.03 on 66 degrees of freedom
## Multiple R-squared: 0.9982, Adjusted R-squared: 0.9981
## F-statistic: 1.206e+04 on 3 and 66 DF, p-value: < 2.2e-16
y_poly_predict <- predict(regresor_poly, nltrain)
ggplot() + 
geom_point(data = nltrain, aes(x = x, y = y), size = 0.9) +
geom_line(aes( x = nltrain$x, y = y_poly_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

Ahora, tenemos que la curva de ajuste sigue mucho mejor la forma de los datos, y estos se distribuyen tanto por encima como por debajo de una manera más adecuada. Por otro lado, el valor de R^2 aumenta a 0.9986.

En función de este resultado, podemos entonces incorporar los elementos polinomiales al conjunto de validación, y aplicar la regresión respectiva:

nltest$x2 <- nltest$x^2
nltest$x3 <- nltest$x^3
y_poly_test_predict <- predict(regresor_poly, nltest)
ggplot() + geom_point(data = nltest, aes(x = x, y = y), size = 0.9) + 
geom_line(aes( x = nltest$x, y = y_poly_test_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Validación (nltest)")

Las curvas de ajuste producidas, tanto para los datos de entrenamiento como para validación, reproducen entonces el comportamiento no lineal de los datos, y sirven como modelos para predecir cualquier valor nuevo de la variable independiente que se tome, por ejemplo:

predict_value_poly <- predict(regresor_poly, data.frame(x = 71,
x2 = 71^2,
x3 = 71^3))
predict_value_poly
##        1 
## 43.09998

Obsérvese que, como parámetro de predicción, se debe colocar el dataframe como la variable independiente seleccionada, así como sus respectivas potencias.

Veamos ahora otros modelos de regresión aplicables a este mismo conjunto de datos.

Regresión con Vectores de Soporte o SVR (Support Vector Regression)

La Regresión con Vectores de Soporte o SVR por sus siglas en inglés, es un modelo de regresión basado en las Máquinas de Vectores de Soporte y que, grosso modo, son modelos capaces de generar clasificaciones o regresiones de datos no lineales a partir de la transformación de los datos de entrada a otros espacios de mayores dimensiones. En el caso de la regresión, la SVR busca encontrar aquella curva que sea capaz de ajustar los datos garantizando que la separación entre ésta y ciertos valores específicos del conjunto de entrenamiento (los vectores de soporte) sea la mayor posible. Para entender mejor el concepto, recomiendo echarle un ojo al video Support Vector Machine (SVM) — Fun and Easy Machine Learning.

En nuestro caso, haremos uso de la función svm del paquete e1071 para crear el modelo de regresión SVR:

library(e1071)
set.seed(1234)
regresor_svr <- svm(y ~ x, data = nltrain, type = "eps-regression")

Como puede verse, como fórmula se introduce la relación entre y — x (sin considerar los elementos polinomiales que se introdujeron en la regresión anterior). El parámetro eps-regression es específico para regresión, pues con svm se pueden realizar modelos tanto de regresión como clasificación.

Ya que tenemos el regresor SVR, vamos a realizar las predicciones sobre el conjunto de entrenamiento y visualizar la curva:

y_svr_predict <- predict(regresor_svr, nltrain)
ggplot() + geom_point(data = nltrain, aes(x = x, y = y), size = 0.9) + 
geom_line(aes( x = nltrain$x, y = y_svr_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

Obteniéndose una correlación entre datos de entrenamiento y la predicción de:

cor(nltrain$y, y_svr_predict)
## [1] 0.9978843

Como puede verse en la curva, el regresor SVR produce un resultado no lineal a pensar de no estar construido con componentes polinomiales. El desempeño del regresor SVR dependerá en gran medida de los hiperparámetros del modelo, que en este caso pueden conocerse al usar la función summary:

summary(regresor_svr)
## 
## Call:
## svm(formula = y ~ x, data = nltrain, type = "eps-regression")
##
##
## Parameters:
## SVM-Type: eps-regression
## SVM-Kernel: radial
## cost: 1
## gamma: 1
## epsilon: 0.1
##
##
## Number of Support Vectors: 11

Por defecto, cost, gamma y epsilon tiene los valores mostrados, pero ajustando dichos parámetros es posible obtener un mejor resultado en la regresión. Sin embargo, en este ejercicio no trataremos el tema de las técnicas para ajustar los hiperparámetros de los modelos.

Para nuestro conjunto de validación tendremos:

y_svr_test_predict <- predict(regresor_svr, nltest)
ggplot() + geom_point(data = nltest, aes(x = x, y = y), size = 0.9) + 
geom_line(aes( x = nltest$x, y = y_svr_test_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Validación (nltest)")

Y una correlación de:

cor(nltest$x, y_svr_test_predict)
## [1] 0.941291

¿Cuál será la predicción del SVR para el valor de 71 probado en el caso polinomial?

predict_value_svr <- predict(regresor_svr, data.frame(x = 71))
predict_value_svr
##        1 
## 42.05621

Regresión con Árboles de Decisión (Decision Tree Regression)

Los Árboles de Decisión son modelos de predicción que pueden usarse tanto para clasificación como para regresión, y cuyo funcionamiento se basa en la construcción de reglas lógicas (divisiones de los datos entre rangos o condiciones) a partir de los datos de entrada.

El entrenamiento de los árboles de decisión se centra principalmente en la maximización de la ganancia de información al momento de realizar las reglas lógicas que forman el árbol.

En nuestro ejercicio, usaremos la función rpart del paquete rpart para crear el árbol de regresión:

library(rpart)
set.seed(1234)
regresor_decisiontree <- rpart(y ~ x, data = nltrain,
control = rpart.control(minsplit = 2))

El parámetro control y el valor minsplit igual a 2 establecen que, para el árbol construido, se garantice al menos 2 divisiones de los datos en cada paso del entrenamiento. Esto para asegurarnos que se obtiene al menos una solución adecuada al problema.

Una vez construido el regresor, podemos realizar las predicciones de entrenamiento y visualizar los resultados:

y_dt_predict <- predict(regresor_decisiontree, nltrain)
ggplot() + geom_point(data = nltrain, aes(x = x, y = y), size = 0.9) + 
geom_line(aes( x = nltrain$x, y = y_dt_predict), color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

Con una correlación de:

cor(nltrain$y, y_dt_predict)
## [1] 0.9919931

La forma no lineal de la curva de regresión del árbol de decisión generado tiene que ver con el hecho de que, una vez se logran todas las subdivisiones de los datos durante el entrenamiento y se alcanza el árbol definitivo, cada hoja del árbol, es decir el extremo en donde se fija el valor final de la regresión (o clasificación), tomará el valor promedio de todos los puntos de los datos de entrada que caen en dicha división. Por ello, la curva resultante es escalonada, y para varios valores de la variable dependiente x se tendrán valores promedio de la dependiente y.

Podemos mejorar el aspecto de la curva si aumentamos la resolución de la predicción:

x_grid <- seq(min(nltrain$x), max(nltrain$x), 0.01)
ggplot() + geom_point(data = nltrain, aes(x = x, y = y), size = 0.9) +
geom_line(aes(x = x_grid, y = predict(regresor_decisiontree, data.frame(x = x_grid))),
color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

Para el conjunto de validación tendremos entonces:

y_dt_test_predict <- predict(regresor_decisiontree, nltest)
x_grid <- seq(min(nltest$x), max(nltest$x), 0.01)
ggplot() + geom_point(data = nltest, aes(x = x, y = y), size = 0.9) +
geom_line(aes(x = x_grid, y = predict(regresor_decisiontree, data.frame(x = x_grid))),
color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Validación (nltest)")

Con correlación de validación de:

cor(nltest$y, y_dt_test_predict)
## [1] 0.9840942

Finalmente, la predicción para el valor 71 será:

predict_value_dt <- predict(regresor_decisiontree, data.frame(x = 71))
predict_value_dt
##        1 
## 38.12003

Regresión con Bosques Aleatorios (Random Forest Regression)

La regresión con Bosques Aleatorios o Random Forest, implica la construcción al azar de una gran cantidad de árboles de decisión sobre un mismo conjunto de datos, y la decisión final de la clasificación o la regresión es tomada a partir de calcular el promedio de las predicciones ofrecidas por cada uno de los árboles que conforman el bosque.

Para implementar el Random Forest sobre nuestros datos se empleará la función randomForest del paquete randomForest:

library(randomForest)
set.seed(1234)
regresor_randomForest <- randomForest(y ~ x, data = nltrain, ntree = 10)

El parámetro ntree establece la cantidad de árboles de decisión que forman el bosque del modelo.

Veamos el resultado:

y_rf_predict <- predict(regresor_randomForest, nltrain)

Con correlación de:

cor(nltrain$y, y_rf_predict)
## [1] 0.9991075

x_grid <- seq(min(nltrain$x), max(nltrain$x), 0.01)
ggplot() + geom_point(data = nltrain, aes(x = x, y = y), size = 0.9) +
geom_line(aes(x = x_grid, y = predict(regresor_randomForest, data.frame(x = x_grid))),
color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

Como se observa, el incorporar muchos árboles a la predicción genera como resultado una curva de ajuste bastante más escalonada que en el caso de un solo árbol de decisión. De manera similar, para la validación:

y_rf_test_predict <- predict(regresor_randomForest, nltest)

Con correlación de validación de:

cor(nltest$y, y_rf_test_predict)
## [1] 0.9965915

Y gráfica:

x_grid <- seq(min(nltest$x), max(nltest$x), 0.01)
ggplot() + geom_point(data = nltest, aes(x = x, y = y), size = 0.9) +
geom_line(aes(x = x_grid, y = predict(regresor_randomForest, data.frame(x = x_grid))),
color = "red") +
xlab("Variable Independiente") +
ylab("Variable Dependiente") +
ggtitle("Curva de Ajuste sobre Conjunto de Entrenamiento (nltrain)")

Para el valor 71, tendremos como predicción con el modelo Random Forest:

predict_value_rf <- predict(regresor_randomForest, data.frame(x = 71))
predict_value_rf
##        1 
## 41.15222

Comparación de resultados para caso No Lineal

En los 4 casos anteriores se construyeron modelos de regresión para un conjunto de datos cuyo comportamiento era no lineal, y cada modelo ofreció resultados distintos tanto para las curvas de ajuste como para la predicción del valor de x = 71, que, de hecho, forma parte del conjunto de entrenamiento. Veamos un cuadro comparativo de los resultados obtenidos para cada modelo:

A partir de la diferencia entre el valor verdadero y el valor predicho por cada uno de los modelos, podemos ver que el SVR ofrece la mayor precisión en la predicción, seguido por el Random Forest, la regresión polinomial, y por último el árbol de decisión.

Sin embargo, ya que al momento de construir los regresores se utilizó la función set.seed para fijar la semilla de generación de los números aleatorios inherentes a cada modelo, los resultados de predicción serán los mismos en cada corrida de los algoritmos. Si no se establece la semilla inicial, es posible entonces tener resultados distintos para cada modelo y las precisiones podrán cambiar según el caso.

Con esto, finalizamos la práctica de implementación de Modelos de Regresión en R.