Pregunta sobre python, numpy, statistics, regression – Regresión polinomial multivariable con numpy

18

Tengo muchas muestras(y_i, (a_i, b_i, c_i)) dóndey se presume que varía como un polinomio ena,b,c hasta cierto punto Por ejemplo, para un conjunto dado de datos y grado 2 podría producir el modelo

y = a^2 + 2ab - 3cb + c^2 +.5ac

Esto se puede hacer usando mínimos cuadrados y es una ligera extensión de la rutina polyfit de numpy. ¿Hay alguna implementación estándar en algún lugar del ecosistema de Python?

He publicado código aquí para resolver este problemahttps://github.com/mrocklin/multipolyfit MRocklin

Tu respuesta

3   la respuesta
2

Polyfit funciona, pero hay mejores minimizadores de mínimos cuadrados por ahí. Recomendaría kmpfit, disponible en

http://www.astro.rug.nl/software/kapteyn-beta/kmpfittutorial.html

Es más robusto que Polyfit, y hay un ejemplo en su página que muestra cómo hacer un ajuste lineal simple que debería proporcionar los conceptos básicos para hacer un ajuste polinomial de segundo orden.


def model(p, v, x, w):       
   a,b,c,d,e,f,g,h,i,j,k = p      #coefficients to the polynomials      
   return  a*v**2 + b*x**2 + c*w**2 + d*v*x + e*v*w + f*x*w + g*v + h*x + i*y + k  

def residuals(p, data):        # Function needed by fit routine
   v, x, w, z = data            # The values for v, x, w and the measured hypersurface z
   a,b,c,d,e,f,g,h,i,j,k = p   #coefficients to the polynomials  
   return (z-model(p,v,x,w))   # Returns an array of residuals. 
                               #This should (z-model(p,v,x,w))/err if 
                               # there are error bars on the measured z values


#initial guess at parameters. Avoid using 0.0 as initial guess
par0 = [1.0, 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] 

#create a fitting object. data should be in the form 
#that the functions above are looking for, i.e. a Nx4 
#list of lists/tuples like (v,x,w,z) 
fitobj = kmpfit.Fitter(residuals=residuals, data=data)

# call the fitter 
fitobj.fit(params0=par0)

El éxito de estas cosas depende en gran medida de los valores iniciales para el ajuste, así que elija cuidadosamente si es posible. Con tantos parámetros gratuitos, podría ser un desafío obtener una solución.

No, y (v, x, w) = av2 + bx2 + cw ** 2 + dvx + evw + fxw + gv + hx + iy + k MRocklin
¿Qué estás tratando de ajustar, y (x) = ax ** 2 + bx + c? De todos modos, ciertamente puede hacer ajustes multivariables con mpfit / kmpfit. reptilicus
¿Puedes publicar un ejemplo de regresión multivariable utilizando polyfit? No estoy convencido de que esto sea compatible. Después de revisar la documentación de kmpfit, me temo que esto también podría ser cierto en esta biblioteca. MRocklin
Así que esta biblioteca funcionaría pero soluciona el problema a través de un método iterativo. El ajuste polinomial de mínimos cuadrados se puede hacer en un solo paso resolviendo un sistema lineal. He publicado código en otra respuesta que hace esto usando numpy. MRocklin
0

Sklearn tiene un buen ejemplo usando su Pipelineaquí. Aquí está el núcleo de su ejemplo:

polynomial_features = PolynomialFeatures(degree=degrees[i],
                                         include_bias=False)
linear_regression = LinearRegression()
pipeline = Pipeline([("polynomial_features", polynomial_features),
                     ("linear_regression", linear_regression)])
pipeline.fit(X[:, np.newaxis], y)

No necesita transformar sus datos usted mismo, solo páselo a Pipeline.

Ese ejemplo no usa regresión multivariable. user4322543
11

Sklearn proporciona una forma sencilla de hacer esto.

Construyendo un ejemplo publicadoaquí:

#X is the independent variable (bivariate in this case)
X = array([[0.44, 0.68], [0.99, 0.23]])

#vector is the dependent data
vector = [109.85, 155.72]

#predict is an independent variable for which we'd like to predict the value
predict= [0.49, 0.18]

#generate a model of polynomial features
poly = PolynomialFeatures(degree=2)

#transform the x data for proper fitting (for single variable type it returns,[1,x,x**2])
X_ = poly.fit_transform(X)

#transform the prediction to fit the model type
predict_ = poly.fit_transform(predict)

#here we can remove polynomial orders we don't want
#for instance I'm removing the `x` component
X_ = np.delete(X_,(1),axis=1)
predict_ = np.delete(predict_,(1),axis=1)

#generate the regression object
clf = linear_model.LinearRegression()
#preform the actual regression
clf.fit(X_, vector)

print("X_ = ",X_)
print("predict_ = ",predict_)
print("Prediction = ",clf.predict(predict_))

Y aquí está la salida:

>>> X_ =  [[ 0.44    0.68    0.1936  0.2992  0.4624]
>>>  [ 0.99    0.23    0.9801  0.2277  0.0529]]
>>> predict_ =  [[ 0.49    0.18    0.2401  0.0882  0.0324]]
>>> Prediction =  [ 126.84247142]
esto no tiene sentido para mí, ¿por quéfit_transform  devuelve tanto la matriz de características polinomiales (matriz de vandermonde) Y también las predicciones? : / Charlie Parker
¿Sería posible incluir la implementación deldelete ¿función? ¡Aclamaciones! Shivam Gaur
¿Cómo se compara esto con solo hacerlo manualmente comoc_pinv = np.dot(np.linalg.pinv( Kern_train ),Y_train)? Charlie Parker
Que hacePolynomialFeatures  hacer explícitamente? ¿Puedo ver el código? Charlie Parker

Preguntas relacionadas