如何使用numpy.polynomial的多维多项式? [英] How can I use multiple dimensional polynomials with numpy.polynomial?

查看:83
本文介绍了如何使用numpy.polynomial的多维多项式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用 numpy.polynomial 使术语适合一维多项式,例如 f(x)= 1 + x + x ^ 2 .如何拟合多维多项式,例如 f(x,y)= 1 + x + x ^ 2 + y + yx + yx ^ 2 + y ^ 2 + y ^ 2 x + y ^ 2 x ^ 2 ?看起来numpy根本不支持多维多项式:是这样吗?在我的实际应用程序中,我有5个输入维度,并且对Hermite多项式感兴趣.看起来 scipy.special 中的多项式也仅可用于一维输入.

I'm able to use numpy.polynomial to fit terms to 1D polynomials like f(x) = 1 + x + x^2. How can I fit multidimensional polynomials, like f(x,y) = 1 + x + x^2 + y + yx + y x^2 + y^2 + y^2 x + y^2 x^2? It looks like numpy doesn't support multidimensional polynomials at all: is that the case? In my real application, I have 5 dimensions of input and I am interested in hermite polynomials. It looks like the polynomials in scipy.special are also only available for one dimension of inputs.

# One dimension of data can be fit
x = np.random.random(100)
y = np.sin(x)
params = np.polynomial.polynomial.polyfit(x, y, 6)
np.polynomial.polynomial.polyval([0, .2, .5, 1.5], params)

array([ -5.01799432e-08,   1.98669317e-01,   4.79425535e-01,
         9.97606096e-01])

# When I try two dimensions, it fails. 
x = np.random.random((100, 2))
y = np.sin(5 * x[:,0]) + .4 * np.sin(x[:,1])
params = np.polynomial.polynomial.polyvander2d(x, y, [6, 6])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-5409f9a3e632> in <module>()
----> 1 params = np.polynomial.polynomial.polyvander2d(x, y, [6, 6])

/usr/local/lib/python2.7/site-packages/numpy/polynomial/polynomial.pyc in polyvander2d(x, y, deg)
   1201         raise ValueError("degrees must be non-negative integers")
   1202     degx, degy = ideg
-> 1203     x, y = np.array((x, y), copy=0) + 0.0
   1204 
   1205     vx = polyvander(x, degx)

ValueError: could not broadcast input array from shape (100,2) into shape (100)

推荐答案

polyfit看起来不支持拟合多元多项式,但是您可以使用 linalg.lstsq 手动完成.步骤如下:

It doesn't look like polyfit supports fitting multivariate polynomials, but you can do it by hand, with linalg.lstsq. The steps are as follows:

  1. 收集要在模型中使用的单项式 x ** i * y ** j 的度数.仔细考虑一下:您的当前模型已经有9个参数,如果要推入5个变量,那么使用当前方法,您最终将获得3 ** 5 = 243个参数,这无疑是过度拟合的道路.也许最多只能将__total_度的单项式限制为2或3 ...

  1. Gather the degrees of monomials x**i * y**j you wish to use in the model. Think carefully about it: your current model already has 9 parameters, if you are going to push to 5 variables then with the current approach you'll end up with 3**5 = 243 parameters, a sure road to overfitting. Maybe limit to the monomials of __total_ degree at most 2 or three...

将x点插入每个单项式;这给出了一个一维数组.将所有此类数组堆叠为矩阵的列.

Plug the x-points into each monomial; this gives a 1D array. Stack all such arrays as columns of a matrix.

求解一个具有上述矩阵且右侧为目标值的线性系统(我称它们为z是因为当您同时将x,y用作两个变量时,y也会造成混淆).

Solve a linear system with aforementioned matrix and with the right-hand side being the target values (I call them z because y is confusing when you also use x, y for two variables).

这里是:

import numpy as np
x = np.random.random((100, 2))
z = np.sin(5 * x[:,0]) + .4 * np.sin(x[:,1])
degrees = [(i, j) for i in range(3) for j in range(3)]  # list of monomials x**i * y**j to use
matrix = np.stack([np.prod(x**d, axis=1) for d in degrees], axis=-1)   # stack monomials like columns
coeff = np.linalg.lstsq(matrix, z)[0]    # lstsq returns some additional info we ignore
print("Coefficients", coeff)    # in the same order as the monomials listed in "degrees"
fit = np.dot(matrix, coeff)
print("Fitted values", fit)
print("Original values", y)

这篇关于如何使用numpy.polynomial的多维多项式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆