2012-02-15 5 views
5

Qualcuno può aiutare con qualche codice di query SQL a fornire stime dei coefficienti di una regressione polinomiale di terzo ordine?È necessaria la query di SQL Server per risolvere la regressione polinomiale di terzo ordine

Si prega di pensare che ho una tabella di valori di dati X e Y e voglia di stimare un, B e C:

Y(X) = aX + bX^2 + cX^3 + E 
+3

Sarebbe utile, se potessi incollare la formula per la stima di a, bec, perché, non tutti qui sono bravi con la matematica ... –

+0

Se è compito dei tuoi amici taggalo. –

+0

etichetta aggiunta [matematica] – zgpmax

risposta

4

soluzione approssimata ma veloce sarebbe quello di campionare 4 punti rappresentativi dai dati e risolvere l'equazione polinomiale per questi punti.

  1. quanto riguarda il campionamento , è possibile suddividere i dati in settori uguali e calcolare la media di X e Y per ogni settore - divisione può essere fatto utilizzando quartili di valori X, medie di X- valori, min(x)+(max(x)-min(x))/4 o qualsiasi cosa tu pensi sia la più appropriata.

    Per illustrare il campionamento quartili (vale a dire dai numeri di riga): illustration of solving 3rd order polynomial by sampling 4 points

  2. Quanto al risolvere, ho usato numberempire.com risolvere questi * equazioni per le variabili k,a,b,c:

    k + a*X1 + b*X1^2 + c*X1^3 - Y1 = 0, 
    k + a*X2 + b*X2^2 + c*X2^3 - Y2 = 0, 
    k + a*X3 + b*X3^2 + c*X3^3 - Y3 = 0, 
    k + a*X4 + b*X4^2 + c*X4^3 - Y4 = 0 
    

    * Poiché Y(X) = 0 + ax bx^2 + cx^3 + ϵ include implicitamente il punto [0, 0] come uno dei punti campione, creerebbe delle approssimazioni errate per i set di dati che non includono [0, 0]. Mi sono preso la libertà di risolvere Y(X) = k + ax bx^2 + cx^3 + ϵ invece.

Lo SQL attuale sarebbe andato come questo:

select 
    -- returns 1 row with columns labeled K, A, B and C = coefficients in 3rd order polynomial equation for the 4 sample points 
    -(X1*(X2p2*(X3p3*Y4-X4p3*Y3)+X2p3*(X4p2*Y3-X3p2*Y4)+(X3p2*X4p3-X3p3*X4p2)*Y2)+X1p2*(X2*(X4p3*Y3-X3p3*Y4)+X2p3*(X3*Y4-X4*Y3)+(X3p3*X4-X3*X4p3)*Y2)+X1p3*(X2*(X3p2*Y4-X4p2*Y3)+X2p2*(X4*Y3-X3*Y4)+(X3*X4p2-X3p2*X4)*Y2)+(X2*(X3p3*X4p2-X3p2*X4p3)+X2p2*(X3*X4p3-X3p3*X4)+X2p3*(X3p2*X4-X3*X4p2))*Y1)/(X1*(X2p2*(X4p3-X3p3)-X3p2*X4p3+X3p3*X4p2+X2p3*(X3p2-X4p2))+X2*(X3p2*X4p3-X3p3*X4p2)+X1p2*(X3*X4p3+X2*(X3p3-X4p3)+X2p3*(X4-X3)-X3p3*X4)+X2p2*(X3p3*X4-X3*X4p3)+X1p3*(X2*(X4p2-X3p2)-X3*X4p2+X3p2*X4+X2p2*(X3-X4))+X2p3*(X3*X4p2-X3p2*X4)) as k, 
    (X1p2*(X2p3*(Y4-Y3)-X3p3*Y4+X4p3*Y3+(X3p3-X4p3)*Y2)+X2p2*(X3p3*Y4-X4p3*Y3)+X1p3*(X3p2*Y4+X2p2*(Y3-Y4)-X4p2*Y3+(X4p2-X3p2)*Y2)+X2p3*(X4p2*Y3-X3p2*Y4)+(X3p2*X4p3-X3p3*X4p2)*Y2+(X2p2*(X4p3-X3p3)-X3p2*X4p3+X3p3*X4p2+X2p3*(X3p2-X4p2))*Y1)/(X1*(X2p2*(X4p3-X3p3)-X3p2*X4p3+X3p3*X4p2+X2p3*(X3p2-X4p2))+X2*(X3p2*X4p3-X3p3*X4p2)+X1p2*(X3*X4p3+X2*(X3p3-X4p3)+X2p3*(X4-X3)-X3p3*X4)+X2p2*(X3p3*X4-X3*X4p3)+X1p3*(X2*(X4p2-X3p2)-X3*X4p2+X3p2*X4+X2p2*(X3-X4))+X2p3*(X3*X4p2-X3p2*X4)) as a, 
    -(X1*(X2p3*(Y4-Y3)-X3p3*Y4+X4p3*Y3+(X3p3-X4p3)*Y2)+X2*(X3p3*Y4-X4p3*Y3)+X1p3*(X3*Y4+X2*(Y3-Y4)-X4*Y3+(X4-X3)*Y2)+X2p3*(X4*Y3-X3*Y4)+(X3*X4p3-X3p3*X4)*Y2+(X2*(X4p3-X3p3)-X3*X4p3+X3p3*X4+X2p3*(X3-X4))*Y1)/(X1*(X2p2*(X4p3-X3p3)-X3p2*X4p3+X3p3*X4p2+X2p3*(X3p2-X4p2))+X2*(X3p2*X4p3-X3p3*X4p2)+X1p2*(X3*X4p3+X2*(X3p3-X4p3)+X2p3*(X4-X3)-X3p3*X4)+X2p2*(X3p3*X4-X3*X4p3)+X1p3*(X2*(X4p2-X3p2)-X3*X4p2+X3p2*X4+X2p2*(X3-X4))+X2p3*(X3*X4p2-X3p2*X4)) as b, 
    (X1*(X2p2*(Y4-Y3)-X3p2*Y4+X4p2*Y3+(X3p2-X4p2)*Y2)+X2*(X3p2*Y4-X4p2*Y3)+X1p2*(X3*Y4+X2*(Y3-Y4)-X4*Y3+(X4-X3)*Y2)+X2p2*(X4*Y3-X3*Y4)+(X3*X4p2-X3p2*X4)*Y2+(X2*(X4p2-X3p2)-X3*X4p2+X3p2*X4+X2p2*(X3-X4))*Y1)/(X1*(X2p2*(X4p3-X3p3)-X3p2*X4p3+X3p3*X4p2+X2p3*(X3p2-X4p2))+X2*(X3p2*X4p3-X3p3*X4p2)+X1p2*(X3*X4p3+X2*(X3p3-X4p3)+X2p3*(X4-X3)-X3p3*X4)+X2p2*(X3p3*X4-X3*X4p3)+X1p3*(X2*(X4p2-X3p2)-X3*X4p2+X3p2*X4+X2p2*(X3-X4))+X2p3*(X3*X4p2-X3p2*X4)) as c 
    from (select 
     samples.*, 
     -- precomputing the powers should give better performance (at least i hope it would) 
     power(X1,2) X1p2, power(X2,2) X2p2, power(X3,2) X3p2, power(X4,2) X4p2, 
     power(Y1,3) Y1p3, power(Y2,3) Y2p3, power(Y3,3) Y3p3, power(Y4,3) Y4p3 
    from (select 
     avg(case when sector = 1 then x end) X1, 
     avg(case when sector = 2 then x end) X2, 
     avg(case when sector = 3 then x end) X3, 
     avg(case when sector = 4 then x end) X4, 
     avg(case when sector = 1 then y end) Y1, 
     avg(case when sector = 2 then y end) Y2, 
     avg(case when sector = 3 then y end) Y3, 
     avg(case when sector = 4 then y end) Y4 
     from (select x, y, 
      -- splitting to sectors 1 - 4 by row number (SQL Server version) 
      ceiling(row_number() OVER (ORDER BY x asc)/count(*) * 4) sector 
     from original_data 
    ) 
    ) samples 
) 

Secondo developer.mimer.com, queste caratteristiche opzionali devono essere attivato in SQL Server:

T611, "Elementary OLAP operations" 
F591, "Derived tables" 
2

SQL Server ha un incorporato in classifica la funzione NTILE (n) che creerà più facilmente i tuoi settori. Ho sostituito:

ceiling(row_number() OVER (ORDER BY x asc)/count(*) * 4) sector 

con:

NTILE(4) OVER(ORDER BY x ASC) [sector] 

Ho anche bisogno di aggiungere alcuni "poteri precalcolate" per consentire l'intervallo di colonna completa come selezionato. L'elenco completo viene visualizzato di seguito:

POWER(samples.X1, 2) AS [X1p2], 
POWER(samples.X1, 3) AS [X1p3], 
POWER(samples.X2, 2) AS [X2p2], 
POWER(samples.X2, 3) AS [X2p3], 
POWER(samples.X3, 2) AS [X3p2], 
POWER(samples.X3, 3) AS [X3p3], 
POWER(samples.X4, 2) AS [X4p2], 
POWER(samples.X4, 3) AS [X4p3], 
POWER(samples.Y1, 3) AS [Y1p3], 
POWER(samples.Y2, 3) AS [Y2p3], 
POWER(samples.Y3, 3) AS [Y3p3], 
POWER(samples.Y4, 3) AS [Y4p3] 

Nel complesso, ottima risposta di @Aprillion! Ben spiegato e il numberempire.com h/t è stato molto utile.