Skip to content

Commit 3d8b248

Browse files
exporting function to construct polyhedral constraints of LASSO
1 parent bbf7e19 commit 3d8b248

File tree

3 files changed

+111
-36
lines changed

3 files changed

+111
-36
lines changed

selectiveInference/NAMESPACE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export(lar,fs,
1414
TG.pvalue,
1515
TG.limits,
1616
TG.interval,
17-
debiasingMatrix
17+
debiasingMatrix,
18+
fixedLassoPoly
1819
)
1920

2021
S3method("coef", "lar")

selectiveInference/R/funs.fixed.R

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,14 @@ fixedLassoInf <- function(x, y, beta, lambda, family=c("gaussian","binomial","co
9393
"'thresh' parameter, for a more accurate convergence."))
9494

9595
# Get lasso polyhedral region, of form Gy >= u
96-
if (type == 'full' & p > n) out = fixedLasso.poly(x,y,beta,lambda,vars,inactive=TRUE)
97-
else out = fixedLasso.poly(x,y,beta,lambda,vars)
98-
G = out$G
99-
u = out$u
96+
if (type == 'full' & p > n) out = fixedLassoPoly(x,y,lambda,beta,vars,inactive=TRUE)
97+
else out = fixedLassoPoly(x,y,lambda,beta,vars)
98+
A = out$A
99+
b = out$b
100100

101101
# Check polyhedral region
102102
tol.poly = 0.01
103-
if (min(G %*% y - u) < -tol.poly * sqrt(sum(y^2)))
103+
if (max(A %*% y - b) > tol.poly * sqrt(sum(y^2)))
104104
stop(paste("Polyhedral constraints not satisfied; you must recompute beta",
105105
"more accurately. With glmnet, make sure to use exact=TRUE in coef(),",
106106
"and check whether the specified value of lambda is too small",
@@ -191,7 +191,7 @@ fixedLassoInf <- function(x, y, beta, lambda, family=c("gaussian","binomial","co
191191
sign[j] = sign(sum(vj*y))
192192
vj = sign[j] * vj
193193

194-
limits.info = TG.limits(y, -G, -u, vj, Sigma=diag(rep(sigma^2, n)))
194+
limits.info = TG.limits(y, A, b, vj, Sigma=diag(rep(sigma^2, n)))
195195
a = TG.pvalue.base(limits.info, null_value=null_value[j], bits=bits)
196196
pv[j] = a$pv
197197
vlo[j] = a$vlo * mj # Unstandardize (mult by norm of vj)
@@ -221,45 +221,39 @@ fixedLassoInf <- function(x, y, beta, lambda, family=c("gaussian","binomial","co
221221
#############################
222222

223223

224-
fixedLasso.poly=
225-
function(x, y, beta, lambda, a, inactive = FALSE) {
226-
xa = x[,a,drop=F]
227-
xac = x[,!a,drop=F]
228-
xai = pinv(crossprod(xa))
229-
xap = xai %*% t(xa)
230-
za = sign(beta[a])
224+
fixedLassoPoly =
225+
function(X, y, lambda, beta, active, inactive = FALSE) {
226+
Xa = X[,active,drop=F]
227+
Xac = X[,!active,drop=F]
228+
Xai = pinv(crossprod(Xa))
229+
Xap = Xai %*% t(Xa)
230+
231+
za = sign(beta[active])
231232
if (length(za)>1) dz = diag(za)
232233
if (length(za)==1) dz = matrix(za,1,1)
233234

234-
if (inactive) {
235-
P = diag(1,nrow(xa)) - xa %*% xap
235+
if (inactive) { # should we include the inactive constraints?
236+
R = diag(1,nrow(Xa)) - Xa %*% Xap # R is residual forming matrix of selected model
236237

237-
G = -rbind(
238-
1/lambda * t(xac) %*% P,
239-
-1/lambda * t(xac) %*% P,
240-
-dz %*% xap
238+
A = rbind(
239+
1/lambda * t(Xac) %*% R,
240+
-1/lambda * t(Xac) %*% R,
241+
-dz %*% Xap
241242
)
242243
lambda2=lambda
243-
if(length(lambda)>1) lambda2=lambda[a]
244-
u = -c(
245-
1 - t(xac) %*% t(xap) %*% za,
246-
1 + t(xac) %*% t(xap) %*% za,
247-
-lambda2 * dz %*% xai %*% za)
244+
if(length(lambda)>1) lambda2=lambda[active]
245+
b = c(
246+
1 - t(Xac) %*% t(Xap) %*% za,
247+
1 + t(Xac) %*% t(Xap) %*% za,
248+
-lambda2 * dz %*% Xai %*% za)
248249
} else {
249-
G = -rbind(
250-
# 1/lambda * t(xac) %*% P,
251-
# -1/lambda * t(xac) %*% P,
252-
-dz %*% xap
253-
)
250+
A = -dz %*% Xap
254251
lambda2=lambda
255-
if(length(lambda)>1) lambda2=lambda[a]
256-
u = -c(
257-
# 1 - t(xac) %*% t(xap) %*% za,
258-
# 1 + t(xac) %*% t(xap) %*% za,
259-
-lambda2 * dz %*% xai %*% za)
252+
if(length(lambda)>1) lambda2=lambda[active]
253+
b = -lambda2 * dz %*% Xai %*% za
260254
}
261255

262-
return(list(G=G,u=u))
256+
return(list(A=A, b=b))
263257
}
264258

265259
##############################
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
\name{fixedLassoPoly}
2+
\alias{fixedLassoPoly}
3+
4+
\title{
5+
Compute polyhedral constraints for a LASSO problem with
6+
a fixed value of lambda.
7+
}
8+
\description{
9+
Compute polyhedral representation of the selection region of Lee et al. (2016).
10+
By construction, y should satisfy A %*% y elementwise less then or equal b.
11+
}
12+
\usage{
13+
fixedLassoPoly(X, y, lambda, beta, active, inactive = FALSE)
14+
}
15+
\arguments{
16+
\item{X}{
17+
Design matrix of LASSO problem.
18+
}
19+
\item{y}{
20+
Response of LASSO problem.
21+
}
22+
\item{lambda}{
23+
Value of regularization parameter.
24+
}
25+
\item{beta}{
26+
Solution of LASSO problem with regularization parameter set to lambda.
27+
}
28+
\item{active}{
29+
Active set of the LASSO problem as a boolean vector. Should correspond
30+
to the non-zeros of beta.
31+
}
32+
\item{inactive}{
33+
Form the inactive constraints as well?
34+
}
35+
}
36+
\details{
37+
This function computes
38+
the polyhedral representation of the selection region of Lee et al. (2016).
39+
}
40+
41+
\value{
42+
\item{A}{Linear part of the affine inequalities.}
43+
\item{b}{RHS offset the affine inequalities.}
44+
}
45+
46+
\references{
47+
Jason Lee, Dennis Sun, Yuekai Sun, and Jonathan Taylor (2016).
48+
Exact post-selection inference, with application to the lasso. Annals of Statistics, 44(3), 907-927.
49+
50+
Jonathan Taylor and Robert Tibshirani (2017) Post-selection inference for math L1-penalized likelihood models.
51+
Canadian Journal of Statistics, xx, 1-21. (Volume still not posted)
52+
}
53+
\author{Ryan Tibshirani, Rob Tibshirani, Jonathan Taylor, Joshua Loftus, Stephen Reid}
54+
55+
\examples{
56+
57+
set.seed(43)
58+
n = 50
59+
p = 10
60+
sigma = 1
61+
62+
x = matrix(rnorm(n*p),n,p)
63+
x = scale(x,TRUE,TRUE)
64+
65+
beta = c(3,2,rep(0,p-2))
66+
y = x\%*\%beta + sigma*rnorm(n)
67+
68+
# first run glmnet
69+
gfit = glmnet(x,y,standardize=FALSE)
70+
71+
# extract coef for a given lambda; note the 1/n factor!
72+
# (and we don't save the intercept term)
73+
lambda = .8
74+
beta = coef(gfit, s=lambda/n, exact=TRUE)[-1]
75+
active = (beta != 0)
76+
77+
fixedLassoPoly(x, y, lambda, beta, active)
78+
79+
}
80+

0 commit comments

Comments
 (0)