我正在将一个用R编写的脚本移植到Python中。在R中我使用smooth.spline,在Python中我使用SciPy UnivariateSpline。它们产生的结果不一样(即使它们都是基于三次样条方法)。有没有一种方法,或者UnivariateSpline的替代方法,使Python样条返回与R相同的样条?
我是一个数学家,我了解样条函数的一般概念,但不了解它们在Python或R中实现的细节。
这是R和Python的代码,两者的输入数据相同。
下面是输入数据:
x = 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0
y = -1, 1, 1, -1, 1, 0, .5, .5, .4, .5, -1
这是R代码
x = seq(0,1, by = .1);
y = c(-1,1,1, -1,1,0, .5,.5,.4, .5, -1);
spline_xy = smooth.spline(x,y)
predict(spline_xy,x)
其输出:
$x
[1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
$y
[1] 0.120614583 0.170800975 0.210954680 0.238032338 0.253672155
[6] 0.253684815 0.236432643 0.200264536 0.145403302 0.074993797
[11] -0.004853825
下面是Python代码
import numpy as np
from scipy.interpolate import UnivariateSpline
x = np.linspace(0, 1, num = 11, endpoint=True)
y = np.array([-1,1,1, -1,1,0, .5,.5,.4, .5, -1])
spline_xy = UnivariateSpline(x,y)
print('x =', x)
print('ysplined =',spline_xy(x))
其输出:
x = [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
ysplined =
[-0.26433566 -0.02587413 0.18857809 0.36585082 0.49277389
0.55617716 0.54289044 0.43974359 0.23356643 -0.08881119
-0.54055944]
我希望R $y和Python ysplined的输出是一样的,但事实并非如此。
任何帮助,例如如何设置参数,或解释将不胜感激!提前感谢。
2条答案
按热度按时间vu8f3i0k1#
在我看来,这些是不同的平滑方法。
R中的
smooth.spline
是一个“平滑样条”,它是一个过度参数化的自然样条(每个数据点都有节点,内部是三次样条,线性外推),用惩罚最小二乘来选择参数。你可以阅读帮助页面了解如何计算惩罚的细节。另一方面,Python的
UnivariateSpline
出现在这里的文档中:https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.UnivariateSpline.html为回归样条,通过最小二乘法拟合,无惩罚。它似乎自适应地选择节点数。这是完全不同的算法,我不希望它们给予相同的结果。我不知道是否有一个R包使用与Python相同的自适应选择结。答案是:https://stackoverflow.com/a/55481248/2554330声称引用了Python中的自然平滑样条实现,但我不知道它是否与R的实现相匹配。
4zcjmb1e2#
可以在Python中将R函数与
rpy2
一起使用:其输出:
就像你希望的那样
如果要直接设置
lambda
:spline_xy = r_smooth_spline(x=r_x, y=r_y, lambda=42)
不起作用,因为lambda
在Python中已经有了另一种含义,但是有一个解决方案:How to use the lambda argument of smooth.spline in RPy WITHOUT Python interprating it as lambda。请注意,此代码与最新版本
rpy2
的Jupyter-notebook不完全兼容。您可以通过使用NotImplementedError中所述的!pip install -Iv rpy2==3.4.2
来修复此问题:只有在我运行代码两次之后,才为类型为“〈class 'rpy2.rinterface.SexpClosure'〉”的对象定义转换“rpy 2 py”