-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRRDAfit.R
95 lines (86 loc) · 2.74 KB
/
RRDAfit.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
#fitting a given RRDA model
#Input:
#Input:covariates
#Response: response vector
#sub: order of regularization (size of covariance matrix)
#modelF:if TRUE then a best model is returned
#Output:
#yHatTrain:prediction
#error:training error
#sub:best order
#canonicalMeans: canonical means matrix (in projected space)
#canonicalMat: canonical covariance matrix (in projected space)
#Pi_k: means
#canonicalTrainData: canonical data matrix
RRDAfit <- function(Input,Response,sub=NULL,modelF=FALSE){
Input=as.matrix(Input)
N=nrow(Input)
p=ncol(Input)
K=length(unique(Response))
classes=sort(unique(yTrain))
error=c()
yHatTrainMat=matrix()
yHatTrain=c()
if(is.null(sub)){modelF=TRUE}
#initiate variables
Mu_k=matrix(0,nrow = K,ncol = p)#centroid vectors
Pi_k=vector(length= K)# classes a priori
sigma=matrix(0,nrow=p,ncol=p)# within class common covariance
mu=colMeans(Mu_k)#general mean
B=matrix(0,ncol=p,nrow = p) #between class covariance B
#compute variables in features space
for (i in 1:K){
tmp=Input[Response==classes[i],]
N0=nrow(tmp)
Pi_k[i]=N0/N
Mu_k[i,]=colMeans(tmp)
for(j in 1:N0){
sigma=sigma+(tmp[j,]-Mu_k[i,])%*%t(tmp[j,]-Mu_k[i,])}
}
sigma=(1/(N-K))*sigma#within class covariance
for(i in 1:nrow(Mu_k)){
B=B+Pi_k[i]*(Mu_k[i,]-mu)%*%t(Mu_k[i,]-mu)
}#between class covariance
#Sphere data w.r.t sigma
e=eigen(sigma)#sigma=V*D*t(V)
U=e$vectors
D=diag(e$values)
W_minus_half=U%*%diag(sqrt(e$values)^(-1))
Mstar=Mu_k%*%W_minus_half
Inputstar=Input%*%W_minus_half
Bstar=t(W_minus_half)%*%B%*%W_minus_half
#extract eigen vectors of Bstar
e2=eigen(Bstar)
V=e2$vector
#Project into canonical base
InputTrainCan=Inputstar%*%V
MeanCan=Mstar%*%V
canonicalMatrix=W_minus_half%*%V
#train classifier
deltaTrain=list()
if(modelF){
yHatTrainMat=matrix(nrow = nrow(Input),ncol = p)
for(subspace in 1:p){
deltaTrain[[subspace]]=matrix(0,ncol=K,nrow=N)
for (i in 1:K){
for (m in 1:N){
deltaTrain[[subspace]][m,i]=0.5*sum((InputTrainCan[m,1:subspace]-MeanCan[i,1:subspace])^2)-log(Pi_k[i])
}
}
yHatTrainMat[,subspace]=apply(deltaTrain[[subspace]],1,which.min)
error[subspace]=mean(yHatTrainMat[,subspace] != Response)
}
sub=which.min(error)
yHatTrain=yHatTrainMat[,sub]
}
if(!modelF){
deltaTrain[[1]]=matrix(0,ncol=K,nrow=N)
for (i in 1:K){
for (m in 1:N){
deltaTrain[[1]][m,i]=0.5*sum((InputTrainCan[m,1:sub]-MeanCan[i,1:sub])^2)-log(Pi_k[i])
}
}
yHatTrain=apply(deltaTrain[[1]],1,which.min)
}
return(list(yHatTrain=yHatTrain,error=error,sub=sub,canonicalMeans=MeanCan,canonicalMat=canonicalMatrix,Pi_k=Pi_k,canonicalTrainData=InputTrainCan))
}