knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(bis557) library(glmnet) library(reticulate) library(purrr) use_condaenv("r-reticulate")
In Python, implement a numerically-stable ridge regression that takes into account colinear (or nearlycolinear) regression variables. Show that it works by comparing it to the output of your R implementation.
data("iris") # create a colinear term iris$colinear <- 2*iris$Petal.Width + 0.1 form <- Sepal.Length ~ . d <- iris mms <- make_model_matrices(form, d, contrasts = NULL) X <- mms$X Y <- mms$Y
# run the ridge regression function - it works without error (r_result <- bis557::ridge_regression(form, d, lambda = 10))
ridge.py
under the folder python
source_python("D:/YALE/20Fall/BIS557/bis557/python/ridge.py") (p_result <- ridge_reg(X, Y, 10))
compare <- as.data.frame(cbind(r_result$coef, p_result)) colnames(compare) <- c("R", "Python") round(compare, 4)
The Python results are the same as the output of my R implementation.
Create an “out-of-core” implementation of the linear model that reads in contiguous rows of a dataframe from a file, updates the model. You may read the data from R and send it to your Python functions for fitting.
We define the loss function as:
$$ \mathcal{L} = (\hat y - y)^2 $$
To minimize the loss, we iteratively update the values of $w$ and $b$ using the value of gradient:
$$ w_{new} = w_{old} - \eta \frac{\partial \mathcal{L}}{\partial {w_{old}}} \ \frac{\partial \mathcal{L}}{\partial {w_{old}}} = \frac{\partial \mathcal{L}}{\partial {\hat y}} \times \frac{\partial \hat y}{\partial {w_{old}}} = 2(\hat y - y) x \ b_{new} = b_{old} - \eta \frac{\partial \mathcal{L}}{\partial {b_{old}}} \ \frac{\partial \mathcal{L}}{\partial {b_{old}}} = \frac{\partial \mathcal{L}}{\partial {\hat y}} \times \frac{\partial \hat y}{\partial {b_{old}}} = 2(\hat y - y) $$
(Reference: Tutorial: Linear Regression with Stochastic Gradient Descent)
# refer to CASL p192 import numpy as np np.random.seed(2020) n = 100 p = 5 X = np.random.randn(n, p) # real coefficients w = np.random.randint(-5, 5, p) b = np.random.randint(-5, 5, 1) y = X @ w + b print(w) # print the real w print(b) # print the real b
sgd.py
under the folder python
source_python("D:/YALE/20Fall/BIS557/bis557/python/sgd.py")
# initialize w and b w = np.ones(p) b = 0 for i in range(int(n)): w, b = sgd(X = X[i, :], y = y[i], w = w, b = b, eta = 0.01 ) np.around(w, decimals = 1) #print the estimated w np.around(b, decimals = 1) #print the estimated b
The results of sgd
function are quite similar to the real coefficients, which means sgd
performs well for linear regression.
Implement your own LASSO regression function in Python. Show that the results are the same as the function implemented in the casl package.
# refer to CASL p192 set.seed(2020) n2 <- 100 p2 <- 500 X2 <- matrix(rnorm(n2 * p2), ncol = p2) beta2 <- c(3, 2, 1, rep(0, p2 - 3)) y2 <- X2 %*% beta2 + rnorm(n = n2, sd = 0.1)
library(casl) # refer to CASL p192 r_bhat <- casl_lenet(X2, y2, lambda = 0.1) names(r_bhat) <- paste0("v", seq_len(n2)) (r_result <- r_bhat[r_bhat != 0])
lasso.py
under the folder python
source_python("D:/YALE/20Fall/BIS557/bis557/python/lasso.py") p_beta <- coord_descent(X2, y2, 0.1) # only print the non-zero results (p_result <- p_beta[p_beta != 0])
compare <- as.data.frame(cbind(r_result, p_result)) colnames(compare) <- c("R", "Python") round(compare, 4)
The results of our lasso
function are exactly the same as the function implemented in the casl
package.
The proposal has been written in a seperated file BIS557 Project Proposal
under the folder project
.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.