You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中高基函数数下B样条平滑报错问题求助

解决无惩罚B样条平滑的正定矩阵报错问题

我来帮你拆解一下这个问题的原因和对应的解决思路:

问题根源分析

你遇到的两个问题是关联的:

  1. 警告信息:Matrix of basis function values has rank 799 < dim(fdobj$basis)[2] = 800 ignoring null space
    当你设置800个B样条基函数时,基函数矩阵出现了秩亏(存在线性相关的列)。这是因为默认的均匀节点设置下,过多的基函数会导致相邻基函数高度重叠,部分基函数可以被其他基函数线性表示,所以矩阵的实际秩比你设定的基函数数少1。

  2. 正定矩阵错误:Error in chol.default(temp) : the leading minor of order 445 is not positive definite
    在无惩罚(j=0)的平滑中,算法需要对基函数交叉乘积矩阵做Cholesky分解,而秩亏的矩阵必然不是正定矩阵,因此分解失败报错。而当你添加惩罚项时,惩罚项相当于给这个秩亏矩阵加了一个正定的“正则化项”,让整体矩阵变得正定,所以能正常运行。

解决办法

1. 优先减少基函数数量

既然200-700个基函数都能正常运行,完全没必要用800个:

  • 无惩罚的B样条平滑中,过多的基函数会导致平滑结果几乎和原始数据重合,完全失去平滑的意义,还会引入过拟合风险。
  • 从你的样本量(44467行)来看,200-500个基函数已经足够捕捉数据的趋势了。

2. 手动设置非均匀节点(如果一定要用更多基函数)

如果你因为特殊需求必须用800个基函数,可以放弃默认的均匀节点,改用基于数据分位数的自适应节点,避免基函数过度重叠:

n=44467
argvals=data_totale$temps_ref_st
library(fda)
TableGCV<-c()

i <- 800
j <- 0
# 基于数据分位数设置节点,B样条基函数数 = 节点数 + 3
breaks <- quantile(argvals, seq(0, 1, length.out = i - 3))
# 创建自适应节点的B样条基
basisobj = create.bspline.basis(c(0, max(argvals)), breaks = breaks)
fdParobj = fdPar(fdobj=basisobj, Lfdobj=2, j)
smoothlist = smooth.basis(argvals, mdata, fdParobj)

xfd_acc = smoothlist$fd
xfd_acc_coef = smoothlist$fd$coefs
gcv = smoothlist$gcv
TableGCV <- rbind(TableGCV,c(i,j,gcv))

3. 保留惩罚项(更推荐的方案)

惩罚项不仅能解决正定矩阵的问题,还能有效控制过拟合。即使你想用较多的基函数,也建议设置一个非0的惩罚系数(比如从0.001开始尝试),平衡拟合效果和平滑性。

4. 检查并处理重复的自变量值

如果你的argvals存在大量重复值,会进一步加剧基函数矩阵的秩亏问题。可以先检查并处理:

# 检查重复值数量
sum(duplicated(argvals))
# 对重复的自变量值,合并对应的因变量(比如取均值)
library(dplyr)
data_clean <- data_totale %>%
  group_by(temps_ref_st) %>%
  summarise(mdata = mean(mdata, na.rm = TRUE)) %>%
  ungroup()
argvals_clean <- data_clean$temps_ref_st
mdata_clean <- data_clean$mdata

内容的提问来源于stack exchange,提问作者Victoire Louis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:00:39