Montag, 8. August 2011

Multiple Regression mit UTL_NLA

Heute geht's erneut um die multiple Regression, die in diesem Beispiel mithilfe von UTL_NLA durchgeführt wird. UTL_NLA stellt dazu BLAS (Basic Linear Algebra Subroutines) und LAPACK (Linear Algebra PACKage) bereit.

Wie im vorherigen Post zu diesem Thema, werden die folgenden Daten verwendet:

y = Nachgefragte Menge in 1000 Stück
x1 = Werbeausgaben in 100.000 Euro für Printmedien
x2 = Werbeausgaben in 100.000 Euro für Fernsehen
x3 = Preis pro Mengeneinheit in 100 Euro

yx1x2x3
500 1 1 20
800 3 1 20
1500 3 3 18
2500 6 4 15
3200 6 6 12

Man erhält die Koeffizienten der Regressionsfunktion in Form des Vektors b durch:


Die Matrix X im Beispiel:


Der Vektor y im Beispiel:


Die Berechnung des Vektors b umfasst also die Bestimmung der Inversen, die Multiplikation von Matrizen und die Multiplikation einer Matrix mit einem Vektor. All diese Operationen lassen sich mithilfe von UTL_NLA durchführen. Für die Multiplikation von Matrizen wird BLAS_GEMM verwendet, für die Multiplikation einer Matrix mit einem Vektor wird BLAS_GEMV verwendet und für die Lösung des Gleichungssystems kommt LAPACK_GESV zum Einsatz.

Die Werte für die Matrizen werden entweder Zeilen- oder Spaltenweise angeben, je nachdem für welches Argument man sich für den Parameter PACK entscheidet. Im folgenden Beispiel wurde als Argument für den Parameter PACK 'R' gewählt. Die Deklaration stellt sich dann wie folgt dar:
v_matrix_xt UTL_NLA_ARRAY_DBL := UTL_NLA_ARRAY_DBL(  1 , 1 , 1 , 1 , 1, 
                                                     1 , 3 , 3 , 6 , 6, 
                                                     1 , 1 , 3 , 4 , 6,
                                                     20, 20, 18, 15, 12 );
 
v_matrix_x UTL_NLA_ARRAY_DBL := UTL_NLA_ARRAY_DBL(   1 , 1 , 1 , 20,
                                                     1 , 3 , 1 , 20,
                                                     1 , 3 , 3 , 18,
                                                     1 , 6 , 4 , 15, 
                                                     1 , 6 , 6 , 12 ); 
Der Aufruf der Prozedur UTL_NLA.BLAS_GEMM ermittelt nun die Matrix XTX.
UTL_NLA.BLAS_GEMM(
   transa => 'N',
   transb => 'N',
   m      => 4,
   n      => 4,
   k      => 5,
   alpha  => 1,
   a      => v_matrix_xt,
   lda    => 5,
   b      => v_matrix_x,
   ldb    => 4,
   beta   => 0,
   c      => v_matrix_xtx,
   ldc    => 4,
   pack   => 'R');
Nun wird der Vektor XTy mithilfe von UTL_NLA.BLAS_GEMV bestimmt:
UTL_NLA.BLAS_GEMV(
   trans  => 'N',
   m      => 4,
   n      => 5,
   alpha  => 1,
   a      => v_matrix_xt,
   lda    => 5,
   x      => v_vector_y,
   incx   => 1,
   beta   => 0,
   y      => v_vector_xty,
   incy   => 1,
   pack   => 'R');
Im finalen Schritt, zur Bestimmung der Koeffizienten, ist das folgende Gleichungssystem zu lösen:

XTXb=XTy

Diese Aufgabe erledigt die Prozedur UTL_NLA.LAPACK_GESV, wobei sich das Ergebnis nach dem Aufruf in der Variablen befindet, die als Argument für den Parameter b übergeben wurde.
UTL_NLA.LAPACK_GESV(
   n      => 4,
   nrhs   => 1,
   a      => v_matrix_xtx,
   lda    => 4,
   ipiv   => v_matrix_p,
   b      => v_vector_xty,
   ldb    => 1,
   info   => v_result,
   pack   => 'R');
Die Ausgabe der Koeffizienten ergibt:
for i in 1..v_vector_xty.count loop
 dbms_output.put_line('b' || (i-1) || ' = ' || to_number(v_vector_xty(i)));
end loop;

b0 = 1440.8163265303169
b1 = 168.36734693877926
b2 = 266.32653061226313
b3 = -69.38775510202751
Die Regressionsfunktion ergibt sich somit zu:

y = 1440,8163 + 168,3673∙x1 + 266,3265∙x2 - 69,3878∙x3

Abschließend sei noch erwähnt, dass eine Matrix bzw. ein Vektor vom Typ UTL_NLA_ARRAY_DBL bzw. UTL_NLA_ARRAY_FLT maximal 1.000.000 Elemente enthalten kann.

Natürlich befinden sich die Daten meist in einer Tabelle und man will die Matrix nicht manuell angeben. Vielmehr möchte man die Elemente durch SQL und PL/SQL gewinnen und in einer Variablen vom entsprechenden Typ speichern.

Aber das ist was für einen anderen Post...

Keine Kommentare:

Kommentar veröffentlichen