R: locpoly返回NaN值错误

7
运行以下代码会得到一个 NaN 的结果:
library(KernSmooth) 
x <- c(5.84155992364115, 1.55292112974119, 0.0349665318792623, 3.93053647398094,
       3.42790577684633, 2.9715553006801, 0.837108410045353, 2.872476865277, 
       3.89232548092257, 0.206399650539628) 
y <- c(0.141415317472329, 1.34799648955049, 0.0297566221758204, 
       -0.966736679061812, 0.246306732122746, 0.557982376254723, 
       0.740542828791083, 0.162336127802977, -0.428804158514744, 
       0.691280978689863) 

locpoly(x, y, bandwidth = 0.4821232, gridsize = 12, degree = 1)[['y']]

我理解

[1]  0.3030137  0.6456624  0.9530586  1.1121106  0.8120947  0.4441603
[7]  0.1425592 -0.3600028 -0.7840411 -1.0517612 -1.2690134        NaN

在另一台电脑上,我得到了同样的结果,只不过我得到的是-0.7270521而不是NaN。我猜你们大多数也会得到这个结果。所以问题是如何修复我的系统?这与我的LAPACK或LIBBLAS有关吗?
请注意,上述两台计算机都使用Ubuntu。给出NaN的那台计算机使用的是Ubuntu 13.10,而给出数字的那台计算机则是12.04。
编辑:
我新的怀疑是这是一个浮点数计算问题: 本地多项式回归只是加权线性回归,其中权重随着点距离评估点的距离而减小,在这种情况下是5.84。应该注意到带宽很小,因此首先想到的是带宽内没有点。然而,locpoly使用高斯核,因此所有点都具有严格正的权重。我的猜测是权重太小了,舍入或浮点数计算可能会有问题。我不确定如何解决这个问题。

我也遇到了NaN的问题,运行在Linux上。 - Rich Scriven
@RScriv 感谢确认。我想我不是唯一一个遇到这个问题的人。我也在使用Linux。我已经更新了我的操作系统信息。 - Xu Wang
我在OSX R 3.03中得到了NaN。在我们都开始深入研究LAPACK之前,有人能确认哪个值是“正确”的吗? - Carl Witthoft
我也是。在OS X 10.9.2上使用R3.0.3,我也得到了NaN - hrbrmstr
5个回答

4

虽然不是回答,但我想发布一张图表。 我仍然不清楚你希望从locpoly获得什么,但这就是它。

Rgames> foo<-locpoly(x, y, bandwidth = 0.4821232, gridsize = 12, degree = 1)
Rgames> foo
$x
 [1] 0.03496653 0.56283866 1.09071078 1.61858291 2.14645504 2.67432716
 [7] 3.20219929 3.73007142 4.25794354 4.78581567 5.31368780 5.84155992

$y
 [1]  0.3030137  0.6456624  0.9530586  1.1121106  0.8120947  0.4441603
 [7]  0.1425592 -0.3600028 -0.7840411 -1.0517612 -1.2690134        NaN

我的猜测是,最右侧的那个点在使用拟合参数时发散,并且你在任何操作系统下都能得到非NaN值,这只是运气好罢了。

谢谢你的想法,卡尔。你有什么支持那个怀疑的证据吗?(我绝对不是挑战,只是好奇你是否有任何见解。)你在这里所说的“分歧”是什么意思?你让我开始考虑可能存在的问题,我的猜测是这是一个浮点数计算问题。我会在我的问题中加入我的猜测和尝试的直觉。 - Xu Wang
@XuWang 红点(locpoly输出)的趋势明显向下,远离最后一个输入值。这让我相信拟合函数要么忽略了输入数据,要么无法“弯曲”回到输入数据。 - Carl Witthoft
我理解你的直觉。感谢你的解释。 - Xu Wang

3

如果我使用的是Windows 7和R 3.0,我会得到以下结果:

 > locpoly(x, y, bandwidth = 0.4821232, gridsize = 12, degree = 1)[['y']]
 [1]  0.3030137  0.6456624  0.9530586  1.1121106  0.8120947
 [6]  0.4441603  0.1425592 -0.3600028 -0.7840411 -1.0517612
[11] -1.2690134 -2.8078788

所以你的问题不在那里。然而,如果我在Ubuntu 13.04(GNU / Linux 3.8.0-23-generic x86_64)上使用R 3.0,我会得到以下结果:

 > locpoly(x, y, bandwidth = 0.4821232, gridsize = 12, degree = 1)[['y']]

 [1]  0.3030137  0.6456624  0.9530586  1.1121106  0.8120947  0.4441603
 [7]  0.1425592 -0.3600028 -0.7840411 -1.0517612 -1.2690134        NaN

我尝试了一下,通过以下方法获得的数字与我在Windows 7中获得的非常相似:

> locpoly(round(x,3), round(y,3), bandwidth = 0.4821232, gridsize = 12, degree = 1)[['y']]

 [1]  0.3032295  0.6459197  0.9533132  1.1121400  0.8118960  0.4437407
 [7]  0.1422658 -0.3604210 -0.7848982 -1.0531299 -1.2710219 -0.7269588

所以,我希望这能解决你的第二个问题。

为了弄清楚为什么我在Windows中可以得到非NaN答案,但在Ubuntu中无法得到,我们可以查看http://cran.r-project.org/web/packages/KernSmooth/index.html并注意到:

MacOS X二进制文件:KernSmooth_2.23-10.tgz Windows二进制文件:KernSmooth_2.23-11.zip

自然地,有两个不同的版本,但是Windows二进制文件比MacOS X二进制文件多一个版本。我在Ubuntu和Windows中检查了函数的源代码,它们看起来是相同的。然而,我发现了这个在sprintf中基于Windows和Unix的系统之间存在舍入差异的报告bug,尽管那是三年前的问题。因此,我认为差异可能是KernSmooth的操作系统或版本(其他人也遇到过该问题)。


这并未回答问题。如果您使用round但指定bandwidth = 0.3821232,问题会再次出现。在这个特定的例子中,round只是有效地增加了带宽。尽管如此,感谢您的努力和提供的大部分信息,我会接受它。 - Xu Wang
感谢您选择我的答案。很抱歉它没有完全回答您的问题,但这是我能做到的最好的。您可以采取的最后一步是给维护该软件包的Brian Ripley ripley@stats.ox.ac.uk发送电子邮件。 - James Tobin

1

我使用的是 Windows 7 操作系统和 R 3.0.1 版本。

看起来这似乎是浮点数问题,但由于 max(x) 的缘故:将 x 中的第一个条目(它恰好是其最大值)从 5.84155992364115 更改为 5.841559923,你的 NaN 就变成了 Inf,而将其更改为 5.84155992,你的 NaN 就变成了 -0.7261049

此外,将选项 truncate 设置为 FALSE 会显著改变输出:

locpoly(x, y, bandwidth = 0.4821232, gridsize = 12, degree = 1, truncate=F)[['y']]
[1]  0.3030137  0.6456624  0.9530586  1.1121106  0.8120947  0.4441603  0.1425592 -0.3600028 -0.7449278 -0.3872891 -0.1235228  0.1414153

由于您没有指定range.x,所以我没有预料到这一点。

1
你需要一个一次本地多项式(需要至少2个点来拟合),而只有一个点与5.84155992364115相邻。真正的问题是,为什么它没有给出一个友好的错误提示,告诉你要增加带宽。将其调整到0.5,所有问题都会解决。

如果使用正态核,局部多项式回归会对每个观测值进行加权。关键在于这些权重非常小。但从理论上讲,这种回归是正确的。有一个很好的参考资料,请阅读http://www.amazon.com/Local-Polynomial-Modelling-Its-Applications/dp/0412983214/ref=sr_1_1/192-9646761-7959750?ie=UTF8&qid=1395898908&sr=8-1&keywords=local+polynomial+regression。 - Xu Wang
通常情况下,软件会添加一个截止点,超过这个点,核心设置为0。对于正态分布来说,4个西格玛大约是正确的。我不会读FORTRAN或C语言,所以我没有看实际函数是否应用了这样的切点,但你可以用其他例子测试一下。尝试在X上添加-14、-15、-17.5、-19.5、-20.5、-21.5,并在Y上添加1:6,你会得到一个关于BW的错误。同样,这是我在这里预期的。 - pdb

0

我想用不同的方式表达,

我不是Ubuntu的常规用户,但我知道NaN(不是数字)是由Java启动的!

首先,我会建议更新Lapack并确保所有文件都正确安装(最近的错误

如果某个文件缺失或者数字没有被正确处理,那么除以零(或由于缺少库而导致无效结果)可能会导致结果为NaN。

我认为Ubuntu在这方面没有任何问题。

请指定LAPACK的版本以更好地理解(包括Ubuntu是32位还是64位,LAPACK是32位还是64位)

希望这可以帮到您。


我确实怀疑是因为权重太小而导致了除以0的情况。 - Xu Wang
如果被零除,就不应该在其他操作系统/系统上运行。所以我不会这么说.. :) - MarmiK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接