Donnerstag, 28. Juli 2011

Multiple Regression mit OLS_REGRESSION

Zur Demonstration dienen die folgenden Daten:

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 möchte mithilfe der multiple Regression überprüfen, ob und welche Abhängigkeiten zwischen dem Absatz und den Werbeausgaben für Printmedien, den Werbeausgaben für Fernsehen sowie dem Preis pro Mengeneinheit bestehen.

Um OLS_REGRESSION verwenden zu können ist ein Skript zu starten, das sich nach der Installation der Examples im Verzeichnis $ORACLE_HOME/plsql/demo befindet und den Namen olstype.sql trägt. Nun wird OLS_REGRESSION dazu verwendet, die oben genannte Fragestellung zu beantworten.

Die Daten befinden sich in einer Tabelle mit dem Namen REGRESSION_SAMPLE:

NACHFRAGE   WERBUNG_PRINT  WERBUNG_TV   PREIS
----------- -------------- ------------ ------
500         1              1            20
800         3              1            20
1500        3              3            18
2500        6              4            15
3200        6              6            12
Zunächst wird ein View erstellt, der eine Spalte vom Typ OLS_REGRESSION enthält. Beim Aufruf des Konstruktors sind die folgenden Argumente für die Parameter zu übergeben:

mean_y:

Arithmetisches Mittel der abhängigen Variable; in diesem Fall die Nachfrage.

Argument: avg(nachfrage)

variance_y:

Varianz der abhängigen Variable; in diesem Fall die Nachfrage. Es spielt dabei keine Rolle, ob man zur Berechnung der Varianz die Funktion VAR_POP oder VAR_SAMP verwendet. Jedoch ist zu beachten, dass man sich für eine der Funktionen entscheidet und diese dann in allen Argumenten verwendet. Bei der Funktion VAR_SAMP handelt es sich um die Stichprobenvarianz, welche mit (n-1) als Divisor gebildet wurde, während die Funktion VAR_POP n als Divisor verwendet.

Argument: var_pop(nachfrage)

MV:

Mittelwerte der unabhängigen Variablen in Form eines Vektors.

Argument:
utl_nla_array_dbl(
 avg(werbung_print),
 avg(werbung_tv),
 avg(preis))
VCM:

Varianz-Kovarianz-Matrix. Aufgrund der Symmetrie der Matrix erfolgt nur die Angabe der Elemente im oberen Dreieck.

Allgemeine Form der Varianz-Kovarianz-Matrix:



Da COV(X,X)=VAR(X) kann für alle Elemente der Hauptdiagonalen die Funktion für die Varianz verwendet werden. Zudem ist zu beachten, dass die Angabe Zeilenweise erfolgt. Im Beispiel stellt sich die gesamte Matrix wie folgt dar:



Ersetzt man auf der Hauptdiagonale noch die Kovarianz durch die Varianz erhält man:



Die Angabe erfolgt nun Zeilenweise in der Form:

VAR(X1),COV(X1,X2),COV(X1,X3),VAR(X2),COV(X2,X3),VAR(X3)

Argument:
utl_nla_array_dbl(
 var_pop(werbung_print),
 covar_pop(werbung_print,werbung_tv),
 covar_pop(werbung_print,preis),
 var_pop(werbung_tv),
 covar_pop(werbung_tv,preis),
 var_pop(preis))
CV:

Kovarianz-Vektor der unabhängigen und abhängigen Variablen in Form eines Vektors:

Argument:
utl_nla_array_dbl(
 covar_pop(nachfrage,werbung_print),
 covar_pop(nachfrage,werbung_tv),
 covar_pop(nachfrage,preis))
Der View stellt sich dann wie folgt dar:
create or replace view ols_view as
select
 count(*) n,
 ols_regression
 (
  avg(nachfrage),
  var_pop(nachfrage),
  utl_nla_array_dbl
  (
   avg(werbung_print),
   avg(werbung_tv),
   avg(preis)
  ),
  utl_nla_array_dbl
  (
   var_pop(werbung_print),
   covar_pop(werbung_print,werbung_tv),
   covar_pop(werbung_print,preis),
   var_pop(werbung_tv),
   covar_pop(werbung_tv,preis),
   var_pop(preis)
  ),
  utl_nla_array_dbl
  (
   covar_pop(nachfrage,werbung_print),
   covar_pop(nachfrage,werbung_tv),
   covar_pop(nachfrage,preis)
  )
 ) ols_object
from
 regression_sample;
Als zusätzliche Spalte wurde die Anzahl der Zeilen aufgenommen, welche nachher zur Berechnung des korrigierten Bestimmtheitsmaßes verwendet wird. Aufbauend auf dieser View lassen sich die Koeffizienten der Regressionsfunktion und das Bestimmtheitsmaß ermitteln:
select
 o.ols_object.getEquation(3) funktionsgleichung,
 round(o.ols_object.getCoefficient(0),3) b0,
 round(o.ols_object.getCoefficient(1),3) b1,
 round(o.ols_object.getCoefficient(2),3) b2,
 round(o.ols_object.getCoefficient(3),3) b3,
 round(o.ols_object.getCorrelation(),6) r,
 round(power(o.ols_object.getCorrelation(),2),6) r_quadrat,
 round((1-((1-power(o.ols_object.getCorrelation(),2))*((o.n-1)/(o.n-1-o.ols_object.betacount)))),3) korrigiertes_r_quadrat
from
 ols_view o;
      B0       B1       B2       B3        R       R2      K_R2
-------- -------- -------- -------- -------- -------- ---------
1440,816  168,367  266,327  -69,388  ,999842  ,999685      ,999
Zusätzlich zu den Koeffizienten kann es von Interesse sein, die standardisierten Koeffizienten zu ermitteln. Diese geben Auskunft über den Einfluss der Variablen auf die Zielgröße. Man erhält die so genannten Beta-Faktoren oder Z-Scores durch folgende Abfrage:
with sd_query as
(
 select
  stddev(werbung_print) sd_x1,
  stddev(werbung_tv) sd_x2,
  stddev(preis) sd_x3,
  stddev(nachfrage) sd_y
 from
  regression_sample
)
select
 round((o.ols_object.getCoefficient(1)*sd.sd_x1/sd.sd_y),6) beta_x1,
 round((o.ols_object.getCoefficient(2)*sd.sd_x2/sd.sd_y),6) beta_x2,
 round((o.ols_object.getCoefficient(3)*sd.sd_x3/sd.sd_y),6) beta_x3
from
 ols_view o, sd_query sd;
BETA_X1                BETA_X2                BETA_X3
---------------------- ---------------------- ----------------------
0.320754               0.496462               -0.211222
Man stellt nun zum Beispiel fest, dass die Variable für TV-Werbung mehr als doppelt so viel Einfluss auf die Nachfrage besitzt, wie die Variable für den Preis.

Will man nun die Regressionsfunktion nutzen, um die Nachfrage zu prognostizieren kann man die Methode PREDICT verwenden. Ein Argument vom TYP UTL_NLA_ARRAY_DBL enthält dabei die Werte für die Regressionsfunktion; in diesem Beispiel genau drei Stück für die Variablen Werbung-Print, Werbung-TV und Preis. Die folgende Abfrage vergleicht die tatsächliche Nachfrage mit dem Wert der Regressionfunktion.
select
 nachfrage,
 o.ols_object.predict(utl_nla_array_dbl(werbung_print,werbung_tv,preis)) prediction
from
 ols_view o, regression_sample;
NACHFRAGE              PREDICTION
---------------------- ----------------------
500                    487.7551020409137
800                    824.48979591844341
1500                   1495.918367346951072
2500                   2475.51020408157385
3200                   3216.32653061211845
Will man nun die Nachfrage prognostizieren, wenn die Werbeausgaben für Printmedien 400.000€, die Werbeausgaben für TV 350.000€ und der Preis pro Mengeneinheit 1.600€ beträgt erhält man:
select o.ols_object.predict(utl_nla_array_dbl(4,3.5,16)) prediction
from ols_view o;
PREDICTION
----------------------
1936.22448979589853

Keine Kommentare:

Kommentar veröffentlichen