R语言奇异矩阵判定:行列式与秩计算结果冲突咨询
相关矩阵奇异性判定冲突问题
问题背景
参考公开文献附录C的指数平滑收益率构建方法,生成了尺寸为101×101的相关矩阵,使用R中不同函数判定矩阵奇异性时得到完全矛盾的结果,无法确认矩阵属性,具体矛盾表现如下:
- 调用
pracma::Rank函数计算矩阵秩,返回结果为101,即判定矩阵满秩 - 调用
matrixcalc::is.singular.matrix函数判定,返回结果为TRUE,即判定矩阵为奇异矩阵 - 调用
base::determinant.matrix函数计算行列式,得到的行列式模值极其接近零
复现代码及输出
pracma::Rank(try.wgtd.cor) #[1] 101 matrixcalc::is.singular.matrix(try.wgtd.cor) #[1] TRUE base::determinant.matrix(try.wgtd.cor, logarithm = FALSE) #$modulus #[1] 2.368591e-55 #attr(,"logarithm") #[1] FALSE # #$sign #[1] 1 # #attr(,"class") #[1] "det"
结果冲突的核心原因
三个函数的计算逻辑、数值容差设置规则完全不同,在双精度浮点计算的误差影响下自然会出现分歧:
pracma::Rank默认基于SVD分解计算秩,默认容差设置偏宽松,只要奇异值没有跌破它预设的固定截断阈值,就会判定为对应维度的满秩。该矩阵最小奇异值仅为极小值、没有触及该函数的默认容差线,因此返回秩为101。matrixcalc::is.singular.matrix的判定逻辑非常简单:直接计算矩阵行列式的模值,只要模值低于它预设的固定容差(默认值为1e-7,完全不考虑矩阵维度、元素尺度的影响),就直接判定为奇异。该矩阵行列式值为2.37e-55,远低于这个固定阈值,因此返回奇异结果。- 行列式本身不适合作为高维矩阵奇异性的判定指标:维度超过几十的矩阵,哪怕每个元素只有机器精度级别的微小扰动,行列式值都会出现量级式坍缩,接近0不代表严格数学意义上的奇异,只能说明矩阵条件数极高,属于病态矩阵。
正确的奇异性判定方法
不要用行列式、不要用带固定容差的封装函数直接下结论,按数值线性代数的标准流程判定:
- 第一步计算矩阵的2-范数条件数,调用
base::kappa(try.wgtd.cor, exact = TRUE)即可。如果条件数超过1/.Machine$double.eps(约1e16量级),说明矩阵在双精度浮点环境下是数值奇异的,直接求逆、解线性方程组等操作会产生极大的数值误差,不能按普通满秩矩阵使用。 - 第二步通过SVD分解计算数值秩:对矩阵做SVD分解得到所有奇异值,以最大奇异值为基准,将小于
最大奇异值 * max(dim(try.wgtd.cor)) * .Machine$double.eps的奇异值判定为数值零,统计非零奇异值的数量就是矩阵的实际数值秩,该结果比封装函数的默认输出可靠得多。 - 针对这类指数平滑构建的相关矩阵,出现极小奇异值是非常普遍的情况,通常是因为指数平滑的有效样本量不足、标的收益率序列存在高度共线性导致的,实际使用时必须做正则化处理(比如添加岭惩罚、用协方差收缩估计),不能直接按理论满秩矩阵操作。
内容的提问来源于stack exchange,提问作者jlewis
相关产品推荐
相关产品推荐

