Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy.polyfit vs numpy.polynomial.polynomial.polyfit

Tags:

python

numpy

Why do numpy.polyfit and numpy.polynomial.polynomial.polyfit produce different plots in the test below?

import numpy as np
from numpy.polynomial.polynomial import polyfit
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 50)
y = 5 * x + 10 + (np.random.random(len(x)) - 0.5) * 5

plt.scatter(x, y,marker='.', label='Data for regression')
plt.plot(x, np.poly1d(np.polyfit(x, y, 1))(x), label='numpy.polyfit')
plt.plot(x, np.poly1d(polyfit(x, y, 1))(x), label='polynomial.polyfit')
plt.legend()
plt.show()

enter image description here

like image 955
William Miller Avatar asked Nov 23 '19 02:11

William Miller


People also ask

What is Numpy Polyfit?

Introduction to NumPy polyfit. In python, Numpy polyfit() is a method that fits the data within a polynomial function. That is, it least squares the function polynomial fit. For example, a polynomial p(X) of deg degree fits the coordinate points (X, Y).

What is Numpy Polyfit return?

The np. polyfit() method takes a few parameters and returns a vector of coefficients p that minimizes the squared error in the order deg, deg-1, … 0. It least squares the polynomial fit.

How does python Polyfit work?

polyfit() helps us by finding the least square polynomial fit. This means finding the best fitting curve to a given set of points by minimizing the sum of squares. It takes 3 different inputs from the user, namely X, Y, and the polynomial degree. Here X and Y represent the values that we want to fit on the 2 axes.

Is Polyfit a regression?

Using polyfit , you can fit second, third, etc… degree polynomials to your dataset, too. (That's not called linear regression anymore — but polynomial regression.


1 Answers

At first glance, the documentation seems to indicate they should give the same result -

numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)

Least squares polynomial fit.

Fit a polynomial p(x) = p[0] * x**deg + ... + p[deg] of degree deg to points (x, y). Returns a vector of coefficients p that minimises the squared error in the order deg, deg-1, … 0.

and

numpy.polynomial.polynomial.polyfit(x, y, deg, rcond=None, full=False, w=None)

Least-squares fit of a polynomial to data.

Return the coefficients of a polynomial of degree deg that is the least squares fit to the data values y given at points x. If y is 1-D the returned coefficients will also be 1-D. If y is 2-D multiple fits are done, one for each column of y, and the resulting coefficients are stored in the corresponding columns of a 2-D return. The fitted polynomial(s) are in the form

p(x) = c0 + c1 * x + ... + cn * xn

But the difference is in the order of coefficients returned from the two methods, at least for the use case in question.

  • numpy.polyfit returns the coefficients in descending order of degree, according to the generation equation
    p(x) = cn * xn + c(n-1) * x(n-1) + ... + c1 * x + c0
  • numpy.polynomial.polynomial.polyfit returns the coefficients in ascending order of degree, according to the generation equation
    p(x) = c0 + c1 * x + ... + c(n-1) * x(n-1) + cn * xn

though mathematically identical, those two equations are not the same in ndarray representation. This might be obfuscated by the use of different notations in the documentation. For demonstration, consider the following

import numpy as np

x = np.linspace(0, 10, 50)
y = x**2 + 5 * x + 10

print(np.polyfit(x, y, 2))
print(np.polynomial.polynomial.polyfit(x, y, 2))
[ 1.  5. 10.]
[10.  5.  1.]

Both methods get the same result, but in opposite order, the former being what np.poly1d() expects,

print(np.poly1d(np.polyfit(x, y, 2)))
print(np.poly1d(np.polynomial.polynomial.polyfit(x, y, 2)))
   2
1 x + 5 x + 10
    2
10 x + 5 x + 1

and the latter being what the np.polynomial.polynomial.Polynomial() constructor expects.,

print(np.polynomial.polynomial.Polynomial(np.polynomial.polynomial.polyfit(x, y, 2)))
print(np.polynomial.polynomial.Polynomial(np.polyfit(x, y, 2)))
poly([10.  5.  1.])  # 10 + 5 * x + 1 * x**2
poly([ 1.  5. 10.])  # 1 + 5 * x + 10 * x**2

Flipping the result from np.polynomial.polynomial.polyfit before passing it to poly1d() or using a np.polynomial.polynomial.Polynomial will produce the expected result:

Matching output

like image 139
William Miller Avatar answered Sep 30 '22 11:09

William Miller