Python小白数据科学教程:SciPy精讲

您所在的位置:网站首页 折现因子计算模型有哪些方法 Python小白数据科学教程:SciPy精讲

Python小白数据科学教程:SciPy精讲

2024-07-07 08:06| 来源: 网络整理| 查看: 265

640?wx_fmt=png

作者 | 王圣元

来源 | 王的机器)

0引言

SciPy 是 Python 里处理科学计算 (scientific computing) 的包,使用它遇到问题可访问它的官网 (https://www.scipy.org/). 去找答案。 在使用 scipy 之前,需要引进它,语法如下:

import scipy

这样你就可以用 scipy 里面所有的内置方法 (build-in methods) 了,比如插值、积分和优化。

numpy.interpolatenumpy.integratenumpy.optimize

但是每次写 scipy 字数有点多,通常我们给 scipy 起个别名 sp,用以下语法,这样所有出现 scipy 的地方都可以用 sp 替代。

import scipy as sp

SciPy 是建立 NumPy 基础上的,很多关于线性代数的矩阵运算在 NumPy 都能做,因此就不重复在这里讲了。此外在〖数组计算之 NumPy (下)〗也说过,数组计算比矩阵计算更通用,

本章换一种写法,我们专门针对科学计算中三个具体问题来介绍 SciPy,它们就是

插值 (interpolation)

积分 (integration)

优化 (optimization)

对于以上每一个知识点我都会介绍一个

简单例子来明晰 SciPy 里各种函数的用法

和金融相关的实际例子

计算远期利率:在零息曲线中插值折现因子

计算期权价格:将期望写成积分并数值求解

配置资产权重:优化「风险平价」模型权重

1插值

给定一组 (xi, yi),其中 i = 1, 2, ..., n,而且 xi 是有序的,称为「标准点」。插值就是对于任何新点 xnew,计算出对应的 ynew。换句话来说,插值就是在标准点之间建立分段函数 (piecewise function),把它们连起来。这样给定任意连续 x 值,带入函数就能计算出任意连续 y 值。

在 SciPy 中有个专门的函数 scipy.interpolate 是用来插值的,首先引进它并记为 spi。 

import scipy.interpolate as spi

简单例子

用 scipy.interpolate 来插值函数 sin(x) + 0.5x。

基本概念

首先定义 x 和函数 f(x):

x = np.linspace(-2 * np.pi, 2 * np.pi, 11) f = lambda x: np.sin(x) + 0.5 * x f(x)

array([-3.14159265, -1.56221761, -1.29717034, -1.84442231,        -1.57937505, 0.         , 1.57937505, 1.84442231,        1.29717034, 1.56221761, 3.14159265])

接下来介绍 scipy.interpolate 里面两大杀器:splrep 和 splev。两个函数名称都是以 spl 开头,全称 spline (样条),可以理解这两个函数都和样条有关。不同的是,两个函数名称以 rep 和 ev 结尾,它们的意思分别是:

rep:representation 的缩写,那么 splrep 其实生成的是一个「表示样条的对象」

ev:evaluation 的缩写,那么 splev 其实用于「在样条上估值」

splrep 和 splev 像是组合拳 (one two punch)

前者将 x, y 和插值方式转换成「样条对象」tck

后者利用它在 xnew 上生成 ynew

一图胜千言:

640?wx_fmt=png

接下来仔细分析一下 tck。

tck = spi.splrep( x, f(x), k=1 ) tck

640?wx_fmt=png

tck 就是样条对象,以元组形式返回,tck 这名字看起来很奇怪,实际指的是元组 (t, c, k) 里的三元素:

t - vector of knots (节点)

c - spline cofficients (系数)

k - degree of spline (阶数)

对照上图,tck 确实一个元组,包含两个 array 和一个标量 1,其中

第一个 array 是节点,即标准点,注意到一开始 x 只有 11 个,但现在是 13 个,首尾都往外补了一个和首尾一样的 x

第二个 array 是系数,注意它就是 y 在尾部补了两个 0

标量 1 是阶数,因为在调用 splrep 时就把 k 设成 1

注:前两个 array 我只是发现这个规律,但解释不清楚为什么这样。它和 matlab 里面的 spline() 的产出不太一样,希望懂的读者可以留言区解释一下。

虽然解释不清楚前两个 array,那就把 tck 当成是个黑匣子 (black-box) 直接用了。比如可用 PPoly.from_spline 来查看每个分段函数的系数。

pp = spi.PPoly.from_spline(tck) pp.c.T

array([[ 1.25682673, -3.14159265],       [ 1.25682673, -3.14159265],       [ 0.21091791, -1.56221761],       [-0.43548928, -1.29717034],       [ 0.21091791, -1.84442231],       [ 1.25682673, -1.57937505],       [ 1.25682673, 0. ],       [ 0.21091791, 1.57937505],       [-0.43548928, 1.84442231],       [ 0.21091791, 1.29717034],       [ 1.25682673, 1.56221761],       [ 1.25682673, 3.14159265]])

tck 的系数数组里有 13 个元素,而上面数组大小是 (12, 2),12 表示 12 段,2 表示每段线性函数由 2 个系数确定。

把 x 和 tck 丢进 splev 函数,我们可以插出在 x 点对应的值 iy。

iy = spi.splev( x, tck ) iy

array([-3.14159265, -1.56221761, -1.29717034, -1.84442231,        -1.57937505, 0.         , 1.57937505, 1.84442231,        1.29717034, 1.56221761, 3.14159265])

用 Matplotlib 来可视化插值的 iy 和原函数 f(x) 发现 iy 都在 f(x) 上。Matplotlib 是之后的课题,现在读者可忽略其细节。

640?wx_fmt=png

640?wx_fmt=png

除了可视化,我们还可以用具体的数值结果来评估插值的效果:

np.allclose(f(x), iy) np.sum((f(x) - iy) ** 2) / len(x)

True0.0

第一行 allclose 的结果都是 True 证明插值和原函数值完全吻合,第二行就是均方误差 (mean square error, MSE),0.0 也说明同样结果。

上面其实做的是在「标准点 x」上插值,那得到的结果当然等于「标准点 y」了。这种插值确实意义不大,但举这个例子只想让大家

明晰 splrep 和 splev 是怎么运作的

如何可视化插出来的值和原函数的值

如何用 allclose 来衡量插值和原函数值之间的差异

一旦弄明白了这些基础,接下来就可以秒懂更实际的例子了。

正规例子

上面在「标准点 x」上插值有点作弊,现在我们在 50 个「非标准点 xd」上线性插值得到 iyd。

xd = np.linspace( 1.0, 3.0, 50 ) iyd = spi.splev( xd, tck ) print( xd, '\n\n', iyd )

640?wx_fmt=png

密密麻麻的数字啥都看不出来,可视化一下把。

640?wx_fmt=png

640?wx_fmt=png

这插得是个什么鬼?红色插值点在第二段和深青色原函数差别也太远了吧 (MSE 也显示有差异)。

np.sum((f(xd) - iyd) ** 2) / len(xd)

0.011206417290260647

问题出在哪儿呢?当「标准点 x」不密集时 (只有 11 个),分段线性函数来拟合 sin(x) + 0.5x 函数当然不会太好啦。那我们试试分段三次样条函数 (k = 3)。

tck = spi.splrep( x, f(x), k=3 )iyd = spi.splev( xd, tck )

可视化一下并计算 MSE 看看

640?wx_fmt=png

np.sum((f(xd) - iyd) ** 2) / len(xd)

1.6073247177220542e-05

视觉效果好多了!误差小多了!

金融例子

用 scipy.interpolate 来插值折现因子来计算远期利率。

在金融市场中,每个货币都有自己相对应的折现曲线,简单来说,就是在「标准日期」上一组折现因子 (discount factor) 或零息利率 (zero rate)。

640?wx_fmt=png

那么在「非标准日期」上折现因子或零息利率怎么求呢?插值!

本小节的知识点内容来之〖弄懂金融十大话题 (上)〗。

知识点

这里面说的插值是分段 (piecewise) 插值!对于线性插值,不是说一条直线拟合上表的 9 个点,这样也是不可能做到的。但是分段线性插值就可以完美解决这个问题,因为 9 个点,有 8 段,每一段首尾两个点,可以连一条直线,全部点之间连起来不就是分段线性插值吗?三种最常见的插值方法

分段常函数

分段线性函数

分段三次样条函数

首先给出数学符号。给定 N 数据点 (xi, fi), i = 1, 2, …, N,其中 x1



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3