我正在执行 LDA(线性判别分析)并注意到 R 生成的缩放矩阵未归一化。这是一个例子:
(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
标准化缩放矩阵:
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
为什么缩放矩阵没有归一化?
注意,如果我们尝试手动拟合 lda:
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
注意直接计算缩放矩阵得到的结果是归一化的。当然,手动计算的缩放矩阵与 lda 生成的缩放矩阵之间的差异是比例因子。
但这对后验概率有影响
查看 R 代码,我注意到他们正在做两次
svd
而不是进行 eigen
分解。
尝试分析 R 代码,几个小时后得出以下结论:
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
问题:这和未归一化的Scaling一模一样。但它背后的直觉是什么?
主要问题:在 LDA 中,为什么缩放矩阵未归一化?以及如何使用特征分解获得这个未归一化的缩放矩阵? (请注意,我对特征分解更感兴趣,因为特征向量是 lda 问题的解决方案——但我不介意使用 SVD 方法)
因为LDA的目标是最大化各个类之间的分离,即使没有归一化缩放也可以实现,所以缩放矩阵在LDA中没有被归一化。类间散布矩阵 (S between) 和类内散布矩阵 (S within) 特征向量在特征空间中提供最具辨别力的方向,用于创建缩放矩阵。归一化和非归一化缩放矩阵都可以实现 LDA 的目标,因为归一化特征向量不会改变判别方向。
现在让我们看看如何使用特征分解方法来获得未归一化的缩放矩阵。你的符号如下:
计算每个类别的平均值:
x <- scale(as.matrix(iris[,-5]), TRUE, FALSE)
y <- iris[,5]
means <- tapply(x,list(rep(y,ncol(x)), col(x)), mean)
计算类内散布矩阵(S_within)和类间散布矩阵(S_between):
Swithin <- crossprod(x - means[y,])
Sbetween <- crossprod(means)
计算广义特征值问题的特征值和特征向量:
eig <- eigen(solve(Swithin, Sbetween))
未归一化的缩放矩阵是特征向量的矩阵:
unnormalized_scaling <- eig$vectors[,eig$values > 1e-8]
这将为您提供使用特征分解的非归一化缩放矩阵:
[,1] [,2]
[1,] 0.2087418 0.006531964
[2,] 0.3862037 -0.586610553
[3,] -0.5540117 0.252561540
[4,] -0.7073504 -0.769453092
请记住,与从手动计算获得的归一化缩放矩阵相比,第二个判别式的符号可以反转。然而,由于判别式的方向保持不变,这对 LDA 的判别能力没有影响。
请记住,各种数值技术的使用导致了 R 中手动特征分解和 LDA 函数之间比例因子的差异。(SVD 与特征分解)。这些技术可能会产生略有不同的结果,但它们仍然实现了 LDA 的目标,即识别特征空间中最具辨别力的方向。