2012-02-15 4 views
5

Czy ktoś może pomóc przy niektórych kodach zapytań SQL, aby podać szacunki współczynników dla regresji wielomianowej 3 rzędu?Potrzebujesz zapytania SQL Server do rozwiązania regresji wielomianowej trzeciego rzędu

Należy zakładać, że mam tabelę wartości danych X i Y i chcemy oszacować A, B i C:

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

Byłoby pomocne, gdyby można było wkleić formułę do oceny a, b i c, ponieważ nie wszyscy tutaj są dobrzy z matematyką ... –

+0

Jeśli jest to zadanie domowe, to je oznacz. –

+0

dodano tag [math] – zgpmax

Odpowiedz

4

przybliżoną, ale szybkim rozwiązaniem byłoby próbka 4 punkty przedstawiciel danych i rozwiązać równanie wielomianowe dla tych punktów.

  1. chodzi o próbkowania, można podzielić dane na równe sektory i obliczyć średnią z X i Y dla każdego sektora - podział można zrobić za pomocą kwartyle X-wartości średnie X- wartości, min(x)+(max(x)-min(x))/4 lub cokolwiek uważasz za najbardziej odpowiednie.

    celu zilustrowania próbkowanie przez kwartyle (tj liczby wierszy): illustration of solving 3rd order polynomial by sampling 4 points

  2. Co do rozwiązania, kiedyś numberempire.com rozwiązać te * równania dla zmiennych 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 
    

    * Ponieważ Y(X) = 0 + ax bx^2 + cx^3 + ϵ niejawnie zawiera punkt [0, 0] jako jeden z punktów przykładowych, tworzy złe przybliżenia dla zestawów danych, które nie obejmują [0, 0]. Zamiast tego skorzystałem z możliwości rozwiązania Y(X) = k + ax bx^2 + cx^3 + ϵ.

Rzeczywiste SQL pójdzie tak:

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 
) 

Według developer.mimer.com te opcjonalne funkcje muszą być włączone w SQL Server:

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

SQL Server ma wbudowanego w funkcji rankingu NTILE (n), która będzie łatwiej tworzyć sektory. Wymieniłem:

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

z:

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

Musiałem także dodać kilka „precomputed moce” w celu umożliwienia pełnego zakresu kolumny jako wybrany. Poniżej znajduje się pełna lista:

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] 

Ogólnie rzecz biorąc, wspaniała odpowiedź autorstwa @Apillion! Dobrze wyjaśnione i numberempire.com h/t był bardzo pomocny.