user1412716
user1412716

Reputation: 109

How to force polyfit with second degree to a y-intercept of 0

I've been using the numpy.polyfit function to do some forecasting. If I put in a degree of 1, it works, but I need to do a second degree polynomial fit. In some cases it works, in other cases the plot of the prediction goes down and then goes up forever. For example:

import matplotlib.pyplot as plt
from numpy import *

x=[1,2,3,4,5,6,7,8,9,10]
y=[100,85,72,66,52,48,39,33,29,32]
fit = polyfit(x, y, degree) 
fitfunction = poly1d(z4)
to_predict=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

plt.plot(to_predict,fitfunction(to_predict))
plt.show()

After I run that, this shows up (I tried putting a picture up but stackoverflow won't let me).

I want to force it to go through zero.

How would I do that?

Upvotes: 5

Views: 9053

Answers (2)

LeeRuns
LeeRuns

Reputation: 514

if anyone has to do this under a deadline, a quick solution is to just add a bunch of extra points at 0 to skew the weighting off. i did this:

for i in range(0,100):
    x_vent.insert(i,0)
    y_vent.insert(i,0)         

slope_vent,intercept_vent=np.polyfit(x_vent,y_vent,1)

Upvotes: 2

kennytm
kennytm

Reputation: 523484

If you don't need the fit's error be computed using the original least square formula (i.e. minimizing ∑ |yi - (axi2 + bxi)|2), you could try to perform a linear fit of y/x instead, because (ax2 + bx)/x = ax + b.

If you must use the same error metric, construct the coefficient matrices directly and use numpy.linalg.lstsq:

coeff = numpy.transpose([x*x, x])
((a, b), _, _, _) = numpy.linalg.lstsq(coeff, y)
polynomial = numpy.poly1d([a, b, 0])

(Note that your provided data sequence does not look like a parabola having a y-intercept of 0.)

Upvotes: 6

Related Questions