第7章 多変量解析

93

soft.th <- function(lambda, z) {
  return(sign(z) * pmax(abs(z) - lambda, 0))
}  # z がベクトルでも,soft.th は動作する

SCoTLASS <- function(lambda, X) {
  n <- nrow(X)
  p <- ncol(X)
  v <- rnorm(p)
  v <- v / norm(v, "2")
  for (k in 1:200) {
    u <- X %*% v
    u <- u / norm(u, "2")
    v <- ## 空欄 ##
    v <- soft.th(lambda, v)
    size <- norm(v, "2")
    if (size > 0) {
      v <- v / size
    } else {
      break
    }
  }
  if (norm(v, "2") == 0)
    print("v の全要素が 0 になった")
  return(v)
}

## サンプル
n <- 100
p <- 50
X <- matrix(rnorm(n * p), nrow = n)
lambda.seq <- 0:10 / 10
S <- NULL
T <- NULL
for (lambda in lambda.seq) {
  v <- SCoTLASS(lambda, X)
  S <- c(S, sum(sign(v ^ 2)))
  T <- c(T, norm(X %*% v, "2"))
}
plot(lambda.seq, S, xlab = "lambda", ylab = "非ゼロベクトルの個数")
plot(lambda.seq, T, xlab = "lambda", ylab = "分散の和")

95

alphaが不完全なようです。

n <- 100
p <- 10
lambda <- 0.001
mu <- 0.1
x <- matrix(rnorm(n * p), ncol = p)
for (j in 1:p)
  x[, j] <- x[, j] - mean(x[, j])
for (j in 1:p)
  x[, j] <- x[, j] / sqrt(sum(x[, j] ^ 2))
r <- rep(0, n)
v <- rnorm(p)
for (h in 1:1100) {
  z <- x %*% v
  theta <- t(x) %*% z / norm(t(x) %*% z, "2")
  alpha <- sum(theta ^ 2) +
  for (k in 1:p) {
    for (i in 1:n)
      r[i] <- sum(theta * x[i, ]) - sum(theta ^ 2) * sum(x[i, -k] * v[-k])
    S <- ## 空欄(1) ##
    T <- ## 空欄(2) ##
    v[k] <- soft.th(lambda, S) / T
  }
}
v
t

97(a)

k.means <- function(X, K, weights = w) {
  n <- nrow(X)
  p <- ncol(X)
  y <- sample(1:K, n, replace = TRUE)
  center <- array(dim = c(K, p))
  for (h in 1:10) {
    for (k in 1:K) {
      if (sum(y[] == k) == 0) {
        center[k, ] <- Inf
      } else {
        for (j in 1:p)
          center[k, j] <- ## 空欄(1) ##
      }
    }
    for (i in 1:n) {
      S.min <- Inf
      for (k in 1:K) {
        if (center[k, 1] == Inf)
          break
        S <- sum((X[i, ] - center[k, ]) ^ 2 * w)
        if (S < S.min) {
          S.min <- S
          ## 空欄(2) ##
        }
      }
    }
  }
  return(y)
}

## データの生成
K <- 10
p <- 2
n <- 1000
X <- matrix(rnorm(p * n), nrow = n, ncol = p)
w <- c(1, 1)
y <- k.means(X, K, w)

## 結果の出力
plot(-3:3, -3:3, xlab = "x", ylab = "y", type = "n")
points(X[, 1], X[, 2], col = y + 1)

97(b)

w.a <- function(a, s) {
  if (sum(a) < s)
    return(a)
  p <- length(a)
  lambda <- max(a) / 2
  delta <- lambda
  for (h in 1:10) {
    for (j in 1:p)
      w[j] <- soft.th(lambda, ## 空欄(1) ##)
    ww <- sqrt(sum(w ^ 2))
    if (ww == 0) {
      w <- 0
    } else {
      w <- w / ww
    }
    if (sum(w) > s) {
      lambda <- lambda + delta
    } else {
      lambda <- ## 空欄(2) ##
    }
    delta <- delta / 2
  }
  return(w)
}

98

sparse.k.means <- function(X, K, s) {
  p <- ncol(X)
  w <- rep(1, p)
  for (h in 1:10) {
    y <- k.means(## 空欄(1) ##)
    a <- comp.a(## 空欄(2) ##)
    w <- w.a(## 空欄(3) ##)
  }
  return(list(w = w, y = y))
}

comp.a <- function(X, y) {
  n <- nrow(X)
  p <- ncol(X)
  a <- array(dim = p)
  for (j in 1:p) {
    a[j] <- 0
    for (i in 1:n) {
      for (h in 1:n)
        a[j] <- a[j] + (X[i, j] - X[h, j]) ^ 2 / n
    }
    for (k in 1:K) {
      S <- 0
      index <- which(y == k)
      if (length(index) == 0)
        break
      for (i in index) {
        for (h in index)
          S <- S + (X[i, j] - X[h, j]) ^ 2
      }
      a[j] <- a[j] - S / length(index)
    }
  }
  return(a)
}

## 実行
p <- 10
n <- 100
X <- matrix(rnorm(p * n), nrow = n, ncol = p)
sparse.k.means(X, 5, 1.5)

99

ww <- function(x, mu = 1, dd = 0) {
  n <- nrow(x)
  w <- array(dim = c(n, n))
  for (i in 1:n) {
    for (j in 1:n)
      w[i, j] <- exp(-mu * sum((x[i, ] - x[j, ]) ^ 2))
  }
  if (dd > 0) {
    for (i in 1:n) {
      dis <- NULL
      for (j in 1:n)
        dis <- c(dis, sqrt(sum((x[i, ] - x[j, ]) ^ 2)))
      index <- which(dis > dd)
      w[i, index] <- 0
    }
  }
  return(w)
}

prox <- function(x, tau) {
  if (sum(x ^ 2) == 0) {
    return(x)
  } else {
    return(max(0, 1 - tau / sqrt(sum(x ^ 2))) * x)
  }
}

update.u <- function(v, lambda) {
  u <- array(dim = c(n, d))
  z <- 0
  for (i in 1:n)
    z <- z + x[i, ]
  y <- x
  for (i in 1:n) {
    if (i < n) {
      for (j in (i + 1):n)
        y[i, ] <- y[i, ] + lambda[i, j, ] + nu * v[i, j, ]
    }
    if (1 < i) {
      for (j in 1:(i - 1))
        y[i, ] <- y[i, ] - lambda[j, i, ] - nu * v[j, i, ]
    }
    u[i, ] <- (y[i, ] + nu * z) / (n * nu + 1)
  }
  return(u)
}

update.v <- function(u, lambda) {
  v <- array(dim = c(n, n, d))
  for (i in 1:(n - 1)) {
    for (j in (i + 1):n)
      v[i, j, ] <- prox(u[i, ] - u[j, ] - lambda[i, j, ] / nu, gamma * w[i, j] / nu)
  }
  return(v)
}

update.lambda <- function(u, v, lambda) {
  for (i in 1:(n - 1)) {
    for (j in (i + 1):n)
      lambda[i, j, ] <- lambda[i, j, ] + nu * (v[i, j, ] - u[i, ] + u[j, ])
  }
  return(lambda)
}

## u, v, lambda の更新のサイクルを max_iter だけ繰り返す
convex.cluster <- function() {
  v <- array(rnorm(n * n * d), dim = c(n, n, d))
  lambda <- array(rnorm(n * n * d), dim = c(n, n, d))
  for (iter in 1:max_iter) {
    u <- ## 空欄(1) ##
    v <- ## 空欄(2) ##
    lambda <- ## 空欄(3) ##
  }
  return(list(u = u, v = v))
}

## データ生成
n <- 50
d <- 2
x <- matrix(rnorm(n * d), n, d)

## 凸クラスタリングの実行
w <- ww(x, 1, dd = 1.5)
gamma <- 50
nu <- 1
max_iter <- 100
v <- convex.cluster()$v

## 隣接行列の計算
a <- array(0, dim = c(n, n))
for (i in 1:(n - 1)) {
  for (j in (i + 1):n)
    if (sqrt(sum(v[i, j, ] ^ 2)) < 1 / 10 ^ 4) {
      a[i, j] <- 1
      a[j, i] <- 1
    }
  }
}

## 作図
k <- 0
y <- rep(0, n)
for (i in 1:n) {
  if (y[i] == 0) {
    k <- k + 1
    y[i] <- k
    if (i < n) {
      for (j in (i + 1):n) {
        if (a[i, j] == 1)
          y[j] <- k
      }
    }
  }
}
plot(0, xlim = c(-3, 3), ylim = c(-3, 3), type = "n", main = "gamma = 50")
points(x[, 1], x[, 2], col = y + 1)

100

s.update.u <- function(v, lambda) {
  u <- array(dim = c(n, d))
  y <- x
  for (i in 1:n) {
    if (i < n) {
      for (j in (i + 1):n)
        y[i, ] <- y[i, ] + lambda[i, j, ] + nu * v[i, j, ]
    }
    if (1 < i) {
      for (j in 1:(i - 1))
        y[i, ] <- y[i, ] - lambda[j, i, ] - nu * v[j, i, ]
    }
  }
  for (j in 1:d)
    u[, j] <- gr(G, G.inv %*% y[, j], gamma.2 * r[j])
  for (j in 1:d)
    u[, j] <- u[, j] - mean(u[, j])
  return(u)
}

s.convex.cluster <- function() {
  ## gamma.2, r[1], ..., r[p] を設定しておく
  G <- sqrt(1 + n * nu) * diag(n) - (sqrt(1 + n * nu) - 1) / n %*% matrix(1, n, n)
  G.inv <- (1 + n * nu) ^ (-0.5) %*% (diag(n) + (sqrt(1 + n * nu) - 1) / n *
    matrix(1, n, n))
  v <- array(rnorm(n * n * d), dim = c(n, n, d))
  lambda <- array(rnorm(n * n * d), dim = c(n, n, d))
  for (iter in 1:max_iter) {
    u <- s.update.u(v, lambda)
    v <- update.v(u, lambda)
    lambda <- update.lambda(u, v, lambda)
  }
  return(list(u = u, v = v))
}