# Homework 6 for the University of Tulsa's CS-7863 Sci-Stat Course # Penalized Machine Learning # Professor: Dr. McKinney, Spring 2023 # Noah L. Schrick - 1492657 if (!require("data.table")) install.packages("data.table") library(data.table) # 1. Penalized Regression and Classification ## a. Modified Ridge classification for LASSO penalties source("Schrick-Noah_Ridge-LASSO-Regression.R") ### Use npdro simulated data to test source("Schrick-Noah_Simulated-Data.R") bundled_data <- create_data() run_comparison <- function(bundled_data){ ### LASSO unpen_beta <- lasso_coeff(bundled_data$train.X, bundled_data$train.y,lambda=0) lasso.df <- data.frame(att=c("intercept", colnames(bundled_data$train.X)), scores=unpen_beta$betas, abs_scores=abs(unpen_beta$betas)) lasso.res <- dplyr::slice_max(lasso.df,order_by=abs_scores,n=20) lasso.table <- as.data.table(lasso.res) ### Compare with Ridge #### Find lambda tune_results <- tune_ridge(bundled_data$train.X, bundled_data$train.y, num_folds=10, 2^seq(-5,5,1), verbose=F) plot(log(tune_results$cv.table$hyp), tune_results$cv.table$means, type="l", xlab="lambda", ylab="CV Mean Loss") abline(v=tune_results$lam.min) tune_results$lam.min #### Use lam.min for Ridge Regression ridge_result <- ridge_betas(bundled_data$train.X, bundled_data$train.y, beta_init = NULL, lam=tune_results$lam.min, method="BFGS") ridge.df <- data.frame(att=c("intercept", colnames(bundled_data$train.X)), scores=ridge_result$betas, abs_scores=abs(ridge_result$betas)) ridge.res <- dplyr::slice_max(ridge.df,order_by=abs_scores,n=20) ridge.table <- as.data.table(ridge.res) ### Compare with Random Forest source("Schrick-Noah_Random-Forest.R") rf_result <- rf_comp(bundled_data$train) rf.df <- data.frame(att=c(colnames(bundled_data$train.X)), scores=rf_result$rf2_imp$rf_score) rf_res <- dplyr::slice_max(rf.df,order_by=scores, n=20) rf.table <- as.data.table(rf_res) ### Compare with glmnet source("Schrick-Noah_glmnet.R") #### Alpha = 0 glm.res.0 <- glm_fcn(bundled_data$train.X, bundled_data$train.y, 0) glm.df.0 <- data.frame(att=c("intercept", colnames(bundled_data$train.X)), scores=glm.res.0$lambda.1se, abs_scores=glm.res.0$abs_scores) glm.df.0.res <- dplyr::slice_max(glm.df.0,order_by=abs_scores,n=20) glm.0.table <- as.data.table(glm.df.0.res) #### Alpha = 1 glm.res.1 <- glm_fcn(bundled_data$train.X, bundled_data$train.y, 1) # alpha=1 glm.df.1 <- data.frame(att=c("intercept", colnames(bundled_data$train.X)), scores=glm.res.1$lambda.1se, abs_scores=glm.res.1$abs_scores) glm.df.1.res <- dplyr::slice_max(glm.df.1,order_by=abs_scores,n=20) glm.1.table <- as.data.table(glm.df.1.res) ### Plot #### Convert names to indices lasso.df$att <- match(lasso.df$att,colnames(bundled_data$train)) ridge.df$att <- match(ridge.df$att,colnames(bundled_data$train)) rf.df$att <- match(rf.df$att,colnames(bundled_data$train)) glm.df.0$att <- match(glm.df.0$att,colnames(bundled_data$train)) glm.df.1$att <- match(glm.df.1$att,colnames(bundled_data$train)) #### Scale lasso.df$abs_scores <- scale(lasso.df$abs_scores) ridge.df$abs_scores <- scale(ridge.df$abs_scores) rf.df$scores <- scale(rf.df$scores) glm.df.0$abs_scores <- scale(glm.df.0$abs_scores) glm.df.1$abs_scores <- scale(glm.df.1$abs_scores) plot(x=lasso.df$att, y=lasso.df$abs_scores, type="l", xlab="Vars", ylab="Coefficients (Abs Scores)", xaxt="n", col="blue", ylim=c(-1,3), main="Scaled scores for simulated data feature selection") axis(1, at=1:101, labels=colnames(bundled_data$train), cex.axis=0.5) lines(x=ridge.df$att, y=ridge.df$abs_scores, col="red") lines(x=rf.df$att, y=rf.df$scores, col="green") lines(x=glm.df.0$att, y=glm.df.0$abs_scores, col="bisque4") lines(x=glm.df.1$att, y=glm.df.1$abs_scores, col="purple") legend(x="topleft", legend=c("LASSO", "Ridge", "Random Forest","glmnet (alpha=0)", "glmnet (alpha=1)"), lty=c(1,1,1,1,1), col=c("blue", "red", "green", "bisque4", "purple"), cex=1) return(lasso.df) } lasso_df.a <- run_comparison(bundled_data) ## b. Repeat comparison using a graph with clusters source("Schrick-Noah_graphs.R") bundled_graph <- sim_graph_data() bundled_graph_data <- bundled_graph$bundled_graph_data g1 <- bundled_graph$g1 lasso_df.b <- run_comparison(bundled_graph_data) ## c. Use npdro and igraph to create knn ### Bundled Graph Data my.k <- 3 # larger k, fewer clusters npdr.nbpairs.idx.g <- npdro::nearestNeighbors(t(bundled_graph_data$train.X), # transpose does dist between predictors # without transpose does dist between samples #nbd.method="multisurf", k=0, nbd.method = "relieff", nbd.metric="manhattan", k=my.k) knn.graph.g <- graph_from_edgelist(as.matrix(npdr.nbpairs.idx.g), directed=F) knn.graph.g <- simplify(knn.graph.g) ### Plot network plot.igraph(knn.graph.g,layout=layout_with_fr(knn.graph.g), vertex.color="red", vertex.size=3,vertex.label=NA, main="Manhattan, knn-graph from simulated data with erdos-renyi graph structure") is_isomorphic_to(g1, knn.graph.g) plot(g1) clusters <- cluster_louvain(knn.graph.g) plot(knn.graph.g, mark.groups=clusters) ## d. Add Laplace graph penalty Lhat <- laplacian_matrix(g1, normalized = TRUE) ### Find lambda tune_graph_results <- tune_ridge(bundled_graph_data$train.X, bundled_graph_data$train.y, num_folds=10, 2^seq(-5,5,1), verbose=F) plot(log(tune_graph_results$cv.table$hyp), tune_graph_results$cv.table$means, type="l", xlab="lambda", ylab="CV Mean Loss") abline(v=tune_graph_results$lam.min) tune_graph_results$lam.min lap.penalty <- tune_graph_results$lam.min*Lhat ### Find resulting beta coeffs unpen_beta_lap <- lasso_coeff(bundled_graph_data$train.X, bundled_graph_data$train.y, lap_penalty=lap.penalty) lasso.df.lap <- data.frame(att=c("intercept", colnames(bundled_graph_data$train.X)), scores=unpen_beta_lap$betas, abs_scores=abs(unpen_beta_lap$betas)) lasso.res.lap <- dplyr::slice_max(lasso.df.lap,order_by=abs_scores,n=20) lasso.table.lap <- as.data.table(lasso.res.lap) ### Compare to a) and b) lasso.df.lap$att <- match(lasso.df.lap$att,colnames(bundled_graph_data$train)) lasso.df.lap$abs_scores <- scale(lasso.df.lap$abs_scores) plot(x=lasso.df.lap$att, y=lasso.df.lap$abs_scores, type="l", xlab="Vars", ylab="Coefficients (Abs Scores)", xaxt="n", col="blue", ylim=c(-1,3), main="Scaled scores for simulated data feature selection for various LASSO approaches") lines(x=lasso_df.a$att, y=lasso_df.a$abs_scores, col="red") lines(x=lasso_df.b$att, y=lasso_df.b$abs_scores, col="green") legend(x="topleft", legend=c("Base", "Erdos-Renyi Graph Structure", "Graph Laplacian Penalty"), lty=c(1,1,1), col=c("blue", "red", "green"), cex=1) # 2. Gradient Descent ## Write fn with learning param grad.rosen <- function(xvec, a=2, b=100){ x <- xvec[1]; y <- xvec[2]; f.x <- -2*(a-x) - 4*b*x*(y-x^2) f.y <- 2*b*(y-x^2) return( c(f.x, f.y)) } a = 2 b=100 alpha = .0001 # learning rate p = c(0,0) # start for momentum xy = c(-1.8, 3.0) # guess for solution # gradient descent epochs = 1000000 for (epoch in 1:epochs){ p = -grad.rosen(xy,a,b); xy = xy + alpha*p; } print(xy) # Should be: ~(2,4) # Using optim: f.rosen <- function(xvec, a=2, b=100){ #a <- 2; b <- 1000; x <- xvec[1]; y <- xvec[2]; return ( (a-x)^2 + b*(y-x^2)^2) } sol.BFGS <- optim(par=c(-1.8,3.0), fn=function(x){f.rosen(x,a=2,b=100)}, gr=function(x){grad.rosen(x,a=2,b=100)}, method="BFGS") sol.BFGS$par