This repository was archived by the owner on Mar 1, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.R
186 lines (167 loc) · 6.17 KB
/
main.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
library(CCAGFA)
#
# Generate some data from the model, with pre-specified
# latent components
#
Ntrain <- Ntest <- 100 # Number of samples (you can try also
# smaller and larger values)
N <- Ntrain + Ntest
D <- c(15,7) # Data dimensions
K <- 4
Z <- matrix(0,N,K) # Latent components
Z[,1] <- sin((1:N)/(N/20))
Z[,2] <- cos((1:N)/(N/20))
Z[,3] <- rnorm(N,0,1)
Z[,4] <- as.matrix(c(2*((1:Ntrain)/Ntrain-0.5),2*((1:Ntest)/Ntest-0.5)),N,1)
tau <- c(3,6) # Noise precisions
alpha <- matrix(0,2,4) # Component precisions for the two data sets
alpha[1,] <- c(1,1,1e6,1) # 1 = active (the value determines the data scale)
alpha[2,] <- c(1,1,1,1e6) # 1e6 = inactive
# Create some random projection vectors and sample data from the
# model. Note that CCAGFAtools.R has a function for sampling data
# from a full model, but as we do not yet have a model we create
# the toy data here.
Y <- vector("list",length=2)
Ytest <- vector("list",length=2)
W <- vector("list",length=2)
for(view in 1:2) {
W[[view]] <- matrix(0,D[view],K)
for(k in 1:K) {
W[[view]][,k] <- rnorm(D[view],0,1/sqrt(alpha[view,k]))
}
Y[[view]] <- Z %*% t(W[[view]]) +
matrix(rnorm(N*D[view],0,1/sqrt(tau[view])),N,D[view])
Ytest[[view]] <- Y[[view]][(Ntrain+1):N,]
Y[[view]] <- Y[[view]][1:Ntrain,]
}
Ztest <- Z[(Ntrain+1):N,]
Z <- Z[1:Ntrain,]
#
# Run CCA/BIBFA
#
K <- 8 # The number of components; should be high enough to capture
# all of the components. This can be recognized by at least a few
# of the components being shut down
opts <- getDefaultOpts()
opts$iter.crit <- 1e-6 # Need to make this more strict if
# having a large sample size
opts$lbfgs.factr <- 1e5 # A bit less strict convergence criterion,
# should be enough for our simple dataset
opts$verbose <- 1 # Looks a bit nicer
print("Training the model")
print("==================")
model <- CCAexperiment(Y,K,opts)
#
# Explore the results
#
#
# Check some model parameters
#
print("")
print("Noise variance check")
print("====================")
print(paste("True :",paste(format(1/tau,digits=2),collapse=",")))
print(paste("Estimated :",paste(format(1/model$tau,digits=2),collapse=",")))
print("")
#
# Check correlations
#
print("Correlation check")
print("=================")
output <- CCAcorr(Y,model)
print(paste("Number of correlating components:",sum(output$active)))
sortedcorr <- sort(output$r*output$active,decreasing=TRUE)
print(paste("BCCA/BIBFA estimates :",paste(format(sortedcorr,digits=2),collapse=",")))
# Regular CCA for comparison
cca <- cancor(Y[[1]],Y[[2]])
print(paste("Classical CCA :",paste(format(cca$cor,digits=2),collapse=",")))
print("")
#
# Draw the latent components
#
# Note that the model is invariant to the sign of the latent
# components, so they might not end up in the right direction.
par(mfrow=c(4,1), oma=c(0,0,2,0))
for(i in 1:4) {
plot(Z[,i],ylim=c(-2,2));
}
par(mfrow=c(1,1));
title(main="True latent components",outer=TRUE)
par(mfrow=c(ceiling(model$K/2),2), oma=c(0,0,2,0))
for(i in 1:model$K) {
plot(model$Z[,i],ylim=c(-2,2));
}
par(mfrow=c(1,1));
title(main="Estimated latent components",outer=TRUE)
trimmed <- CCAtrim(model)
par(mfrow=c(trimmed$K,1), oma=c(0,0,2,0))
for(i in 1:trimmed$K) {
plot(trimmed$Z[,i],ylim=c(-2,2));
}
par(mfrow=c(1,1));
title(main="Estimated active latent components",outer=TRUE)
#
# Try prediction from one data to another, to both directions
# as the model itself is symmetric. Compare to linear regression,
# to see how CCA gives better predictions for small sample sizes.
#
print("Prediction check (relative MSE for each output dimension)")
print("=========================================================")
for(m in 1:2) {
if(m==1) {
observed <- c(1,0)
mpred <- 2
print("Predicting from view 1 to view 2.")
} else {
observed <- c(0,1)
mpred <- 1
print("Predicting from view 2 to view 1.")
}
pred <- CCApred(observed,Ytest,model)
error <- vector()
for(d in 1:D[mpred]) {
error[d] <- mean((Ytest[[mpred]][,d]-pred$Y[[mpred]][,d])^2) / mean(Ytest[[mpred]][,d]^2)
}
print(paste("Full model :",paste(format(error,digits=2),collapse=",")))
# Show that the predictions are the same when inactive components
# are removed, so they really were inactive
trimmed <- CCAtrim(model)
pred2 <- CCApred(observed,Ytest,trimmed)
error2 <- vector()
for(d in 1:D[mpred]) {
error2[d] <- mean((Ytest[[mpred]][,d]-pred2$Y[[mpred]][,d])^2) / mean(Ytest[[mpred]][,d]^2)
}
print(paste("Trimmed model :",paste(format(error2,digits=2),collapse=",")))
# Feature-wise linear regression for comparison
error3 <- vector()
for(d in 1:D[mpred]) {
xnam <- paste(paste("X",1:D[m],sep=""),collapse="+")
fit <- lm(paste("Y[[mpred]][,d] ~ ",xnam),data=data.frame(Y[[m]]))
out <- predict.lm(fit,newdata=data.frame(Ytest[[m]]))
error3[d] <- mean((Ytest[[mpred]][,d]-out)^2) / mean(Ytest[[mpred]][,d]^2)
}
print(paste("Least squares :",paste(format(error3,digits=2),collapse=",")))
print("")
barplot(rbind(error,error2,error3),beside=TRUE,legend.text=c("BCCA/BIBFA",
"trimmed BCCA/BIBFA",
"Regression"))
title(paste("Prediction errors for the features of data set",mpred))
}
#
# Create data from the model and check that model learned from
# that data is roughly the same
#
print("")
print("Training a new model from generated data")
print("========================================")
data <- CCAsample(trimmed,Ntrain)
newmodel <- CCAexperiment(data$Y,K,Nrep=3,opts)
newtrimmed <- CCAtrim(newmodel)
print("")
print("Original model vs. model learned from data generated from the original model")
print("============================================================================")
print(paste("Components :",trimmed$K,"vs",newtrimmed$K))
print(paste("Noise variance:",paste(format(1/trimmed$tau,digits=2),collapse=","),"vs",paste(format(1/newtrimmed$tau,digits=2),collapse=",")))
# The projection vectors can be inspected by commands like:
# image(trimmed$W[[1]]); image(newtrimmed$W[[1]])
# to verify that the models are indeed the same.