Home > Blockchain >  How do I make prediction on numpy linear model using new Polynomials api?
How do I make prediction on numpy linear model using new Polynomials api?

Time:12-18

I am working on the new Polynomials api and want to make a prediction on the data. I know how to do this using poly1d but have not been able to accomplish this using numpy,Polynomials. The code I am working on is:-

#create family column
family = list(range(1,41))

#salary in '0000
import random
X = []
for i in range(40):
  i  = random.randint(10,100)
  X.append(i)

#create home ownership
y = []
for i in range(40):
  if X[i] > 30:
    own = 1
  else:
    own = 0
  y.append(own)

#create dataframe
import pandas as pd
df = pd.DataFrame(
    {'family': family,
     'y': y,
     'X': X
    })
print(df)

#linear model using legacy code
# Fit the trend line.
model = np.polyfit(X[:39], y[:39], 1)

predict = np.poly1d(model)
print(predict(X[39 :]))

#linear model using numpy.polynomial (new api)
from numpy.polynomial import Polynomial
import numpy as np
import matplotlib.pyplot as plt

X = pd.Series(X)
y = pd.Series(y)

# Fit the trend line.
model = Polynomial.fit(X[:39].values, y[:39].values, 1)

predict = Polynomial(model)
print(predict(X[39 :]))

I have included the legacy code in this piece of code, which I know works. Please can someone advise me what code I should insert to make a prediction using the new Polynomial api?

I have spent a considerable amount of time searching the google and stackoverflow but have been unable to find the answer.

Thanks in advance for any advice someone can give me to tell me where I am going wrong.

CodePudding user response:

For predicting try using Lagrange interpolation in this example enter (x, y) points and it will return polynom that goes through all points

def lagrange_interpolation(x, fX):
'''
Finds the Lagrange polynomial for given points

        Parameters:
                x(np.array, 1d): Points on x axis
                fX(np.array, 1d): Points on y axis

        Returns:
                p(np.array, 1d): Lagrange polynomial coefficients such that 
                                 L = p[0]*x**(N-1)   p[1]*x**(N-2)   ...   p[N-2]*x   p[N-1]
'''
order = x.size

p = 0

for itFX in range(order):
    lNumer = 1
    lDenom = 1

    for itX in range(itFX):
        lNumer = np.convolve(lNumer, np.array([1, -x[itX]]))
        lDenom = lDenom * (x[itFX] - x[itX])
    
    for itX in range(itFX 1, order):
        lNumer = np.convolve(lNumer, np.array([1, -x[itX]]))
        lDenom = lDenom*(x[itFX] - x[itX])

    p = p   lNumer/lDenom*fX[itFX]

return p

Or you can approximate using least squares regression for multiple 2d points and the precision you decide based on order (int) higher-order more precise the polynom in return will be.

def least_squares_regression(x, fX, order):
'''
Performs least-squares regression with polynomial of given order

        Parameters:
                x(np.array, 1d): Points on x axis
                fX(np.array, 1d): Points on y axis
                order(int): Polynomial order

        Returns:
                p(np.array, 1d): Polynomial coefficients of the least-squares solution such that 
                                 R = p[0]*x**(N-1)   p[1]*x**(N-2)   ...   p[N-2]*x   p[N-1]
'''
n = x.size
m = min(order 1, n)
A = np.zeros((n, m))

for it in range(m):
    A[:, it] = x**(it)

a = np.linalg.solve(np.matmul(A.T, A), np.matmul(A.T, fX))

p = a[::-1]
return p

CodePudding user response:

To make predictions using the Polynomial API in NumPy, you will need to use the Polynomial.polyval function rather than the Polynomial constructor.

Here is the modified code that should work using the Polynomial API:

#create family column
family = list(range(1,41))

#salary in '0000
import random
X = []
for i in range(40):
  i  = random.randint(10,100)
  X.append(i)

#create home ownership
y = []
for i in range(40):
  if X[i] > 30:
    own = 1
  else:
    own = 0
  y.append(own)

#create dataframe
import pandas as pd
df = pd.DataFrame(
    {'family': family,
     'y': y,
     'X': X
    })
print(df)

#linear model using legacy code
# Fit the trend line.
model = np.polyfit(X[:39], y[:39], 1)

predict = np.poly1d(model)
print(predict(X[39 :]))

#linear model using numpy.polynomial (new api)
from numpy.polynomial import Polynomial
import numpy as np
import matplotlib.pyplot as plt

X = pd.Series(X)
y = pd.Series(y)

# Fit the trend line.
coefficients, residuals, rank, singular_values, rcond = Polynomial.fit(X[:39].values, y[:39].values, 1, full=True)

# Make predictions
predictions = Polynomial.polyval(X[39:].values, coefficients)
print(predictions)

This code should fit a linear model to the data using the Polynomial API, and then make predictions for the remaining data using the Polynomial.polyval function.

I hope this helps!

  • Related