python - 如何将二维曲线拟合到矩阵

标签 python numpy scipy curve-fitting

我有实数值的方阵,我想将低次多项式或其他简单函数拟合到它们。这是一个玩具示例矩阵:

M = [[ 0.63,  2.58,  8.7 , 18.17, 32.97],
     [ 3.97,  4.42, 11.9 , 19.88, 34.74],
     [ 7.75, 10.68, 14.11, 24.11, 34.99],
     [15.75, 10.86, 10.72, 24.99, 42.02],
     [16.57,  7.48, 16.91, 42.33, 48.43]]

我想拟合一个函数,以便当我给它 (i,j) 时,它会计算出大约为 M[i,j] 的值。

scipy 或 numpy (或任何其他 python 库)是否有某种方法可以做到这一点?

最佳答案

内置工具RectBivariateSpline提供对 2D 网格数据的平滑近似(平滑度由参数 s 控制)。然而,您似乎想要一个适合数据的简单公式;样条曲线不是这样的。但是您可以根据基本原理构建最小二乘拟合,如下所示(其中我假设 M 是 NumPy 2D 数组):

degrees = [(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2)]   # degrees to use
row = np.arange(M.shape[0])
col = np.arange(M.shape[1])
basis = np.array([np.outer(row**deg[0], col**deg[1]).ravel() for deg in degrees])
coeffs = np.linalg.lstsq(basis.T, M.ravel(), rcond=None)[0]
fit = coeffs.dot(basis).reshape(M.shape)

说明:

  1. 列表 Degrees 指示模型中使用的单项式:这里它们是常量 row ** 0 * col ** 0 ,线性 row * *1 * col**0row**0 * col**1 以及二次方程。
  2. basis 是通过在方形网格上评估这些单项式而形成的。
  3. lstsq 通过基本元素的线性组合找到适合 M 的最小二乘法。
  4. fit 是重建,通过将基本元素与我们找到的系数相结合而获得。

在此示例中,系数为 [3.46017143, 1.26657143, -3.31471429, 0.38585714, 0.2627, 2.64942857],这意味着模型为

3.46017143 + 1.26657143*row - 3.31471429*col + 0.38585714*row**2 + 0.2627*row*col + 2.64942857*col**2

考虑到数据中的各种突然跳跃,拟合是合理的。例如。 M 最后一行的 7.48 确实很难适合任何东西,而且还有其他奇怪的地方。

  [[ 3.46017143,  2.79488571,  7.42845714, 17.36088571, 32.59217143],
   [ 5.1126    ,  4.71001429,  9.60628571, 19.80141429, 35.2954    ],
   [ 7.53674286,  7.39685714, 12.55582857, 23.01365714, 38.77034286],
   [10.7326    , 10.85541429, 16.27708571, 26.99761429, 43.017     ],
   [14.70017143, 15.08568571, 20.77005714, 31.75328571, 48.03537143]]

通过将它们添加到基础中,可以将其推广到多项式以外的函数:例如np.outer(np.sin(row), np.cos(col)).ravel() 会将 sin(row)*cos(col) 项添加到模型。

(我不调用变量 x 和 y,因为矩阵坐标的垂直水平顺序如何映射到 x-y 坐标的水平垂直顺序常常令人困惑。)

关于python - 如何将二维曲线拟合到矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51564228/

相关文章:

python - 为什么 np.shape 没有显示所有尺寸?

python - Elastic Beanstalk SciPy.* 无提示地失败

python - subprocess.Popen 无法正确管道 urllib3 响应

python - 如何获取 Pandas 中具有数值和分类值的列作为单独的列表?

python - Python3.6安装urllib

pandas - 使用时间索引在 pandas 数据帧上滚动积分

python - 如何在 python 中随机抽样 2 参数 weibull 分布

python - Scipy 在 Julia 中使用 PyCall

python - 检查 Python 模块中是否存在类型

Python LDAP 旧密码仍然有效