library(data.table)
library(ggplot2)
library(caret)
library(jtools)
library(scales)
library(dplyr)
library(lattice)
library(MASS)
library(faraway)
library(cvTools)
library(lmtest)
library(faraway)
library(latex2exp)
library(cvTools)
library(Metrics)
rm(list = ls())
df<- data.table(read.table('ew_f1_2.6598863068_ogle051153.02.txt', header = T, sep = " " , encoding = 'Latin-1'))
df<-df[,-3]
#Planteo inicial de datos#
colnames(df)[1]<-"ti"
colnames(df)[2]<-"yi"
# Parametros Fijos
f1= 2.6598863068
# Pi ya se encuentra definido
graph1 <- ggplot() +
geom_point(df, mapping = aes(x=df$ti, y=df$yi, color='Valores reales')) +
geom_line(df, mapping = aes(x=df$ti, y=df$yi), color='#FF36C2', method='loess',se=F, fullrange = T, alpha=0.3)+
theme_minimal() +
labs(x='ti',y='yi',color=NULL) +
theme(legend.position = 'bottom')
## Warning in geom_line(df, mapping = aes(x = df$ti, y = df$yi), color =
## "#FF36C2", : Ignoring unknown parameters: `method`, `se`, and `fullrange`
graph1
Este gráfico presenta el ajuste de la línea de luz original. Incorpora
los valores reales y los ajustes pertinentes para denotar el
comportamiento de los datos.
# Define the value of f1 and k
k <- 6
# Create a data frame to store the harmonic terms
harmonics <- data.frame(matrix(0, nrow = nrow(df), ncol = 2 * k))
# Generate the harmonic terms
for (j in 1:k) {
harmonics[, (2 * j - 1)] <- sin(2 * pi * f1 * j * df$ti)
harmonics[, (2 * j)] <- cos(2 * pi * f1 * j * df$ti)
}
# Combine the harmonic terms with the other variables
df_harmonics <- cbind(df, harmonics)
# Perform nonlinear regression
reg1 <- nls(yi ~ b0 + b1 * ti + rowSums(harmonics * rep(c(a, b), each = nrow(df))),
data = df, start = c(a = 1, b = 1, b0 = 0, b1 = 0))
sum01<-summary(reg1)
sum01
##
## Formula: yi ~ b0 + b1 * ti + rowSums(harmonics * rep(c(a, b), each = nrow(df)))
##
## Parameters:
## Estimate Std. Error t value Pr(>|t|)
## a 1.533e-02 2.401e-03 6.388 5.94e-10 ***
## b 1.522e-02 2.562e-03 5.944 7.31e-09 ***
## b0 4.973e+00 2.404e+01 0.207 0.836
## b1 4.963e-06 9.807e-06 0.506 0.613
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.07464 on 319 degrees of freedom
##
## Number of iterations to convergence: 1
## Achieved convergence tolerance: 1.933e-07
Este modelo no se considera más adelante, puesto que considera un funcionamiento en el cual solo se incorpora y analiza el valor de un K a la vez. Por ende no cumple con el requerimiento de mostrar la totalidad de ciclos respecto al valor máximo del K. No obstante, permite analizar correctamente el ajuste de cada una de las iteraciones incluidas.
graph1 <- ggplot() +
geom_point(df, mapping = aes(x=df$ti, y=df$yi, color='Valores Reales')) +
geom_line(df, mapping = aes(x=df$ti, y=predict(reg1)), color='#36FFA4', method='loess',se=F, fullrange = T) +
geom_line(df, mapping = aes(x=df$ti, y=df$yi), color='#FF36C2', method='loess',se=F, fullrange = T, alpha=0.3)+
theme_minimal() +
labs(x='ti',y='yi',color=NULL) +
theme(legend.position = 'bottom') +
scale_y_continuous(labels = number_format(scale = 1))
graph1
mean((df$yi-predict(reg1))^2)
## [1] 0.005501552
La idea de aplicación de este modelo se basa en la idea de no linealidad. Por ende, incorpora funciones y analiza su comportamiento dependiendo del valor K asignado arbitrariamente, pero carece de la incorporación o asignación de los demás Y asociados.
## Determinación de K y generación de variables adicionales
k<-1
for (j in 1:k) {
componente_a <- sin(2 * pi * f1 *j* df$ti)
componente_b <- cos(2 * pi * f1 *j* df$ti)
col_name_a <- paste0("componente_a")
col_name_b <- paste0("componente_b")
df$col_name_a <- componente_a
df$col_name_b <- componente_b
}
# Implementación de la regresión
f2=formula(yi~ ti + col_name_a + col_name_b)
reg2 = lm(formula=f2, data=df)
pred <- predict(reg2)
sum02<-summary((reg2))
sum02
##
## Call:
## lm(formula = f2, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.065736 -0.017436 -0.000261 0.018424 0.074491
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.841e+01 9.013e+00 2.043 0.0419 *
## ti -5.223e-07 3.677e-06 -0.142 0.8871
## col_name_a 6.500e-02 2.173e-03 29.916 <2e-16 ***
## col_name_b 8.884e-02 2.242e-03 39.629 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.02802 on 319 degrees of freedom
## Multiple R-squared: 0.8856, Adjusted R-squared: 0.8845
## F-statistic: 822.8 on 3 and 319 DF, p-value: < 2.2e-16
graph1 <- ggplot() +
geom_point(df, mapping = aes(x=df$ti, y=df$yi, color='Valores Reales')) +
geom_line(df, mapping = aes(x=df$ti, y=predict(reg2)), color='#36FFA4') +
geom_line(df, mapping = aes(x=df$ti, y=df$yi), color='#FF36C2', alpha=0.3)+
theme_minimal() +
labs(x='ti',y='yi',color=NULL) +
theme(legend.position = 'bottom') +
scale_y_continuous(labels = number_format(scale = 1))
graph1
mean((df$yi-predict(reg2))^2)
## [1] 0.0007751282
Este modelo, a diferencia del modelo anterior si considera la interacción de las variables dependiendo del k. Por ende realiza una asignación conjunta para realizar el análisis dependiendo del número de valores asignados. No obstante, parece que tampoco cumple con los valores y requerimientos solicitados por la pregunta.
# Define the number of terms and f1 value
k <- 4
# Initialize an empty formula string
formula <- "df$yi ~ df$ti"
# Iterate over the terms and add them to the formula string
for (i in 1:k) {
# Generate the sine and cosine terms for each i
sin_term <- paste("sin(2 * pi * f1 *", i, "* df$ti)", sep = "")
cos_term <- paste("cos(2 * pi * f1 *", i, "* df$ti)", sep = "")
# Add the sine and cosine terms to the formula string
formula <- paste(formula, "+", sin_term, "+", cos_term, sep = " ")
df[, paste0("sin_term", i)] <- eval(parse(text = sin_term))
df[, paste0("cos_term", i)] <- eval(parse(text = cos_term))
}
# Create the final formula
f3 <- formula(yi~., data=df)
reg3 = lm(formula=f3, data=df)
pred <- predict(reg3)
sum03<-summary((reg3))
sum03
##
## Call:
## lm(formula = f3, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.04670 -0.01065 -0.00139 0.01333 0.06640
##
## Coefficients: (2 not defined because of singularities)
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.790e+01 5.863e+00 3.052 0.00246 **
## ti -3.111e-07 2.392e-06 -0.130 0.89662
## col_name_a 6.418e-02 1.416e-03 45.336 < 2e-16 ***
## col_name_b 8.995e-02 1.465e-03 61.397 < 2e-16 ***
## sin_term1 NA NA NA NA
## cos_term1 NA NA NA NA
## sin_term2 2.594e-02 1.404e-03 18.474 < 2e-16 ***
## cos_term2 7.649e-03 1.476e-03 5.181 3.97e-07 ***
## sin_term3 1.217e-02 1.455e-03 8.359 2.10e-15 ***
## cos_term3 -4.414e-03 1.428e-03 -3.091 0.00218 **
## sin_term4 3.321e-03 1.442e-03 2.303 0.02194 *
## cos_term4 -2.058e-03 1.440e-03 -1.429 0.15399
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.01817 on 313 degrees of freedom
## Multiple R-squared: 0.9527, Adjusted R-squared: 0.9514
## F-statistic: 701.1 on 9 and 313 DF, p-value: < 2.2e-16
graph1 <- ggplot() +
geom_point(df, mapping = aes(x=df$ti, y=df$yi, color='Valores Reales')) +
geom_line(df, mapping = aes(x=df$ti, y=predict(reg3)), color='#36FFA4') +
geom_line(df, mapping = aes(x=df$ti, y=df$yi), color='#FF36C2', alpha=0.3)+
theme_minimal() +
labs(x='ti',y='yi',color=NULL) +
theme(legend.position = 'bottom') +
scale_y_continuous(labels = number_format(scale = 1))
graph1
mean((df$yi-predict(reg3))^2)
## [1] 0.0003200887
Este modelo final, incorpora la esencia del planteo armónico. Se enfoca en considerar las distintas instancias de la no linealidad e incorpora los parámetros lineales estimados para cada uno dentro de la estimación. Por lo cual, a diferencia de los modelos anteriores, minimiza el error cuadrático medio con un K=4, a diferencia de los primeros dos modelos que lo encontraban en un K=1.
Como se ha presentado en la parte anterior, se puede apreciar que en los gráficos el ajuste del modelo 3 supera a los dos primeros en la línea ajustada para cada parámetro. No obstante, cabe mencionar que todos los modelos en esencia cuentan con un sobre ajuste de los datos.
Por otro lado, la razón principal de la elección del K=4, junto al modelo 3 es que este modelo minimiza el error cuadrático medio, junto a lo que el K va a determinar el valor mínimo que puede tomar sin entrar en un sobre ajuste excesivo de los datos.
Adicionalmente, se considera que al aumentar el K valores sobre 4, esto produce que el sobre ajuste quite peso a variables importantes para el análisis y afecta en el modelo en general, ya que las variables incorporadas carecen de significancia para el modelo y se intenta minimizar el nivel de variables omitidas.
data.table(Regresión=c('Modelo 03','Modelo 02'),
`R2`=c(sum03$r.squared, sum02$r.squared),
`R2 ajustado`=c(sum03$adj.r.squared, sum02$adj.r.squared),
`Mean Absolute Error` = c(MAE(reg3$fitted.values, df$yi),
MAE(reg2$fitted.values, df$yi)),
`Root Mean Squared Error`=c(RMSE(reg3$fitted.values, df$yi),
RMSE(reg2$fitted.values, df$yi)))
set.seed(12345) ## setear una semilla
training.samples <- createDataPartition(df$yi,p = 0.8, list = FALSE)
train.data <- df[training.samples, ]
test.data <- df[-training.samples, ]
model <- lm(formula = f3, data = train.data)
predictions01 <- predict(model,train.data)
predictions02 <- predict(model,test.data)
data.table(' ' = c('Dentro de muestra','Fuera de muestra'),
RMSE = c(RMSE(predictions01, train.data$yi),
RMSE(predictions02, test.data$yi)),
MAE = c(MAE(predictions01, train.data$yi),
MAE(predictions02, test.data$yi)))
Por lo tanto, parece que el modelo es posee un bajo nivel de explicación associado a las variables fuera de la muestra en el proceso de entrenamiento.
set.seed(123)## setear una semilla
setupLOO <- trainControl(method = "LOOCV")
predLOO <- train(f3,data=df[1:323],method="lm",trControl= setupLOO)
print(predLOO)
## Linear Regression
##
## 323 samples
## 11 predictor
##
## No pre-processing
## Resampling: Leave-One-Out Cross-Validation
## Summary of sample sizes: 322, 322, 322, 322, 322, 322, ...
## Resampling results:
##
## RMSE Rsquared MAE
## 0.01845812 0.9497015 0.01466882
##
## Tuning parameter 'intercept' was held constant at a value of TRUE
Como presentamos en este análisis, el modelo se somete a dos formas de validación cruzada para la determinación de su error de predicción. En este caso va a corresponder a un 0.01845812 con el método de LOO y a un 0.02167478 con el método de K-Folds considerando los valores fuera de la muestra.
Por estas razones el modelo muestra un buen desempeño en las pruebas actuales y es un candidato idóneo para el desarrollo de consideraciones dentro de la muestra. No obstante, es necesario someterlo a nuevas validaciones y formas para poder justificar la elección correcta del K y la formulación escogida.
df<- data.table(read.table('ew_f1_2.6598863068_ogle051153.02.txt', header = T, sep = " " , encoding = 'Latin-1'))
df<-df[,-3]
#Planteo inicial de datos#
colnames(df)[1]<-"ti"
colnames(df)[2]<-"yi"
# Pi ya se encuentra definido
Para la consideración del tiempo t0 se va a considerar el mínimo correspondiente a la variable del tiempo. Esto garantiza que sea el tiempo inicial en un instante propio del tiempo. No obstante, este resultado se va a modificar en el caso de utilizar directamente el valor de ti=2450458, cambiando la concavidad del problema. Adicionalmente, si se toma en consideración el tiempo inicial con la sustracción de una unidad para asegurar un instante de tiempo fuera de la base, este modelo también se modifica. Se incorporan comentarios con los códigos para realizar las pruebas pertinentes.
# Definir los parámetros t0 y f1
t0 <- min(df$ti) # Valor de referencia para t0
#t0 <- 2450458 # Valor directo
#t0 <- min(df$ti)-1 # Valor fuera de la base
# Parametros Fijos
f1= 2.6598863068
# Calcular zi
df$zi <- (df$ti - t0) %% (1 / f1)
# Graficar zi vs yi
graph1 <- ggplot() +
geom_point(df, colour = "#36DAFF", size = 1, mapping = aes(x=df$zi, y=df$yi)) +
theme_minimal() +
labs(x='zi',y='yi', title = "Gráfico de zi v/s yi") +
theme(legend.position = 'bottom') +
scale_y_continuous(labels = number_format(scale = 1))
graph1
# Ajuste de polinomio a los datos (zi, yi)
grados <- 1:9 # Rango de grados del polinomio a probar
ajustes <- list() # Lista para almacenar los ajustes
# Iterar sobre los diferentes grados del polinomio
for (grado in grados) {
polinomio <- poly(df$zi, degree = grado, raw = TRUE) # Generar polinomio de grado 'grado'
ajuste <- lm(df$yi ~ polinomio) # Ajustar modelo lineal utilizando el polinomio
# Almacenar el ajuste en la lista
ajustes[[as.character(grado)]] <- ajuste
}
# Calcular los errores cuadrados medios (MSE) de los ajustes
mse <- sapply(ajustes, function(x) mean(x$residuals^2))
# Identificar el menor grado del polinomio que ajusta a los datos
menor_grado <- which.min(mse)
menor_grado
## 9
## 9
# Generar el polinomio de grado 10
pol_10 <- poly(df$zi, degree = menor_grado, raw = TRUE)
f4<-yi ~ pol_10
# Ajustar el modelo de regresión polinomial con grado 10
reg_pol <- lm(f4, data=df)
df$pred<-predict(reg_pol)
# Imprimir el resumen del modelo
sum04<-summary(reg_pol)
sum04
##
## Call:
## lm(formula = f4, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.046889 -0.011062 -0.001053 0.013358 0.066347
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.726e+01 8.093e-03 2132.913 <2e-16 ***
## pol_101 3.354e+00 1.321e+00 2.539 0.0116 *
## pol_102 -1.019e+02 6.837e+01 -1.491 0.1369
## pol_103 1.680e+02 1.595e+03 0.105 0.9162
## pol_104 1.375e+04 2.001e+04 0.687 0.4925
## pol_105 -1.690e+05 1.465e+05 -1.154 0.2493
## pol_106 9.337e+05 6.439e+05 1.450 0.1480
## pol_107 -2.755e+06 1.674e+06 -1.646 0.1007
## pol_108 4.213e+06 2.368e+06 1.779 0.0762 .
## pol_109 -2.626e+06 1.405e+06 -1.869 0.0625 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.01817 on 313 degrees of freedom
## Multiple R-squared: 0.9528, Adjusted R-squared: 0.9514
## F-statistic: 701.6 on 9 and 313 DF, p-value: < 2.2e-16
ggplot() +
geom_segment(df, mapping = aes(x=df$zi, xend=df$zi, y=df$yi, yend=df$pred)) +
geom_point(df, mapping = aes(x=df$zi, y=df$yi, color='Valores reales')) +
geom_line(df, mapping = aes(x=df$zi, y=df$pred, color='Valores predichos'), method='loess',se=T, fullrange = T, size=1) +
theme_minimal() +
labs(x='Position',y='Height',color=NULL, title = "Modelo 2") +
theme(legend.position = 'bottom') +
scale_y_continuous(labels = number_format(scale = 1))
El proceso de selección del K se realizó gracias a la consideración del error cuadrático medio. En este modelo se escoge e implementa un K=9, no obstante, se ha determinado que para minimizar el sobre ajuste de los datos y tener un modelo más generalizable es necesario tomar un K entre el valor de 2 y el valor de 4.
No obstante, para buscar generar la comparación más cercana con el modelo anterior, se ha escogido el valor de 9, que ajusta los valores sin llegar a un sobre ajuste excesivo, pasando por el centro de toda la muestra, minimizando el error cuadrático bajo las consideraciones antes expuestas.
set.seed(12345) ## setear una semilla
training.samples <- createDataPartition(df$yi,p = 0.8, list = FALSE)
train.data <- df[training.samples, ]
test.data <- df[-training.samples, ]
model <- lm(f3, data = train.data)
predictions01 <- predict(model,train.data)
predictions02 <- predict(model,test.data)
data.table(' ' = c('Dentro de muestra','Fuera de muestra'),
RMSE = c(RMSE(predictions01, train.data$yi),
RMSE(predictions02, test.data$yi)),
MAE = c(MAE(predictions01, train.data$yi),
MAE(predictions02, test.data$yi)))
set.seed(12345) ## setear una semilla
training.samples <- createDataPartition(df$yi,p = 0.8, list = FALSE)
train.data <- df[training.samples, ]
test.data <- df[-training.samples, ]
model <- lm(yi~ zi + zi^2 + zi^3 + zi^4 + zi^5 + zi^6, data = train.data)
predictions01 <- predict(model,train.data)
predictions02 <- predict(model,test.data)
data.table(' ' = c('Dentro de muestra','Fuera de muestra'),
RMSE = c(RMSE(predictions01, train.data$yi),
RMSE(predictions02, test.data$yi)),
MAE = c(MAE(predictions01, train.data$yi),
MAE(predictions02, test.data$yi)))
data.table(Regresión=c('Modelo 03','Modelo 04'),
`R2`=c(sum03$r.squared, sum04$r.squared),
`R2 ajustado`=c(sum03$adj.r.squared, sum04$adj.r.squared),
`Mean Absolute Error` = c(MAE(reg3$fitted.values, df$yi),
MAE(reg_pol$fitted.values, df$yi)),
`Root Mean Squared Error`=c(RMSE(reg3$fitted.values, df$yi),
RMSE(reg_pol$fitted.values, df$yi)))
En esta sección se presentan todos los métodos de evaluación implementados para la determinación del modelo. Dadas las características del modelo 3 y 4, es esperable que exista un mejor ajuste con el modelo 3, lo cual es el resultado obtenido del análisis. No obstante, la diferencia entre el modelo transformado y el modelo básico es mínima. Por lo cual, es mejor presentar la diferencia con un modelo menos ajustado en la parte 3. Ya que esto va a dar mejor punto de comparación para la determinación final.
rm(list = ls())
df<- data.table(read.table('sys.txt', header = T, sep = " " , encoding = 'Latin-1'))
colnames(df)[1]<-"sys1"
library(pls)
##
## Attaching package: 'pls'
## The following object is masked from 'package:caret':
##
## R2
## The following object is masked from 'package:stats':
##
## loadings
library(psych)
##
## Attaching package: 'psych'
## The following object is masked from 'package:faraway':
##
## logit
## The following objects are masked from 'package:scales':
##
## alpha, rescale
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
#Split the data
idx<-floor(0.8*nrow(df))
#Set the partition
train_ind<-sample(seq_len(nrow(df)), size=idx)
train<-df[train_ind,]
test<-df[-train_ind,]
pc<-df[,-1]
pc.fit<-prcomp(~., data=train)
screeplot(pc.fit, type="l", main="Sreeplot for SYS features" )
# Estimar el modelo de regresión en componentes principales
modelo_pls <- plsr(sys1 ~ .,ncomp=1, data=df, validation="CV") # ncomp es el número de componentes principales a considerar
# Resumen del modelo
sum00<-summary(modelo_pls)
## Data: X dimension: 1643 2658
## Y dimension: 1643 1
## Fit method: kernelpls
## Number of components considered: 1
##
## VALIDATION: RMSEP
## Cross-validated using 10 random segments.
## (Intercept) 1 comps
## CV 20.82 21.16
## adjCV 20.82 21.12
##
## TRAINING: % variance explained
## 1 comps
## X 2.352
## sys1 4.464
sum00
## NULL
# Predicción
pls_predict<-predict(modelo_pls)
# Calculo de Error cuadratico medio
rmse_value <- rmse(actual=df$sys1, predicted=pls_predict)
# R-squared (R2) calculation
y_mean <- mean(df$sys1)
ss_total <- sum((df$sys1 - y_mean)^2)
ss_residual <- sum((df$sys1 - pls_predict)^2)
r_squared <- 1 - (ss_residual / ss_total)
# Adjusted R-squared (R2 adjusted) calculation
n <- nrow(train)
p <- ncol(train) - 1 # Number of predictors (excluding the intercept)
r_squared_adjusted <- (1-(ss_residual / ss_total)*((n-p)/(n-1)))
# Print RMSE, R-squared, and adjusted R-squared
print(paste("RMSE:", rmse_value))
## [1] "RMSE: 20.3387868916449"
print(paste("R-squared:", r_squared))
## [1] "R-squared: 0.0446448036865995"
print(paste("Adjusted R-squared:", r_squared_adjusted))
## [1] "Adjusted R-squared: 1.97791118343123"
En este modelo se aplican las conspiraciones indagatorias antes realizadas para poder determinar el número de componentes. En esta formulación se implementa un modelo de componentes que minimiza el error y toma en cuenta los valores de prueba para el modelo final.
library(glmnet)
## Loading required package: Matrix
## Loaded glmnet 4.1-7
#define response variable
y <- data.matrix(df[,1])
#define matrix of predictor variables
x <- data.matrix(df[,-1])
#fit ridge regression model
model <- glmnet(x, y, alpha = 0)
#view summary of model
summary(model)
## Length Class Mode
## a0 100 -none- numeric
## beta 265800 dgCMatrix S4
## df 100 -none- numeric
## dim 2 -none- numeric
## lambda 100 -none- numeric
## dev.ratio 100 -none- numeric
## nulldev 1 -none- numeric
## npasses 1 -none- numeric
## jerr 1 -none- numeric
## offset 1 -none- logical
## call 4 -none- call
## nobs 1 -none- numeric
#perform k-fold cross-validation to find optimal lambda value
cv_model <- cv.glmnet(x, y, alpha = 0)
#find optimal lambda value that minimizes test MSE
best_lambda <- cv_model$lambda.min
best_lambda
## [1] 1484.406
#produce plot of test MSE by lambda value
plot(cv_model)
#find coefficients of best model
best_model <- glmnet(x, y, alpha = 0, lambda = best_lambda)
sum01<-summary(best_model)
sum01
## Length Class Mode
## a0 1 -none- numeric
## beta 2658 dgCMatrix S4
## df 1 -none- numeric
## dim 2 -none- numeric
## lambda 1 -none- numeric
## dev.ratio 1 -none- numeric
## nulldev 1 -none- numeric
## npasses 1 -none- numeric
## jerr 1 -none- numeric
## offset 1 -none- logical
## call 5 -none- call
## nobs 1 -none- numeric
#produce Ridge trace plot
plot(model, xvar = "lambda")
abline(h=0,
col = "yellow", # Modify color
lty = "dashed", # Modify line type
lwd = 3)
#use fitted best model to make predictions
y_predicted <- predict(model, s = best_lambda, newx = x)
#find SST and SSE
sst <- sum((y - mean(y))^2)
sse <- sum((y-y_predicted)^2)
#find R-Squared
R2_ridge <- 1 - sse/sst
R2_ridge
## [1] 0
El modelo de Ridge presenta todos los cálculos asociados a su implementación y visualización. Por los resultados obtenidos se presenta una conclusión improbable. Ya que en esta formulación se muestra como la mayoría de las variables tienden a cero, esto produce que la conclusión final sea que la presión sistólica no pareciera tener tanta determinación a partir de una componente genética. Por lo cual, la alternativa es que el modelo puede mostrar ciertas variables influyentes, pero existe otra información que no está observada por la determinación de esta variable.
# R-squared (R2) calculation
y_mean1 <- mean(y)
ss_total1 <- sum((y - y_mean1)^2)
ss_residual1 <- sum((y - y_predicted)^2)
r_squared1 <- 1 - (ss_residual1 / ss_total1)
# Adjusted R-squared (R2 adjusted) calculation
n1 <- nrow(df)
p1 <- ncol(df) - 1 # Number of predictors (excluding the intercept)
adj_R2_ridge <- (1-(ss_residual / ss_total)*((n1-p1)/(n1-1)))
rmse_ridge <- rmse(actual=y, predicted=y_predicted)
# Print RMSE, R-squared, and adjusted R-squared
print(paste("RMSE:", rmse_ridge))
## [1] "RMSE: 20.8085879664976"
print(paste("R-squared:", r_squared1))
## [1] "R-squared: 0"
print(paste("Adjusted R-squared:", adj_R2_ridge))
## [1] "Adjusted R-squared: 1.59055147640566"
data.table(Regresión=c('Modelo CP','Modelo Ridge'),
`R2`=c(r_squared, r_squared1),
`R2 ajustado`=c(r_squared_adjusted, adj_R2_ridge),
`Root Mean Squared Error`=c(rmse_value, rmse_ridge))
Dada la comparación cruzada extraída de las dos implementaciones, podemos concluir que el modelo de componentes principales muestra un mejor ajuste que el modelo de Ridge, en la consideración de poder explicar mejor los datos. Por otro lado, el modelo de Ridge nos permite apreciar la importancia de algunas variables en el análisis final, puesto que el modelo en sí penaliza ciertos valores y los acerca a cero.