The Setup

The goal of this script is to help understand matrix algebra and notation in linear and generalized linear models.

Imagine there are \(n=10\) data points and you want to fit a linear regression model and predict \(\hat{y}\) from the estimated coeffients (\(\boldsymbol{\beta}\)) and covariates with the design matrix (\(\textbf{X}\)).

We will ignore the estimation of coeffients and just pretend that we know what they are.

Lets setup the coeffients as one intercept and two slopes (\(\boldsymbol{\beta}\))

 betas = matrix(c(2,1,5),nrow=3)
 betas
##      [,1]
## [1,]    2
## [2,]    1
## [3,]    5

Next, create a design matrix that has one intercept and two continuous covariates

 set.seed(34524254)
 X = matrix(cbind(rep(1,10),rnorm(10,2,1),rpois(10,10)),nrow=10)
 head(X)
##      [,1]        [,2] [,3]
## [1,]    1  2.91595970    9
## [2,]    1 -0.05838379    7
## [3,]    1  0.10943754    9
## [4,]    1  2.60919391    8
## [5,]    1  3.75040827   12
## [6,]    1  2.39877244   11

If I want to multiple the coeffients by the covariates and intercept to predict \(\hat{y}\), how do I relate \(\textbf{X}\) and (\(\boldsymbol{\beta}\))?

First, what are the dimensions of the matrices…

 dim(X)
## [1] 10  3
 dim(betas)
## [1] 3 1

Can we multiply them together and what does that even mean?

 X*betas
## Error in `X * betas`:
## ! non-conformable arrays
 betas*X
## Error in `betas * X`:
## ! non-conformable arrays

No, we can’t do that.

Rather, we need to do matrix multiplication (called a dot product (\(\cdot\))), as

Matrix multiplication

 X%*%betas
##           [,1]
##  [1,] 49.91596
##  [2,] 36.94162
##  [3,] 47.10944
##  [4,] 44.60919
##  [5,] 65.75041
##  [6,] 59.39877
##  [7,] 68.79571
##  [8,] 64.08380
##  [9,] 45.07889
## [10,] 55.24953

Notice that the dimensions of the output is the number of samples, n = 10

But what is the dot product exactly doing?

Lets take one row at a time of (\(\boldsymbol{\beta}\)). Start with the first row

 X[1,]
## [1] 1.00000 2.91596 9.00000

We want to multiply betas[1] by 1, and betas[2] by 2.91596 and betas[3] by 9

  X[1,]*betas
##          [,1]
## [1,]  2.00000
## [2,]  2.91596
## [3,] 45.00000

And then we want to sum them…

 sum(X[1,]*betas)
## [1] 49.91596

This is the same as the first element of

( X%*%betas)[1]
## [1] 49.91596

Remember what the \(\boldsymbol{\beta}\) are. They are the partial effects of a known variable or covariate. The coeffients in columns 2 and 3 are slopes of a line or magnitude of effect that all together sum (linear approximation) to relate to the data, \(y\).

Go ahead and calculate manually the matrix multiplication of row 7 of \(\textbf{X}\) and the \(\boldsymbol{\beta}\)

Is your answer the same as (X%*%betas)[7]?

Summary: So X%*%betas is multiplying all the elements of coeffients by each row of \(\textbf{X}\) and then summing it.

Matrix Transpose

Transpose is an important matrix operation. It takes a matrix and turns it on its side.

 X
##       [,1]        [,2] [,3]
##  [1,]    1  2.91595970    9
##  [2,]    1 -0.05838379    7
##  [3,]    1  0.10943754    9
##  [4,]    1  2.60919391    8
##  [5,]    1  3.75040827   12
##  [6,]    1  2.39877244   11
##  [7,]    1  1.79571183   13
##  [8,]    1  2.08380215   12
##  [9,]    1  3.07889390    8
## [10,]    1  3.24953278   10
 t(X)
##         [,1]        [,2]      [,3]     [,4]      [,5]      [,6]      [,7]
## [1,] 1.00000  1.00000000 1.0000000 1.000000  1.000000  1.000000  1.000000
## [2,] 2.91596 -0.05838379 0.1094375 2.609194  3.750408  2.398772  1.795712
## [3,] 9.00000  7.00000000 9.0000000 8.000000 12.000000 11.000000 13.000000
##           [,8]     [,9]     [,10]
## [1,]  1.000000 1.000000  1.000000
## [2,]  2.083802 3.078894  3.249533
## [3,] 12.000000 8.000000 10.000000

Note the dimension change

 dim(X)
## [1] 10  3
 dim(t(X))
## [1]  3 10

What about betas?

 dim(betas)
## [1] 3 1
 dim(t(betas))
## [1] 1 3

If you multiply two matrices together, you should know the dimensions of the output matrix before the multiplication.

X%*%t(X)
##            [,1]     [,2]      [,3]      [,4]      [,5]      [,6]      [,7]
##  [1,]  90.50282 63.82976  82.31912  80.60830 119.93604 106.99472 123.23622
##  [2,]  63.82976 50.00341  63.99361  56.84767  84.78104  77.85995  91.89516
##  [3,]  82.31912 63.99361  82.01198  73.28554 109.41044 100.26252 118.19652
##  [4,]  80.60830 56.84767  73.28554  71.80789 106.78554  95.25886 109.68536
##  [5,] 119.93604 84.78104 109.41044 106.78554 159.06556 141.99638 163.73465
##  [6,] 106.99472 77.85995 100.26252  95.25886 141.99638 127.75411 148.30750
##  [7,] 123.23622 91.89516 118.19652 109.68536 163.73465 148.30750 173.22458
##  [8,] 115.07628 84.87834 109.22805 102.43704 152.81511 137.99857 160.74191
##  [9,]  81.97793 56.82024  73.33695  73.03343 108.54711  96.38557 110.52881
## [10,] 100.47551 70.81028  91.35562  89.47866 133.18707 118.79489 136.83522
##            [,8]      [,9]     [,10]
##  [1,] 115.07628  81.97793 100.47551
##  [2,]  84.87834  56.82024  70.81028
##  [3,] 109.22805  73.33695  91.35562
##  [4,] 102.43704  73.03343  89.47866
##  [5,] 152.81511 108.54711 133.18707
##  [6,] 137.99857  96.38557 118.79489
##  [7,] 160.74191 110.52881 136.83522
##  [8,] 149.34223 103.41581 127.77138
##  [9,] 103.41581  74.47959  91.00497
## [10,] 127.77138  91.00497 111.55946

\(\textbf{X}\) by \(\textbf{X}^{t}\) is matrix multiplying a 10x3 matrix by a 3x10 matrix.

We know we can multiply them because the columns of the first matrix (3) is the same number as the rows of the second matrix (3). The matrix that is produced has the dimensions of rows of the first matrix (10) and the number of columns of the second matrix (10). Thus, the outcome is a 10x10 matrix

 dim(X)
## [1] 10  3
 dim(t(X))
## [1]  3 10
 dim(X%*%t(X))
## [1] 10 10

We can not multiple matrices that don’t align in terms of the dimensions

 X%*%X
## Error in `X %*% X`:
## ! non-conformable arguments

Why is X%*%X non-conformable?

Can we always multiply a square matrix by itself? Try it.

Identity Matrix

The Identity matrix is a special matrix, in which the diagonals are all one, and all other elements (off diagonals) are zeros.

 diag(10)
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
##  [1,]    1    0    0    0    0    0    0    0    0     0
##  [2,]    0    1    0    0    0    0    0    0    0     0
##  [3,]    0    0    1    0    0    0    0    0    0     0
##  [4,]    0    0    0    1    0    0    0    0    0     0
##  [5,]    0    0    0    0    1    0    0    0    0     0
##  [6,]    0    0    0    0    0    1    0    0    0     0
##  [7,]    0    0    0    0    0    0    1    0    0     0
##  [8,]    0    0    0    0    0    0    0    1    0     0
##  [9,]    0    0    0    0    0    0    0    0    1     0
## [10,]    0    0    0    0    0    0    0    0    0     1
 diag(3)
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1

What is the outcome of multiplying \(\boldsymbol{\beta}\) by an identity matrix

 diag(3)%*%(betas)
##      [,1]
## [1,]    2
## [2,]    1
## [3,]    5

Nothing changed!

In GLM’s an identity link is the identity matrix- basically, no transformation. In contrast to a log-transformation for the Poisson or the logit for the Binomial.

Questions

If I multiply a matrix that is 8x10 times a matrix that is 8x10, what is the dimension of the produced matrix? See if you can figure it out.

If I multiply a matrix that is 9x3 times a matrix that is 3x1000, what is the dimension of the produced matrix? See if you can figure it out.

Can we multiply a matrix by a scalar?

 scalar=3
 diag(3)*scalar
##      [,1] [,2] [,3]
## [1,]    3    0    0
## [2,]    0    3    0
## [3,]    0    0    3
# OR, how about
 X*100
##       [,1]       [,2] [,3]
##  [1,]  100 291.595970  900
##  [2,]  100  -5.838379  700
##  [3,]  100  10.943754  900
##  [4,]  100 260.919391  800
##  [5,]  100 375.040827 1200
##  [6,]  100 239.877244 1100
##  [7,]  100 179.571183 1300
##  [8,]  100 208.380215 1200
##  [9,]  100 307.889390  800
## [10,]  100 324.953278 1000

Yes, we can do that, no problem.

Can we divide, add, and substract by a scalar?

 diag(3)/scalar
##           [,1]      [,2]      [,3]
## [1,] 0.3333333 0.0000000 0.0000000
## [2,] 0.0000000 0.3333333 0.0000000
## [3,] 0.0000000 0.0000000 0.3333333
#OR
 diag(3)+1000
##      [,1] [,2] [,3]
## [1,] 1001 1000 1000
## [2,] 1000 1001 1000
## [3,] 1000 1000 1001
 diag(3)-1000
##       [,1]  [,2]  [,3]
## [1,]  -999 -1000 -1000
## [2,] -1000  -999 -1000
## [3,] -1000 -1000  -999

Yes, not a problem

Can we do these in a different order?

 3/diag(3)
##      [,1] [,2] [,3]
## [1,]    3  Inf  Inf
## [2,]  Inf    3  Inf
## [3,]  Inf  Inf    3
 1000+diag(3)
##      [,1] [,2] [,3]
## [1,] 1001 1000 1000
## [2,] 1000 1001 1000
## [3,] 1000 1000 1001
 1000-diag(3)
##      [,1] [,2] [,3]
## [1,]  999 1000 1000
## [2,] 1000  999 1000
## [3,] 1000 1000  999

Yes, but the order of operations matters, so the output is different. We also shouldn’t divide by zero!

Matrix operations

Does it matter what order of operations we do our matrix multiplication?

 A=matrix(c(10,2,1,5),nrow=2,ncol=2)
 B=matrix(c(1,5,2,10),nrow=2,ncol=2)
 
 A
##      [,1] [,2]
## [1,]   10    1
## [2,]    2    5
 B
##      [,1] [,2]
## [1,]    1    2
## [2,]    5   10
 A%*%B
##      [,1] [,2]
## [1,]   15   30
## [2,]   27   54
 B%*%A
##      [,1] [,2]
## [1,]   14   11
## [2,]   70   55

Are the output matrices the same? No!

We can’t assume \(A\cdot B\) is equal to \(B\cdot A\) when dealing with matrices, which we can assume with regular multiplication: \(3\times2 = 2\times3\)

An applied example

What if we don’t have continiuos variables, but categorical?

Imagine a categorical variable (habtat) with three levels: grassland, forest, shrub

We want to relate elk density (\(y\); our data) to habitat with these three levels. We thus need a design matrix (\(\textbf{X}\)) that has 3 columns, to translate which row of data correspond to each level.

Lets consider 12 elk densities in which 4 of each correspond to each of the habitat levels

Here is the variable

 habitat=factor(c(rep("Forest",4),rep("Grass",4),rep("Shrub",4)))
 habitat
##  [1] Forest Forest Forest Forest Grass  Grass  Grass  Grass  Shrub  Shrub 
## [11] Shrub  Shrub 
## Levels: Forest Grass Shrub

Let’s turn this into a design matrix

 X=model.matrix(~habitat)
 X
##    (Intercept) habitatGrass habitatShrub
## 1            1            0            0
## 2            1            0            0
## 3            1            0            0
## 4            1            0            0
## 5            1            1            0
## 6            1            1            0
## 7            1            1            0
## 8            1            1            0
## 9            1            0            1
## 10           1            0            1
## 11           1            0            1
## 12           1            0            1
## attr(,"assign")
## [1] 0 1 1
## attr(,"contrasts")
## attr(,"contrasts")$habitat
## [1] "contr.treatment"

This transformation is a really really important part of understanding all linear models.

Notice that the first column is the intercept, the second and third columns are called partial intercepts or dummy codes to indicate the different levels.

For each row, there is a unique combination of 1’s and 0’s that indicate which is forest, grassland, and shrub. The first row is 1 0 0, and we know looking at ‘habitat’ that the first element is ‘forest’. The 5th row is 1 1 0, which from ‘habitat’, we know is grassland. Lastly, row 9 is 1 0 1, which we can see is Shrub.

How do we interpret the intercept?

The intercept alone ( 1 0 0 ), indicates Forest because no matter what the other coefficient values are we will always only be adding 1beta1 + 0beta2 + 0beta3, which is equal to just 1beta1. Thus, the intercept and beta1 indicate the density of elk in forest.

What does the 2nd column indicate? The beta2 corresponds to the difference in elk density between forest and grassland, so if grassland has less elk than forests beta2 will be negative, and if grassland has more elk than forests it will be positive. If there is no difference, we would expect beta2 to be zero.

The same is true for column three. beta3 is the difference from the intercept (forest) because anytime we multiply the betas by the rows of X, we only ever add the intercept and one of the other habitat types.

What if you didn’t care that much about forest, but wanted to know the effect difference between grassland and shrub. Then, just use a different design matrix

Now, lets we reassign which is the “reference” category

 habitat2=relevel(habitat, ref="Shrub")
 X2=model.matrix(~habitat2)
 X2
##    (Intercept) habitat2Forest habitat2Grass
## 1            1              1             0
## 2            1              1             0
## 3            1              1             0
## 4            1              1             0
## 5            1              0             1
## 6            1              0             1
## 7            1              0             1
## 8            1              0             1
## 9            1              0             0
## 10           1              0             0
## 11           1              0             0
## 12           1              0             0
## attr(,"assign")
## [1] 0 1 1
## attr(,"contrasts")
## attr(,"contrasts")$habitat2
## [1] "contr.treatment"

Notice how the design matrix has changed. Now, we have the 1 0 0 be the last part of the data, thus the intercept corresponds to “Shrub”,

Let use a set of betas and get the prediction of y (elk density) using the new design matrix

 betas2=c(0.5,1,2)
 X2%*%betas2
##    [,1]
## 1   1.5
## 2   1.5
## 3   1.5
## 4   1.5
## 5   2.5
## 6   2.5
## 7   2.5
## 8   2.5
## 9   0.5
## 10  0.5
## 11  0.5
## 12  0.5

By changing the design matrix ( (\(\textbf{X}\))) you can manipulate what betas are estimate and what they mean, but not necessarily the predictions of y-hat. Below is an example.

Design matrix and predictions

#This is our data…

 y=c(3, 3, 3, 3, 1.5, 1.5, 1.5, 1.5, 1,  1,  1,  1)

Let’s relate our data to two different betas and sets of design matrices

 y.hat.1=t(X%*%c(3,-1.5,-2))
 y.hat.2=t(X2%*%c(1,2,0.5))

 y==y.hat.1
##         1    2    3    4    5    6    7    8    9   10   11   12
## [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 y==y.hat.2
##         1    2    3    4    5    6    7    8    9   10   11   12
## [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 y.hat.1==y.hat.2
##         1    2    3    4    5    6    7    8    9   10   11   12
## [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Is it an issue that our betas are not unique solutions, but can change depending on our design matrix?

No, not at all. We just need to be certain that we understand the design matrix so that we can understand the meaning of out betas. But, irregardless of their meaning, we still predict the same y-hat’s.

When using a design matrix (\(\textbf{X}\)) what is the definition of the intercept (beta1)? This indicates the elk desnity in Forests

When using design matrix (\(\textbf{X2}\)) what is the definition of the intercept (beta1)? This indicates the elk desnity in Shrubs

When using design matrix (\(\textbf{X}\)) what is the definition of slope 1 (beta2)? It is the difference in elk density between forests and …..

When using design matrix (\(\textbf{X2}\)) what is the definition of slope 1 (beta2)? It is the difference in elk density between shrubs and …..

When using design matrix (\(\textbf{X}\)) what is the definition of slope 2 (beta3)?

When using design matrix (\(\textbf{X2}\)) what is the definition of slope 2 (beta3)?

lm and glm

How does this all relate to linear modeling and generalized linear modeling?

Does using variable habitat or habitat2 change the inference on the coefficients? Does the variable habitat or habitat2 change the predictions from the model?

Lets fit a linear regression model with the variable habitat

 fit1=lm(y~habitat)
 fit1
## 
## Call:
## lm(formula = y ~ habitat)
## 
## Coefficients:
##  (Intercept)  habitatGrass  habitatShrub  
##          3.0          -1.5          -2.0
 fit1$model
##      y habitat
## 1  3.0  Forest
## 2  3.0  Forest
## 3  3.0  Forest
## 4  3.0  Forest
## 5  1.5   Grass
## 6  1.5   Grass
## 7  1.5   Grass
## 8  1.5   Grass
## 9  1.0   Shrub
## 10 1.0   Shrub
## 11 1.0   Shrub
## 12 1.0   Shrub

Do the predictions match y?

 predict(fit1)
##   1   2   3   4   5   6   7   8   9  10  11  12 
## 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0
 y
##  [1] 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0

#Now use habitat2 instead of habitat. Did the coefficients change? What about the predictions?

 fit2=lm(y~habitat2)
 fit2
## 
## Call:
## lm(formula = y ~ habitat2)
## 
## Coefficients:
##    (Intercept)  habitat2Forest   habitat2Grass  
##            1.0             2.0             0.5
 predict(fit2)
##   1   2   3   4   5   6   7   8   9  10  11  12 
## 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0
 y
##  [1] 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0

Instead of doing y~habitat, lets specify the design matrix we want to use, X1 and X2.

If we fit the y data with the design matrix, do they match with above? Meaning do we get the same results by using habitat or by using X? #Do we also get the same results by using habitat2 or by using X2?

 lm(y~X+0)
## 
## Call:
## lm(formula = y ~ X + 0)
## 
## Coefficients:
##  X(Intercept)  XhabitatGrass  XhabitatShrub  
##           3.0           -1.5           -2.0
 lm(y~X2+0)
## 
## Call:
## lm(formula = y ~ X2 + 0)
## 
## Coefficients:
##    X2(Intercept)  X2habitat2Forest   X2habitat2Grass  
##              1.0               2.0               0.5

Do the same as above but for glm..

 fit3=glm(y~habitat,family=gaussian)
 fit3
## 
## Call:  glm(formula = y ~ habitat, family = gaussian)
## 
## Coefficients:
##  (Intercept)  habitatGrass  habitatShrub  
##          3.0          -1.5          -2.0  
## 
## Degrees of Freedom: 11 Total (i.e. Null);  9 Residual
## Null Deviance:       8.667 
## Residual Deviance: 1.42e-29  AIC: -784.9
 predict(fit3)
##   1   2   3   4   5   6   7   8   9  10  11  12 
## 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0
 y
##  [1] 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0

Same results as y~habitat?

 glm(y~X+0,family=gaussian)
## 
## Call:  glm(formula = y ~ X + 0, family = gaussian)
## 
## Coefficients:
##  X(Intercept)  XhabitatGrass  XhabitatShrub  
##           3.0           -1.5           -2.0  
## 
## Degrees of Freedom: 12 Total (i.e. Null);  9 Residual
## Null Deviance:       49 
## Residual Deviance: 1.42e-29  AIC: -784.9
 fit4=glm(y~habitat2,family=gaussian)
 fit4
## 
## Call:  glm(formula = y ~ habitat2, family = gaussian)
## 
## Coefficients:
##    (Intercept)  habitat2Forest   habitat2Grass  
##            1.0             2.0             0.5  
## 
## Degrees of Freedom: 11 Total (i.e. Null);  9 Residual
## Null Deviance:       8.667 
## Residual Deviance: 8.677e-30     AIC: -790.8
 predict(fit4)
##   1   2   3   4   5   6   7   8   9  10  11  12 
## 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0
 y
##  [1] 3.0 3.0 3.0 3.0 1.5 1.5 1.5 1.5 1.0 1.0 1.0 1.0

Same results as y~habitat2?

 glm(y~X2+0,family=gaussian)
## 
## Call:  glm(formula = y ~ X2 + 0, family = gaussian)
## 
## Coefficients:
##    X2(Intercept)  X2habitat2Forest   X2habitat2Grass  
##              1.0               2.0               0.5  
## 
## Degrees of Freedom: 12 Total (i.e. Null);  9 Residual
## Null Deviance:       49 
## Residual Deviance: 8.677e-30     AIC: -790.8

THE END