I was carrying out LDA (linear Discriminant Analysis) and noticed that the Scaling matrix produced by R is not normalized. Here is an example:
(res <- MASS::lda(Species~., iris))
Call:
lda(Species ~ ., data = iris)
Prior probabilities of groups:
setosa versicolor virginica
0.3333333 0.3333333 0.3333333
Group means:
Sepal.Length Sepal.Width Petal.Length Petal.Width
setosa 5.006 3.428 1.462 0.246
versicolor 5.936 2.770 4.260 1.326
virginica 6.588 2.974 5.552 2.026
Coefficients of linear discriminants:
LD1 LD2
Sepal.Length 0.8293776 0.02410215
Sepal.Width 1.5344731 2.16452123
Petal.Length -2.2012117 -0.93192121
Petal.Width -2.8104603 2.83918785
Proportion of trace:
LD1 LD2
0.9912 0.0088
Normalizing the scaling matrix:
scale(res$scaling, F, sqrt(colSums(res$scaling^2)))
LD1 LD2
Sepal.Length 0.2087418 0.006531964
Sepal.Width 0.3862037 0.586610553
Petal.Length -0.5540117 -0.252561540
Petal.Width -0.7073504 0.769453092
attr(,"scaled:scale")
LD1 LD2
3.973222 3.689878
Why is the scaling matrix not normalized?
Notice that if we try to fit lda manually:
x <- scale(as.matrix(iris[,-5]), TRUE, FALSE)
y <- iris[,5]
means <- tapply(x,list(rep(y,ncol(x)), col(x)), mean)
Swithin <- crossprod(x - means[y,])
Sbetween <- crossprod(means)
eig <- eigen(solve(Swithin, Sbetween))
eig[[2]][,eig[[1]] > 1e-8]
[,1] [,2]
[1,] 0.2087418 -0.006531964
[2,] 0.3862037 -0.586610553
[3,] -0.5540117 0.252561540
[4,] -0.7073504 -0.769453092
Notice that the results Obtained by directly computing the scaling matrix is normalized. Of course the difference between the manually computed scaling matrix and the one produced by lda is the scale factor.
But this has an impact on the posterior probabilities.
Looking at the R code, i noticed they are doing svd
twice rather than doing eigen
decomposition.
Tried analyzing the R code and after hours came up with the following:
a <- svd((x - means[y, ])/sqrt(nrow(x) - nrow(means)))
S1 <- a$v %*% diag(1/a$d)
S1 %*% svd(means %*% S1)$v
[,1] [,2] [,3]
[1,] 0.8293776 0.02410215 -3.176869
[2,] 1.5344731 2.16452123 1.965956
[3,] -2.2012117 -0.93192121 2.076870
[4,] -2.8104603 2.83918785 -1.447218
Question: This is exactly like the unnormalized Scaling. But what is the intuition behind it?
Main QUESTION: in LDA Why is the scaling matrix not normalized? and How can I obtain this unnormalized scaling matrix using eigen decomposition? (Note that I am more interested with eigen decomposition since the eigenvectors are the solutions to the lda problem - But i do not mind having the SVD approach)
The lda
objective:
$$\max_{w} J(w) = \max_{w} \frac{w'S_{between}w}{w'S_{within}w}$$
EDIT:
I have found out that the formula used in R is the same used in python. Am I missing something regarding lda
?
Python too does give the unnormalized vectors.
if interested in the python code check here