evir::gev()拟合特定数据时触发optim非有限有限差分错误
R语言evir包gev()拟合GEV分布入参报错问题
场景说明
需要对最大值得分拟合广义极值分布,计算统计显著性阈值,选用R语言evir包的gev()函数实现拟合流程,测试时出现异常:
- 直接从存储置换扫描结果的
permuted_scans对象中,提取max.statistics节点下的LOD列值传入gev()函数时,拟合过程抛出错误 - 传入手动定义的、取值一致的双精度(double)型数值向量时,代码可正常运行
初步核查确认两种场景下传入的data对象均为double类型向量,打印输出的取值无肉眼可见差异,但函数处理结果存在明显区别。
复现代码
正常运行版本
data <- c(5.401319,6.580631,6.120880,5.686255,6.640302,6.990672,5.797920,6.902248,5.694203,6.853788) print(data) typeof(data) fit <- evir::gev(data)
触发报错版本
data <- permuted_scans$max.statistics$LOD print(data) typeof(data) fit <- evir::gev(data)
报错信息
执行报错代码时抛出的错误如下:
Error in optim(theta, negloglik, hessian = TRUE, ..., tmp = data) : non-finite finite-difference value 1
排查解决方法
这个报错的本质是gev()内部调用optim()做极大似然估计时,数值梯度计算的差分结果出现了非有限值(NaN/Inf/-Inf),和向量本身的存储类型是否为double没有直接关系,按以下优先级排查:
- 排查隐藏的非有限值
不要仅靠打印输出判断取值合法性,R默认打印数值时会对极端值、缺失值做显示截断,直接执行以下命令校验向量完整性:
绝大多数同类报错都是因为提取的LOD列中混了置换计算生成的隐式无穷大、缺失值,传入优化函数后直接导致似然计算崩溃。# 统计各类非有限值数量 sum(is.na(data)) sum(is.nan(data)) sum(is.infinite(data)) # 检查向量是否存在零变异(所有值完全相同会导致似然函数失效) var(data) length(unique(data)) - 剥离向量多余属性
从结构化结果对象(比如tibble、S4类结果、带标签的统计结果对象)中提取的列,往往会附带label、col_type这类非基础向量属性,evir::gev内部没有做入参的属性剥离逻辑,带额外属性的向量传入后可能在计算时被错误解析。直接执行data <- as.numeric(data)将其转为无额外属性的基础double向量,再传入拟合函数即可排除这类干扰。 - 排查极端离群值
如果提取的LOD列存在远偏离常规取值范围的离群点,会导致GEV分布形状参数的初始估计值严重偏离合理区间,优化迭代时直接跑到参数边界外,生成非有限的似然结果。可以先执行plot(data)查看取值分布,过滤掉明显不合理的离群值后再做拟合。
内容的提问来源于stack exchange,提问作者mcme
相关产品推荐
相关产品推荐

