插值、导数和积分
本部分探讨了插值和数值微积分的相互关联的数学表达式。
插值
插值用于在已知控制点集之间构建新的数据点。预测新数据点的能力允许沿控制点定义的曲线进行采样。
下面描述的所有插值函数都返回一个插值函数,该函数可以传递给利用采样功能的其他函数。
如果直接返回,则插值函数将返回一个包含每个控制点预测的数组。这在loess
插值的情况下很有用,该插值首先平滑控制点,然后插值平滑的点。所有其他插值函数都只返回原始控制点,因为插值预测通过原始控制点的曲线。
有不同的插值算法,它们将导致沿曲线产生不同的预测。数学表达式库当前支持以下插值函数
-
lerp
:线性插值预测通过每个控制点并形成控制点之间直线的点。 -
spline
:样条插值预测通过每个控制点并形成控制点之间平滑曲线的点。 -
akima
:Akima 样条插值类似于样条插值,但对异常值稳定。 -
loess
:Loess 插值首先执行非线性局部回归以平滑原始控制点。然后使用样条插值平滑的控制点。
沿曲线采样
更好地理解插值的一种方法是可视化沿曲线采样意味着什么。下面的示例通过在特定 x 轴范围之间对曲线进行采样,对曲线的特定区域进行放大。
上面的可视化首先创建两个包含 x 和 y 轴点的数组。请注意,x 轴范围从 0 到 9。然后将 akima
、spline
和 lerp
函数应用于向量,以创建三个插值函数。
然后从 0 到 3 之间的均匀分布中绘制 500 个随机样本。这些是新的放大 x 轴点,介于 0 和 3 之间。请注意,我们正在对曲线的特定区域进行采样。
然后使用 predict
函数预测所有三个插值函数的采样 x 轴的 y 轴点。最后,将所有三个预测向量与采样 x 轴点一起绘制。
红线是 lerp
插值,蓝线是 akima
,紫线是 spline
插值。您可以看到它们在控制点之间产生不同的曲线。
平滑插值
loess
函数是一个平滑插值器,这意味着它不会派生出通过原始控制点的函数。相反,loess
函数返回一个平滑原始控制点的函数。
一种称为局部回归的技术用于计算平滑曲线。局部回归邻域的大小可以调整,以控制新曲线与原始控制点的接近程度。
loess
函数传递 x 和 y 轴,并为数据拟合平滑曲线。如果只提供一个数组,则将其视为 y 轴,并为 x 轴生成一个序列。
下面的示例显示了 loess
函数用于对月度时间序列进行建模。在示例中,timeseries
函数用于生成股票代码 AMZN 的平均收盘价的月度时间序列。然后将时间序列中的 date_dt
和 avg(close_d)
字段向量化并存储在变量 x
和 y
中。然后将 loess
函数应用于包含平均收盘价的 y 向量。bandwidth
命名参数指定用于计算局部回归的数据集的百分比。loess
函数返回平滑数据点的拟合模型。
然后使用 zplot
函数绘制 x
、y
和 y1
变量。
导数
函数的导数测量 y
值相对于 x
值变化率的变化率。
derivative
函数可以计算上面描述的任何插值函数的导数。每个插值函数将产生不同的导数,以匹配函数的特征。
一阶导数(速度)
一个简单的示例展示了如何使用 derivative
函数来计算变化率或速度。
在示例中,创建了两个向量,一个表示小时数,另一个表示行驶的英里数。然后使用 lerp
函数创建 hours
和 miles
向量的线性插值。然后将 derivative
函数应用于线性插值。然后使用 zplot
在 x 轴上绘制hours
,在 y 轴上绘制 miles
,并在每个 x 轴点绘制 derivative
作为 mph
。
请注意,miles_traveled 线的斜率为 10,直到第 5 小时变为 50。mph 线是导数,它可视化miles_traveled 线的速度。
还要注意,导数是沿着直线计算的,显示了从一点到下一点的立即变化。这是因为线性插值 (lerp
) 用作插值函数。如果使用了 spline
或 akima
函数,它将产生具有圆形曲线的导数。
积分
积分是曲线下方体积的度量。integral
函数计算曲线的累积积分或插值曲线的特定范围的积分。与 derivative
函数一样,integral
函数在插值函数上运行。
单积分
如果 integral
函数传递了 start 和 end 范围,它将计算该特定范围内的曲线下方体积。
在以下示例中,integral
函数计算整个曲线范围(0 到 10)的积分。请注意,integral
函数传递插值曲线和开始和结束范围,并返回该范围的积分。
let(x=array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20),
y=array(0, 1, 2, 3, 4, 5.7, 6, 7, 7, 7,6, 7, 7, 7, 6, 5, 5, 3, 2, 1, 0),
curve=loess(x, y, bandwidth=.3),
integral=integral(curve, 0, 10))
当此表达式发送到 /stream
处理程序时,它会响应
{
"result-set": {
"docs": [
{
"integral": 45.300912584519914
},
{
"EOF": true,
"RESPONSE_TIME": 0
}
]
}
}
累积积分图
如果 integral
函数传递单个插值曲线,它将返回该曲线的累积积分向量。累积积分向量包含每个 x 轴点的累积积分计算。累积积分通过计算每个 x 轴点和 first x 轴点之间的范围的积分来计算。在上面的示例中,这意味着计算一个积分向量,如下所示
let(x=array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20),
y=array(0, 1, 2, 3, 4, 5.7, 6, 7, 7, 7,6, 7, 7, 7, 6, 5, 5, 3, 2, 1, 0),
curve=loess(x, y, bandwidth=.3),
integrals=array(0, integral(curve, 0, 1), integral(curve, 0, 2), integral(curve, 0, 3), ...)
累积积分图可视化每个 x 轴点下方曲线的累积体积。
以下示例显示了由 timeseries
函数生成的时间序列的累积积分图。在该示例中,为股票代码 amzn
的平均收盘价生成月度时间序列。avg(close)
列使用 spline
进行矢量化和插值。
然后使用 zplot
函数绘制时间序列的累积积分。
上图可视化了曲线下方体积,因为 AMZN 股票价格随时间变化。由于此图是累积的,因此股票价格时间序列下方体积随时间保持不变,将具有正的 线性斜率。价格上涨的股票将具有 凹面形状,而价格下跌的股票将具有 凸面形状。
在这个特定示例中,积分图随着时间的推移变得更加 凹面,显示出股票价格的加速上涨。
双三次样条
bicubicSpline
函数可用于插值和预测数据网格内的任意值。
一个简单的例子将使这一点更加清晰
let(years=array(1998, 2000, 2002, 2004, 2006),
floors=array(1, 5, 9, 13, 17, 19),
prices = matrix(array(300000, 320000, 330000, 350000, 360000, 370000),
array(320000, 330000, 340000, 350000, 365000, 380000),
array(400000, 410000, 415000, 425000, 430000, 440000),
array(410000, 420000, 425000, 435000, 445000, 450000),
array(420000, 430000, 435000, 445000, 450000, 470000)),
bspline=bicubicSpline(years, floors, prices),
prediction=predict(bspline, 2003, 8))
在此示例中,使用三次样条插值法对房地产数据矩阵进行插值。矩阵的每一行代表特定的年份
。矩阵的每一列代表建筑物的楼层
。数字网格是每一年和楼层的公寓平均售价。例如,2002 年,9 楼的平均售价为415000
(第 3 行,第 3 列)。
然后使用bicubicSpline
函数对网格进行插值,并使用predict
函数预测 2003 年、8 楼的值。请注意,该矩阵不包括 2003 年、8 楼的数据点。bicubicSpline
函数基于矩阵中周围的数据创建该数据点
{
"result-set": {
"docs": [
{
"prediction": 418279.5009328358
},
{
"EOF": true,
"RESPONSE_TIME": 0
}
]
}
}