Search code examples
matlabfor-loopmatrixlinear-regression

MATLAB: linear regression for data that is stored in matrices (for loop?)


I try to do a linear regression for data that is stored in several matrices (Matlab). For vectors, the linear regression is pretty straight forward:

%x-values
x = [1.5;2.5;5];                                        %x-vector
          
%y-values
y = [9;11.1;17];                                        %y-vector

%Regression:
X = [ones(length(x),1) x]                               %Matrix to do the backslash calculation--> how can I set that up if I have a matrix for x and not a vector?
m2 = X\y;                                               %backslash calculation --> first value: intercept, second value: slope
yCalc = X*m2;                                           %linear regression
Rsq2 = 1 - sum((y - yCalc).^2)/sum((y - mean(y)).^2);   %R² value

In my case the x- and y-data is stored in matrices:

X = [a1 b1 c1;
     a2 b2 c2;
     a3 b3 c3]

Y = [A1 B1 C1;
     A2 B2 C2;
     A3 B3 C3]

The linear regression has to be done between the first column in matrix X (x-values: a1 a2 a3) and the first column of matrix Y (respective y-values: A1 A2 A3) and then for all the other columns in the same way (2...i). I already tried a couple of different approaches (mainly for-loops). In the end, I always mess up with setting up 1...i matrices that contain ones in the first column and the x-data of column 1...i (Matrix X) in the second column to run the backslash operation which is needed to obtain the intercept and slope for the regression. IN the end, I would like to store the variables m2,yCalc and Rsq2 for every regression that I did. Can anyone help? That would be very helpful! Many thanks in advance!


Solution

  • Use a function file to organize your program. Put

    function [m2 yCalc Rsq2] = lin_reg(x, y)
      X = [ones(length(x),1) x];
      m2 = X\y;
      yCalc = X*m2;
      Rsq2 = 1 - sum((y - yCalc).^2)/sum((y - mean(y)).^2);
    end
    

    in a file lin_reg.m. Сall lin_reg from a script

    X = [1 10 100;
         2 20 200;
         3 30 300];
    
    Y = [4 40 400;
         5 50 500;
         7 70 600];
    
    [m, n] = size(X);
    m2 = zeros(2, n);
    yCalc = zeros(m, n);
    Rsq2 = zeros(1, n);
    for k=1:n
      [m2(:, k) yCalc(:, k) Rsq2(k)] = lin_reg(X(:, k), Y(:, k));
    end
    
    m2
    yCalc
    Rsq2
    

    outputs

    m2 =
    
        2.3333   23.3333  300.0000
        1.5000    1.5000    1.0000
    
    
    yCalc =
    
        3.8333   38.3333  400.0000
        5.3333   53.3333  500.0000
        6.8333   68.3333  600.0000
    
    
    Rsq2 =
    
        0.9643    0.9643    1.0000