I am trying to use canonical correlation to predict a set of held out x variables from a multivariable set of X and Y data. In this particular case I am only interested in X. In the real data X is a behavioural variable and Y is a biomarker.
My approach so far involves:
- running the training CCA
- apply the CCA weights to the held out Y data (V = Y * B)
- using linear regression to estimate the unknown U value (assumes V and U are linearly related, as CCA should find)
- applying the same CCA weights backwards to find X (X = U / A)
I've pasted some generalized code below using the fisheriris dataset in matlab. It produces high correlations between predicted and real values but I'm unsure if this is correct.
load fisheriris
X = meas(:,1:2);
Y = meas(:,3:4);
%% CCA LOO
N = length(X); %sample size
for subj = 1:N
trainN = 1:N;
trainN(subj) = []; % remove left-out subject
Yheld = Y(subj,:); %held out data used to predict held out X
%training data
Xtrain = X(trainN,:); %held in data
Ytrain = Y(trainN,:);
%remove mean
XTrainCentre = mean(Xtrain);
YTrainCentre = mean(Ytrain);
Xtrain = Xtrain - XTrainCentre;
Ytrain = Ytrain - YTrainCentre;
%This computes CCA on the training data
[A,B,r,U,V,stats] = canoncorr(Xtrain,Ytrain);
%Only interested in the first Mode
Mode = 1;
% build linear regression model using U and V
y = U(:,Mode); % want to predict U
x = [ones(length(V(:,1)),1),V(:,Mode)]; % from V
beta = regress(y,x); % get regression coefficient
% Calculate held-out V using the training data weights
% see matlab help: V = (Y-repmat(mean(Y),N,1))*B
Vpred = (Yheld - YTrainCentre) * B(:,Mode);
% Calculate held-out U via linear regression equation from training set
Upred = beta(1) + (Vpred * beta(2));
% Apply weights, in the opposite direction, to get raw behaviour
% U = X * A
% X = U / A
Xpred(subj,:,Mode) = Upred ./ A(:,Mode);
end
% prediction accuracy (by correlating real and predicted values).
for beh = 1:size(X,2)
[r,p] = corr(X(:,beh),Xpred(:,beh));
disp(['For variable: ',num2str(beh),', r = ',num2str(r),', p = ',num2str(p)])
end
```