第3章 グループLasso

37

gr <- function(X, y, lambda) {
  nu <- 1 / max(2 * eigen(t(X) %*% X)$values)
  p <- ncol(X)
  beta <- rnorm(p)
  beta.old <- rnorm(p)
  while (max(abs(beta - beta.old)) > 0.001) {
    beta.old <- beta
    gamma <- ## 空欄(1) ##
    beta <- ## 空欄(2) ##
  }
  return(beta)
}

## データの生成
n <- 100
p <- 3
X <- matrix(rnorm(n * p), ncol = p)
beta <- rnorm(p)
epsilon <- rnorm(n)
y <- 0.1 * X %*% beta + epsilon

## 係数の値の変化を表示
lambda <- seq(1, 50, 0.5)
m <- length(lambda)
beta <- matrix(nrow = m, ncol = p)
for (i in 1:m) {
  est <- gr(X, y, lambda[i]) 
  for (j in 1:p)
    beta[i, j] <- est[j]
}
y.max <- max(beta)
y.min <- min(beta)
plot(lambda[1]:lambda[m], ylim = c(y.min, y.max),
     xlab = "lambda", ylab = "係数の値", type = "n")
for (j in 1:p)
  lines(lambda, beta[, j], col = j + 1)
legend("topright", legend = paste("係数", 1:p), lwd = 2, col = 2:(p + 1))
segments(lambda[1], 0, lambda[m], 0)

38

n <- 100
p <- 1  # p <- 3 
X <- matrix(rnorm(n * p), ncol = p)
beta <- rnorm(p)
epsilon <- rnorm(n)
y <- 0.1 * X %*% beta + epsilon
lambda <- 0.01
nu <- 1 / max(2 * eigen(t(X) %*% X)$values)
p <- ncol(X)
m <- 10
beta <- rep(1, p)
beta.old <- rep(0, p)
t <- 0
val <- matrix(0, m, p)
while (t < m) {
  t <- t + 1
  val[t, ] <- beta
  beta.old <- beta
  gamma <- ## 空欄(1) ##
  beta <- ## 空欄(2) ##
}
eval <- array(dim = m) 
val.final <- val[m, ]
for (i in 1:m)
  eval[i] <- norm(val[i, ] - val.final, "2")
plot(1:m, ylim = c(0, eval[1]), type = "n",
     xlab = "回数", ylab = "L2 誤差", main = "FISTA と ISTA の比較")
lines(eval, col = "blue")
beta <- rep(1, p)
beta.old <- rep(0, p)
alpha <- 1
gamma <- beta
t <- 0
val <- matrix(0, m, p)
while (t < m) {
  t <- t + 1
  val[t, ] <- beta
  beta.old <- beta
  w <- ## 空欄(3) ##
  beta <- ## 空欄(4) ##
  alpha.old <- alpha
  alpha <- ## 空欄(5) ##
  gamma <- ## 空欄(6) ##
}
val.final <- val[m, ]
for (i in 1:m)
  eval[i] <- norm(val[i, ] - val.final, "2")
lines(eval, col = "red")
legend("topright", c("FISTA", "ISTA"), lwd = 1, col = c("red", "blue"))

41(b)

fista <- function(X, y, lambda) {
  nu <- 1 / max(2 * eigen(t(X) %*% X)$values)
  p <- ncol(X)
  alpha <- 1
  beta <- rnorm(p)
  beta.old <- rnorm(p)
  gamma <- beta
  while (max(abs(beta - beta.old)) > 0.001) {
    print(beta)
    beta.old <- beta
    w <- ## 空欄(1) ##
    beta <- ## 空欄(2) ##
    alpha.old <- alpha
    alpha <- (1 + sqrt(1 + 4 * alpha ^ 2)) / 2
    gamma <- beta + (alpha.old - 1) / alpha * (beta - beta.old)
  }
  return(beta)
}

42

group.lasso <- function(z, y, lambda = 0) {
  J <- length(z)
  theta <- list()
  for (j in 1:J)
    theta[[j]] <- rep(0, ncol(z[[j]]))
  for (m in 1:10) {
    for (j in 1:J) {
      r <- y
      for (k in 1:J) {
        if (k != j)
          r <- r - ## 空欄(1) ##
      }
      theta[[j]] <- ## 空欄(2) ##
    }
  }
  return(theta)
}
  
## データの生成
N <- 100
J <- 2
u <- rnorm(n)
v <- u + rnorm(n)
s <- 0.1 * rnorm(n)
t <- 0.1 * s + rnorm(n)
y <- u + v + s + t + rnorm(n)
z <- list()
z[[1]] <- cbind(u, v)
z[[2]] <- cbind(s, t)  

## 係数の値の変化を表示
lambda <- seq(1, 500, 10)
m <- length(lambda)
beta <- matrix(nrow = m, ncol = 4)
for (i in 1:m) {
  est <- group.lasso(z, y, lambda[i])
  beta[i, ] <- c(est[[1]][1], est[[1]][2], est[[2]][1], est[[2]][2])
}
y.max <- max(beta)
y.min <- min(beta)
plot(lambda[1]:lambda[m], ylim = c(y.min, y.max),
     xlab = "lambda", ylab = "係数の値", type = "n")
lines(lambda, beta[, 1], lty = 1, col = 2)
lines(lambda, beta[, 2], lty = 2, col = 2)
lines(lambda, beta[, 3], lty = 1, col = 4)
lines(lambda, beta[, 4], lty = 2, col = 4)
legend("topright",
       legend = c("グループ1", "グループ1", "グループ2", "グループ2"),
       lwd = 1, lty = c(1, 2), col = c(2, 2, 4, 4))
segments(lambda[1], 0, lambda[m], 0)

44

sparse.group.lasso <- function(z, y, lambda = 0, alpha = 0) {
  J <- length(z)
  theta <- list()
  for (j in 1:J)
    theta[[j]] <- rep(0, ncol(z[[j]]))
  for (m in 1:10) {
    for (j in 1:J) {
      r <- y
      for (k in 1:J) {
        if (k != j)
          r <- r - z[[k]] %*% theta[[k]]
      }
      theta[[j]] <- ## 空欄(1) ## 
    }
  }
  return(theta)
}

sparse.gr <- function(X, y, lambda, alpha = 0) {
  nu <- 1 / max(2 * eigen(t(X) %*% X)$values)
  p <- ncol(X)
  beta <- rnorm(p)
  beta.old <- rnorm(p)
  while (max(abs(beta - beta.old)) > 0.001) {
    beta.old <- beta
    gamma <- beta + nu * t(X) %*% (y - X %*% beta)
    delta <- ## 空欄(2) ##
    beta <- ## 空欄(3) ##
  }
  return(beta)
}

46

## データの生成
n <- 100
J <- 2
x <- rnorm(n)
y <- x + cos(x)
z[[1]] <- cbind(rep(1, n), x)
z[[2]] <- cbind(## 空欄(1) ##)

## 係数の値の変化を表示
lambda <- seq(1, 200, 5)
m <- length(lambda)
beta <- matrix(nrow = m, ncol = 5)
for (i in 1:m) {
  est <- ## 空欄(2) ##
  beta[i, ] <- c(est[[1]][1], est[[1]][2], est[[2]][1], est[[2]][2], est[[2]][3])
}
y.max <- max(beta)
y.min <- min(beta)
plot(lambda[1]:lambda[m], ylim = c(y.min, y.max),
     xlab = "lambda", ylab = "係数の値", type = "n")
lines(lambda, beta[, 1], lty = 1, col = 2)
lines(lambda, beta[, 2], lty = 2, col = 2)
lines(lambda, beta[, 3], lty = 1, col = 4)
lines(lambda, beta[, 4], lty = 2, col = 4)
lines(lambda, beta[, 5], lty = 3, col = 4)
legend("topright", legend = c("1", "x", "cos x", "cos 2x", "cos 3x"),
       lwd = 1, lty = c(1, 2, 1, 2, 3), col = c(2, 2, 4, 4, 4))
segments(lambda[1], 0, lambda[m], 0)

i <- 5  # lambda[5]の値を用いた

f.1 <- function(x) {
  return(beta[i, 1] + beta[i, 2] * x)
}

f.2 <- function(x) {
  return(beta[i, 3] * cos(x) + beta[i, 4] * cos(2 * x) + beta[i, 5] * cos(3 * x))
}

f <- function(x) {
  return(f.1(x) + f.2(x))
}

curve(f.1(x), -5, 5, col = "red", ylab = "関数の値")
curve(f.2(x), -5, 5, col = "blue", add = TRUE)
curve(f(x), -5, 5, add = TRUE)
legend("topleft", legend = c("f = f.1 + f.2", "f.1", "f.2"),
       col = c(1, "red", "blue"), lwd = 1)