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 ```