Das folgende Notebook gibt einen Einblick in die Möglichkeiten des Einsatzes emergenzbasierter Statistik am Beispiel der Analyse makroökonomischer Daten. Es soll als Lehrmaterial zur Vermittlung emergenter Methoden dienen.
Es ist in sehr kurzer Zeit entstanden und wir bitten daher um Nachsicht wegen sicher vorhandener orthographischer und anderer formaler Fehler.
Das Notebook lässt sich auf dem Methoden-Server des ZES nachrechnen und weiterentwickeln.
Um noch einmal kurz die Grundbegriffe der emergenzbasierten Statistik zu rekapitulieren, wollen wir mit einem kleinen emergenten Gesetz über das Geldmengenwachstum beginnen.
Lesen wir zuerst die ML-Toolbox und die Datenbank ein,
from ML_Tool_029 import *
set_global_rel(0.8,plot_rel=False)
source="C:/Users/Frischhut/Desktop/Lehrveranstaltung Emergente Gesetze/Projektarbeit_Ruth/Projektarbeit Yannik Ruth_1.csv"
#source='C:/Users/Kuck/Documents/kuck/Python/YannikRuth/Projektarbeit Yannik Ruth_1.csv' #Hier liegt die Datei
data = pd.read_csv(source,sep=',',parse_dates=False)
data=copy.deepcopy(data.loc[~data.M1_US.isnull()])
change_cent=False
def add_century(x):
global change_cent
if x[4:]=="00":
change_cent=True
if change_cent:
return x[:4]+"20"+x[4:]
else:
return x[:4]+"19"+x[4:]
data["DATE"]=data["DATE"].apply(add_century)
data["DATE"]=pd.to_datetime(data["DATE"],format="%b-%Y")
data.index=data["DATE"]
#data=copy.deepcopy(data.loc[~data.C_REX.isnull()])
#data.index=np.arange(len(data))
data['C']=True
data['null']=False
und werfen einen kurzen Blick auf den Verlauf der einzelnen Zeitreihen:
df=data
zeile=1
spalte=1
pl=0
plt.figure(figsize=(20, 15))
dataseries=['C_SU', 'Case_home', 'Case_10', 'C_DJ', 'M1_US', 'M2_US',
'C_DAX', 'C_KDAX', 'C_REX', 'M1_DE', 'M2_DE', 'M3_DE', 'C_FT', 'M1_GB',
'M2_GB', 'M3_GB', 'C_NI', 'M0_JP']
for asset in dataseries:
#print(asset,df[asset].pct_change().mean())
zeilen=(len(dataseries)//3)+1
spalten=3
#print(pl+1,zeile,spalte)
plt.subplot(zeilen,spalten,pl+1)
plt.plot(df.loc[~df[asset].isnull()]['DATE'],df[asset].loc[~df[asset].isnull()],label=asset)
pl=pl+1
plt.legend()
plt.show()
Die Daten in diesem Beispiel bestehen aus Monatsdaten einer kleinen Auswahl von unterschiedlichen Assets:
Zusätzlich dazu werden Monatsdaten für eine kleine Anzahl von Geldmengenaggregaten verwendet:
Wenn wir nun die Frage nach den Wachstumsraten der Geldmenge M2 für Deutschland (M2_DE.pct_change()
) stellen, so können wir feststellen, dass die Geldmenge in manchen Monaten gewachsen und in anderen geschrumpft ist:
plt.plot(data.DATE,data.M2_DE.pct_change())
plt.show()
Wenn wir aber nach einer Fenstergröße T suchen, für die die rollierende mittlere Wachstumsrate der Geldmenge immer größer (oder kleiner) ist als Null, dann stellen wir fest dass:
Eine solche bisher immer wahre Relation von Funktionen über Sequenzen von Messungen nennen wir ein emergentes Gesetz.
aktlaw=LLaws(data,'df.M2_DE.pct_change()',bed_y='df.C')
#aktlaw.create_emergence_movie('ot',fps=1,LagList=range(1,len(data)//2-1,10))
aktlaw.PlotLaws('ot')
display(aktlaw.DescribeLaw()[['Target','Bench','Bed_y','R','Bed_x','TU_ot','Div(TU_ot)','Min(TU_ot)','Max(TU_ot)']])
Wir haben an dieser Stelle die Größen DiV und T noch einmal kurz eingeführt, weil sie für die weitergehenden Berechnungen von zentraler Bedeutung sind.
Eines der zentralen Ergebnisse der emergenzbasierten Statistik ist die Entdeckung von empirischen Gesetzen über die Güte von Prognoseprozessen.
Wenn man mit zum Zeitpunkt t DiV mal bestätigten Gesetzen mit Emergenzmenge T prognostiziert, dass das Muster zum Zeitpunkt t+T wieder zu beobachten sein wird, dann kann man zum Zeitpunkt t+T überprüfen, ob diese Prognose richtig war.
Dies haben wir für sehr viele Datensätze und Prognoseprobleme getan und die Anzahl von Gesetzen mit den Eigenschaften (DiV,T) und die Anzahl richtiger Prognosen gezählt.
Den Anteil bestätigter Prognosen an den gesamten Prognose nennen wir Rel oder Reliability. Man kann nun feststellen, dass es für Prognosen mit Gesetzen aus einer (DiV,T)-Klasse emergente Gesetze über die Mindestreliability nach einer bestimmten Anzahl von Prognosen gibt. Wir nennen diese Gesetze Meta-Gesetze.
Mit Hilfe dieser Meta-Gesetze können wir die Anforderungen an die Anzahl von notwendigen Bestätigungen einer T-Klasse von Gesetzen empirisch festlegen, wenn wir eine bestimmte Mindestreliability verlangen:
set_global_rel(0.8,plot_rel=True)
Die erzeugte Grafik zeigt, wie häufig ein Muster - in Abhängigkeit von der Emergenzmenge T
- aufgetreten sein muss, um in eine Kategorie zu fallen, die bisher immer eine bestimmte Mindestprognosegüte hatte (hier Reliability von 0.8 --> mindestens 80% richtige Vorhersagen nach einer bestimmten Anzahl von Prognosen mit Gesetzen dieser Art).
Ein Muster, dass (wie im obigen Beispiel) sich in Sequenzen der Länge T=32
immer finden ließ, muss also mindestens 9 mal aufgetreten (oder 8 mal bestätigt worden) sein, um zu den Gesetzen mit einer Reliability von 0.8 zu gehören. Wenn ein Muster nach 265 Beobachtungen emergiert so genügen bereits 4 Bestätigungen.
Bei unseren weiteren Berechnungen steuern die Meta-Gesetze im Hintergrund alle Berechnungen. Auf diese Art werden die Mindestanforderungen an die Anzahl von Bestätigungen von verwendeten Gesetzen festgelegt werden.
Eine genauere Erklärung und Beispiele von Meta-Gesetzen lassen sich auf unserer Internetseite finden.
Wir wollen an dieser Stelle noch einmal festhalten, dass
dieser Ansatz auf einem rein empirischen Fundament basiert:
Die Aussage, dass die durchschnittliche monatliche Wachstumsrate der Geldmenge M2 nach jeder Sequenz von $T=32$ Monaten größer ist als Null, ist eine rein empirische Aussage.
Weiterhin wissen wir aus unseren Metaanalysen, dass die Prognosen, dass ein Muster der Größe $T=32$ das $DiV=12,56$ mal bestätigt wurde, auch beim nächsten Mal wieder auftritt, (nach Sequenzen von mindestens 16384 Prognosen) bisher immer zumindest zu 80% richtig waren. Auch dies ist ein empirisches Faktum.
Wenn wir also die Reliability auf 80% setzen so stellen wir sicher, dass wir nur Gesetze finden, für die die Prognose, dass das Muster auch beim nächsten Mal zu beobachten sein wird, bisher immer in mindestens 80% der Fälle richtig war.
Aus den oben bereits dargestellten Größen erzeugen wir eine Reihe von Prognosezielen (endogene Variablen) und potentiell erklärenden Variablen oder Features.
Eine endogene Variable, also eine Variable, die man vorhersagen möchte, ist z.B. die Veränderung der M1-Geldmenge in Deutschland im nächsten Monat, oder aber die Wachstumsrate des DAX in den nächsten 2 Monaten usw.
Ein Beispiel für ein Feature ist die durchschnittliche Veränderung der M3-Geldmenge in den USA in den letzten 3 Monaten oder die durchschnittliche Wachstumsrate in den letzten 12 Monaten etc.
Die dahinterliegende Vermutung ist, dass evtl. in Abhängigkeit dieser Größe emergente Gesetze für endogene Variablen gefunden werden können.
IndexList=['C_SU','C_DJ','Case_home','Case_10','C_DAX','C_KDAX','C_REX','C_FT','C_NI'] #Liste der verwendeten Indizes
#GeldList=[['M1_US','M2_US'],['M1_US','M2_US'],['M1_US','M2_US'],['M1_US','M2_US'],['M1_DE','M2_DE','M3_DE'],['M1_DE','M2_DE','M3_DE'],['M1_DE','M2_DE','M3_DE'],['M1_GB','M2_GB','M3_GB'],['M0_JP']]
GeldL=[['M1_US','M2_US'],['M1_DE','M2_DE','M3_DE'],['M1_GB','M2_GB','M3_GB'],['M0_JP']] #Liste der Geldmengen
endo=[] #Initialisierung der Liste mit Größen, die prognostiziert werden sollen
exo=[] #Initialisierung der Liste mit exogenen Variablen
for aktindex in IndexList:
endo+=['df.'+aktindex+'.pct_change().shift(-1)'] #Ein-Monats-Rendite
endo+=['df.'+aktindex+'.pct_change(2).shift(-2)'] #Zwei-Monats-Rendite
endo+=['df.'+aktindex+'.pct_change(3).shift(-3)'] #Drei-Monats-rendite
for lag in [1,2,3,4,5,6,8,12,16,24,36]:
exo+=['df.'+aktindex+'.pct_change().rolling(window='+str(lag)+').mean()'] #Rollierende Mittelwerte
if lag>2:
exo+=['df.'+aktindex+'.pct_change().rolling(window='+str(lag)+').std()']
exo+=['df.'+aktindex+'.pct_change().rolling(window='+str(lag)+').std()']#Rollierende Standardabweichungen
for geld in GeldL:
for aktgeld in geld:
endo+=['df.'+aktgeld+'.pct_change().shift(-1)'] #Ein-Monatsveränderungsrate der Geldmente
endo+=['df.'+aktgeld+'.pct_change(2).shift(-2)'] #Zwei-Monatsveränderungsrate der Geldmente
endo+=['df.'+aktgeld+'.pct_change(3).shift(-3)'] #Drei-Monatsveränderungsrate der Geldmente
for lag in [1,2,3,4,5,6,8,12,16,24,36]:
exo+=['df.'+aktgeld+'.pct_change().rolling(window='+str(lag)+').mean()']
if lag>2:
exo+=['df.'+aktgeld+'.pct_change().rolling(window='+str(lag)+').std()']
exo=DataFrame(exo,columns=['Genstring'])
data.index=np.arange(len(data))
data['C']=True
data['null']=False
Die Daten werden in eine Stichprobe, die zur Suche nach Emergenten Gesetzen verwendet wird (within-sample Beobachtungen) und eine Stichprobe (out-of-sample Beobachtungen/Evaluierungsdaten), die für die Überprüfung der Gesetze verwendet wird, aufgeteilt.
Die Evaluierungsstichprobe umfassen die letzten 5 Jahre (2011 bis 2016) der Beobachtungen in der Datenbank. So können die gefundenen emergenten Gesetze anhand von bisher "ungesehenen Daten" überprüft werden und ein tatsächliches Anwendungsszenario simuliert werden.
BisT=len(data)-60 #Aufteilung: 5 Jahre (60 Monate) zur Evaluierung / Rest der Beobachtungen zur Schätzung
# Größe, gesamte Anzahl Beobachtungen in Schätzstichprobe,Anzahl in Evaluierungsstichprobe, Gesamt
for feld in data.columns:
print(feld,data.iloc[:BisT][feld].count(),data.iloc[BisT:][feld].count(),data[feld].count())
Im nächsten Schritt wird auf Basis der Daten ein sog. KnowledgeNet berechnet.
Die verwendeten Ziele (endogene Variablen) für das KnowledgeNet sind in diesem Fall die zukünftigen prozentualen Veränderungen im nächsten Monat, in 2 Monaten und in 3 Monaten der oben bereits beschriebenen Größen.
df.C_SU.pct_change().shift(-1): Prozentuale Veränderung des S&P500 im nächsten Monat
df.C_SU.pct_change(2).shift(-2): Prozentuale Veränderung des S&P500 über die nächsten 2 Monate
df.C_SU.pct_change(3).shift(-3): Prozentuale Veränderung des S&P500 über die nächsten 3 Monate
Beispiel für ein solches Objekt ist in diesem Fall die Auswahl der Zeitpunkte anhand einer Regel wie dieser:
Man betrachtet nur die Monate, in denen die Veränderung der M1-Geldmenge in den USA im Schnitt im letzten Jahr im 80%-100% Quantil (expandierend berechnet) war, d.h. in den höchsten 20% der Veränderungsraten.
categorize(df.M1_US.pct_change().rolling(window=12).mean(),5)==5
Das expandierende Quantil wird mithilfe der categorize
-Funktion berechnet. Im Netz werden noch deutliche komplizierte Objektregeln erzeugt.
Eine etwas detailliertere Erklärung von KnowledgeNets findet man ebenfalls auf unserer Internetseite.
knet=Knowledge_Net(data.iloc[:BisT],endo,exo,file_name="makro_test",limitdepth=5,law_OR=True,eval_data=data)
knet.create_unique_features()
Creation of Unique Features:
df.C_SU.pct_change().rolling(window=1).mean(): cardinal var without parameters
categorization [1, 2, 3, 4, 5] 5
...
df.Case_home.pct_change().rolling(window=16).mean(): cardinal var without parameters
categorization [1, 2, 3, 4, 5] 5
...
df.M0_JP.pct_change().rolling(window=36).std(): cardinal var without parameters
categorization [1, 2, 3, 4, 5] 5
All Features 8820
Features 4638 Unique Feature No. 8820 (categorize(df.M0_JP.pct_change().rolling(window=3
All Features: 8820 Unique Features: 4638
Am Anfang der Zellenausgabe erscheinen Meldungen zur Erstellung von exogenen Variablen (Features). Dabei wird jede Größe in die bereits angesprochenen expandierenden Quantile unterteilt, die als Ausgangsobjekte im Netz verwendet werden.
knet.create_net()
Die grafische Übersicht am Ende der Ausgabe zeigt die gefundenen Objekte für alle im Netz verwendeten Ziele.
Jede einzelne Grafik zeigt Punkte, die Eigenschaften von Objekten graphisch darstellen: Den Durchschnittwert einer einzelnen endogenen Variablen für dieses Objekt und seine Größe.
In der oberen linken Grafik zeigen die Punkte z.B. die prozentuale Veränderung des S&P500 im nächsten Monat auf der Ordinate. (df.C_SU.pct_change().shift(-1)
). An der Abszisse der Grafik ist jeweils die Größe des Objekts, d.h. die Anzahl Beobachtungen, die mit dieser Objektregel ausgewählt werden, abzulesen. Ein Wert von 125 ist so zu interpretieren, dass 125 Monate im Schätzsample durch die Regel ausgewählt wurden.
Es sei noch einmal erwähnt, dass diese Objekte sich dadurch auszeichnen, dass sie in Bezug auf den Rollierenden T-Mittelwert einer der endogenen Variablen gegenüber allen ungefähr "gleichgroßen" Objekten immer unterschieden haben.
Ein einfaches Beispiel eines Objekts oder einer Auswahlregel ist das Folgende:
'~((categorize(df.C_KDAX.pct_change().rolling(window=1).mean(),3)==1.0))'
Mit dieser Regel werden Monate ausgewählt, bei denen die prozentuale Veränderung des Kurs-DAX im letzten Monat nicht (~
Negation) im untersten Drittel (==1.0
) der Beobachtungen lag (mit expandierenden Quantilen berechnet).
Man kann nun sehr leicht überprüfen, wie gut sich der Mittelwert der gefundenen Objekte für die einzelnen Ziele out-of-sample "übertragt", d.h. ob der Mittelwert mit den neuen/ungesehen Daten ähnlich hoch ist.
Dabei ist aber zu bedenken, dass Gesetze nur in Bezug auf die Rangordnung der Mittelwerte mindestens eines Ziels gefunden wurden. Es kann also gar nicht erwartet werden, dass sich die Größe der Mittelwerte 1:1 in die Zukunft überträgt.
Empirisch wissen wir nur, dass die Gesetze über die Ordnungsbeziehung der Mittelwerte zu einer Klasse von Gesetzen gehören, die sich (salopp formuliert) in mindestens 80% der Fälle wiederholt.
Wir suchen diese Objekte aber auch gar nicht mit dem Ziel, dass wir aus den Ergebnissen deduktiv etwas über zukünftige Werte der Ziele ableiten wollen. Sie sind nur in dem Sinne "interessant", dass wir so eine Menge von bisher immer unterschiedlicher Situationen charakterisieren können.
Trotzdem wollen wir an dieser Stelle eine Grafik erzeugen, die den Mittelwerten des jeweiligen Objekts in der Schätzstichprobe den Mittelwert in der Evaluierungsstichprobe gegenüberstellt.
Wir werden sehen, dass die Objekte Information über die relative und absolute Höhe der Mittelwerte der endogen Variablen in der Evaluierungsstichprobe enthalten. (Wir verfügen auch über Algorithmen, mit denen man Objekte aus KnowledgeNets direkt für die Entscheidungsfindung verwenden kann. Diese werden aber in diesem Notebook nicht vorgestellt.)
# Ausgabe der Scatterplotts zwischen Mittelwert eines Objekts in der
# Schätzstichprobe und in der Evaluierungsstichprobe für alle Ziele
df=data
zeile=1
spalte=1
pl=0
plt.figure(figsize=(20, 45))
plt.subplots_adjust(hspace=0.4)
for goal in endo:
zeilen=(len(endo)//3)+1
spalten=3
a=copy.deepcopy(knet.ResultsList[0]).sort_values(['objective','mean'],ascending=False)
a=a.loc[(a.objective==goal)
plt.subplot(zeilen,spalten,pl+1)
plt.plot(a['mean'],a['EvalMean'],'.',label='Observed')
plt.plot(a['mean'],a['mean'],'-',label='Bisector')
text=str(a['mean'].cov(a['EvalMean'])/a['mean'].var())
plt.title(goal+' b='+text)
plt.ylabel('Evaluation')
#plt.xlabel('Estimation')
#plt.plot(df.loc[~df[asset].isnull()]['Date'],logrend(df[asset].loc[~df[asset].isnull()]).expanding().sum(),label=asset)
pl=pl+1
plt.legend()
plt.xlabel('Estimation')
plt.show()
In obiger Übersichtsgrafik, wird die Güte der Übertragung der Mittelwerte der Objekte für die einzelnen Ziele dargestellt.
Auf der Abszisse ist die Höhe des in-sample Mittelwerts des Objekts, auf der Ordinate die Höhe des out-of-sample Mittelwerts des Objekts dargestellt. Bei perfekter Übertragung liegt der Punkt auf der grünen Winkelhalbierenden, da in diesem Fall in-sample und out-of-sample Mittelwert identisch wäre.
Wie man anhand der einzelnen Grafiken sehen kann, variiert die Güte der Übertragbarkeit für das jeweilige Ziel bzw. für die einzelne Prognosedauer (jeweils 1 Monat/2 Monate/3 Monate in die Zukunft).
Auch wenn die Übertragung (wie auch nicht anders zu erwarten) nicht perfekt ist, zeigt die Übersichtsgrafik doch, dass sich die Mittelwerte der gefundenen Objekte für die vielen unterschiedlichen Ziele gut übertragen und es möglich ist Zusammenhänge für die Veränderung von Aktienindizes, Rentenindizes, Häuserpreisen und Geldmengen zu finden.
Bei einigen der untersuchten Aktienindizes ist es sogar möglich Objektregeln zu finden, die Monate auswählen mit einer im Schnitt negativen Rendite.
Vielleicht sei an dieser Stelle noch kurz erwähnt, warum gerade Multiziel-Oder-Netze ein so informationshaltiges Konstrukt sind. Es hat sich empirisch gezeigt, dass Objekte, die für ein bestimmtes Ziel immer anders sind als alle anderen, oft auch hilfreich bei der Suche nach Objekten für andere Ziele sind. In diesem Sinne leistet ein Multizielnetz dass, was die "unsupervised Layers" in "deep neural nets" leisten: Sie geben eine Zusammenfassung der in den Daten zu findenden Strukturen.
Im nächsten Schritt werden auf Basis der gefundenen Objekte im Knowledge-Net Emergenzbasierte Modelle für die einzelnen endogenen Variablen erstellt.
Ein Beispiel einer Prognoseheuristik ist z.B. die Schätzung mit dem Mittelwert, linearen kleinste-Quadrate Regression etc (alles expandierend berechnet).
Eine etwas genauere Erklärung des Ablaufs und der Vorgehensweise können Sie in folgendem Notebook finden.
In der folgenden Zelle wird für das erste Ziel (prozentuale Veränderung des S&P500 im nächsten Monat) ein Emergenzbasiertes Modell mithilfe des hinterlegten KnowledgeNets makro_test_0
erstellt.
In der Ausgabe werden zunächst die Modellergebnisse mit in-sample Daten und anschließend die Ergebnisse mit out-of-sample Daten gezeigt.
#Erstellung eines Modells für die prozentuale Veränderung des S&P500 im nächsten Monat
aktvar="df.C_SU.pct_change().shift(-1)"
modellist_1=[]
print()
print(aktvar)
print()
aktmodel=Model(['makro_test_0'],"makro_test_0",aktvar,QAb,New_Y=False,Only_mean=False,load_directory="./")
aktmodel.addmodel(['makro_test_0'],'('+aktvar+')',addtype=2,GlobalRel=0.75,MaxIter=1,AddEst=True)
aktmodel.evalmodel(data)
modellist_1+=[aktmodel]
Die Interpretation der Ergebnisse soll anhand des ersten Modells für die prozentuale Veränderung des S&P500 im nächsten Monat (df.C_SU.pct_change().shift(-1)
) verdeutlicht werden.
Die erste Grafik in der Ausgabe geben die vom Algorithmus endogen bestimmten Grenzen der prozentualen Veränderung des S&P500 an.
Anschließend werden die gefundenen Objekte aus dem Netz dahingehend untersucht, ob Prognoseregeln für die einzelnen Objekte gefunden werden können, die gesetzmäßig eine bestimmte Fehlermetrik immer verbessern (hier QAb
: rollierender mittlerer quadratischer Prognosefehler).
Dies erfolgt iterativ für unterschiedliche Reliabilities (0.75
und 0.725
).
Die Beschreibung des resultierenden Modells ist in der folgenden Zelle dargestellt:
# Beschreibung des Modells für das erste Ziel df.C_SU.pct_change().shift(-1):
modellist_1[0].LawList[0]
Jede Zeile in der Tabelle zeigt eine Objekt-Prognoseheuristik Kombination (obj
: Objekt bzw. heuristic
: Prognoseheuristik) und einige Charakteristika der gefundenen Ergebnisse.
Diese Objekt-Prognoseheuristik Kombinationen hatten immer in Fenstern der Länge T=44
(bzw. T=186
) die Eigenschaft, dass die Fehlermetrik (hier QAb
; Quadratischer Fehler) immer niedriger war als bei Prognosen mit dem bis dahin verwendeten Modell. Jede Zeile zeigt also eine Heuristik, die relativ zu vorherigen Verfahren immer zu einer Verbesserung der Schätzung (in Bezug auf die Zielmetrik) geführt hat.
Das erste Gesetz hat z.B. relativ zur universellen ersten Benchmark yd=0
in jeder Sequenz der Länge T=44
zu einer Verbesserung des mittleren quadrierten Prognosefehlers geführt. Dabei lag die Verbesserung in jeder Sequenz zwischen min=0.000033
und max=0.002330
. Dieses emergente Gesetz über die Prognoseverbesserung mit dieser Heuristik ist DiV=5
mal bestätigt. Damit gehört die Prognose, dass bei Verwendung dieser Heuristik zur Schätzung im nächsten Fenster von T=44
Beobachtungen wieder eine durchschnittliche Verbesserung erreicht wird zu einer Klasse von Prognosen, von denen wir wissen das bisher mindestens 80% richtig waren.
Anschließend werden in der Ausgabe einige within-sample Statistiken gezeigt:
mean absolute prediction error: 0.028975303315531043
mean squared prediction error : 0.001510170184198542
root of mean squared prediction error : 0.038860908175164174
Correlation : 0.435296776785
mean for yd>0: 0.013926756505256453 mean for yd<0 -0.01681083871697961
Quantiles, Estimate-min, Estimate-max, Actual-mean
< 0.1 63 -0.114204475725 -0.00724506318853 -0.03322429369269691
0.1 - 0.2 62 -0.00713905278312 -0.000506183321433 -0.004907805057147527
0.2 - 0.3 63 -0.000483089674556 0.000297186768394 0.0004448734851063545
0.3 - 0.4 62 0.000311989474656 0.00211104256645 0.004805555688945485
0.4 - 0.5 63 0.00213641473385 0.00332340650492 0.002210626003115094
0.5 - 0.6 62 0.00333448665848 0.00533991360845 0.004500071127566962
0.6 - 0.7 63 0.00534545606738 0.00695710454597 0.009822358485020223
0.7 - 0.8 62 0.0069891435363 0.0124472509797 0.019134586921813922
0.8 - 0.9 63 0.0126979602647 0.0208302638276 0.023301333588047014
>= 0.9 63 0.0208346764742 0.0909801518663 0.03389618960913428
Wir hoffen, dass diese Statistiken mehr oder weniger selbsterklärend sind.
Die darauf folgende Grafik zeigt den Zusammenhang zwischen Schätzung, tatsächlicher Größe und Zahl der Beobachtungen.
Da man in diesem Beispiel eine Schätzung yd>0
(yd<0
) als long-(short-)Signal für den Kauf z.B. eines Futures auf den S&P500 interpretieren kann, sei noch kurz die die folgende Ergebniszeile etwas näher erläutert:
mean for yd>0: 0.013926756505256453 mean for yd<0 -0.01681083871697961
Hier wird der tatsächlich Mittelwert der prozentualen Veränderung für Schätzungen größer als 0 (yd>0
) sowie der tatsächliche Mittelwert für Schätzungen kleiner als 0 (yd<0
) angegeben.
War die Schätzung in der Schätzstichprobe größer als 0, so ist der S&P500 tatsächlich im Schnitt um 1.39% an im nächsten Monat gestiegen. War die Schätzung kleiner als 0 ist er im Schnitt um 1.68% gefallen.
Mit der Evaluierungsstichprobe wird dann das so entstandene Modell auf seine Güte hin überprüft und die Ergebnisse in derselben Form ausgegeben.
Nehmen wir wieder nur die oben erläuterte Zeile:
mean for yd>0: 0.02171763557283458 mean for yd<0 -0.011597131727433194
So erkennt man, dass sich dieses potentiell entscheidungsrelevante Muster in der Evaluierungsstichprobe wiederholt hat.
Es war also tatsächlich möglich, Monate zu identifizieren, in denen der S&P500 im Schnitt um 2.17% steigt bzw. um -1.16% fällt.
Auf Basis des Multiziel-KnowledgeNets lassen sich auch für die anderen Ziele einzelne Modelle berechnen.
Für diese Ziele wird auf eine ausführliche Ausgabe verzichtet und nur eine Auswahl von in-sample und out-of-sample Ergebnissen der Modelle ausgegeben.
Auch für die anderen untersuchten Größen (Aktienindizes, Häuserpreisindizes und Geldmengen) zeigen die Modellergebnisse eine gute Prognosequalität. Bei anderen Aktienindizes ist es ebenfalls möglich Monate zu identifizieren mit im Schnitt negativer Rendite.
Besonders gut lassen sich die prozentualen Veränderungen des Case-Shiller Häuser Preis Index vorhersagen. Hier sind Korrelationen zwischen Schätzung und tatsächlicher Veränderung von über 0.9 möglich.
#Erstellung von Modellen für alle restlichen Ziele auf Basis des Multi-Ziel-Netzes
for aktvar in endo[1:]:
print()
print(aktvar)
aktmodel=Model(['makro_test_0'],"makro_test_0",aktvar,QAb,New_Y=False,Only_mean=False,load_directory="./",compact_output=True)
aktmodel.addmodel(['makro_test_0'],'('+aktvar+')',addtype=2,GlobalRel=0.75,MaxIter=1,AddEst=True)
aktmodel.evalmodel(data)
modellist_1+=[aktmodel]
In der nun folgenden Zelle werden die Einträge im Modell (Objekte und Prognoseheuristiken) für die prozentuale Veränderung des S&P500 sowie des Case-Shiller Index (der 10 größten Städte in den USA) vollständig ausgegeben.
Zusätzlich dazu werden die Ergebnisse der Anwendung dieser Prognoseregeln in Form der Korrelation zwischen Schätzung der zukünftigen monatlichen Veränderung und der tatsächlich eingetretenen Veränderung (in-sample sowie out-of-sample) dargestellt.
# Ausgabe einer Ergebnisszusammenfassung für df.C_SU.pct_change().shift(-1) und df.Case_10.pct_change().shift(-1)
for j in [0,9]:
a=modellist_1[j]
print("#################################")
print(endo[j])
print("#################################")
for i in np.arange(len(a.LawList[0].obj)):
# Index, In-sample Korrelation, Out-of-sample Korrelation nach Anwendung der Prognosregel, Emergentes Gesetz gilt weiter
print(i+1,a.LawList[0].R_S[i],a.LawList[0].R_E[i],a.LawList[0].Verified[i])
display(a.LawList[0].obj[i])
display(a.LawList[0].heuristic[i])
print()
Anhand des ersten Eintrags in der Ausgabe soll die Bedeutung etwas genauer erklärt werden:
df.C_SU.pct_change().shift(-1)
1 0.42199383427 0.514982776096 True
'~((((categorize(df.Case_home.pct_change().rolling(window=16).mean(),3)==1.0)&(categorize(df.Case_home.pct_change().rolling(window=16).std(),3)==2.0))|(categorize(df.Case_10.pct_change().rolling(window=36).mean(),1)==0.0)))'
'estkq_eval((y-yd).loc[obj],df.C_KDAX.pct_change().rolling(window=1).mean().loc[obj],44,False,0.00636628374218,0.0,0.493132859707,Series(0,index=y.loc[obj].index,dtype=np.float64),Series(0,index=y.loc[obj].index,dtype=np.float64),eval_string)'
Zunächst wird das Ziel ausgegeben (df.C_SU.pct_change().shift(-1)
) - hier die prozentuale Veränderung des S&P500 im nächsten Monat.
Anschließend wird die Indexnummer des Gesetzes (1
), die in-sample Korrelation (0.4219
) und die out-of-sample Korrelation (0.5149
) gezeigt, die bei Anwendung der ersten Prognoseregel entsteht.
In den nachfolgenden beiden Zeilen werden das Objekt und die Prognoseheuristik ausgegeben, die zur Prognose verwendet werden.
Das Objekt wählt den Anwendungsbereich (also die Monate) aus, bei denen dann mithilfe der angegeben Prognoseheuristik eine Schätzung getroffen wird.
In diesem Fall wählt das Objekt Monate, anhand des Case-Shiller Home Prize Index aus.
Konkret werden Beobachtungen ausgewählt, bei denen der rollierende 16-Monats Mittelwert der prozentualen Veränderung des Case-Shiller Home Price Index nicht im expandierenden 0%-33% der Quantile der 16-Monats-Mittelwerte lag. Außerdem lag auch die rollierende 16-Monats-Standardabweichung nicht im expandierenden 33%-66% Quantil der Standardabweichungen.
Die Prognoseheuristik ist eine expandierende kleinste-Quadrate lineare Regression mit der prozentualen Veränderung des KDAX (Kurs-DAX) des vorigen Monats als Regressor.
In diesem Fall beträgt der Steigungskoeffizient der Regression 0.493132859707, d.h. für jedes zusätzliche Prozent der Veränderung des KDAX, steigt die Prognose für die prozentuale Veränderung des S&P500 um 0.49%.
Wird diese Prognoseheuristik für die ausgewählten Monate angewendet, ergibt sich eine in-sample Korrelation von 0.4219
der Schätzung mit der tatsächlichen prozentualen Veränderung des S&P500. Out-of-sample beträgt die Korrelation sogar 0.5149
.
Die nachfolgende Ausgabe zeigt die Ergebnisse für die restlichen Ziele, beschränkt sich aber auf die in-sample bzw. out-of-sample Korrelation nach Anwendung der jeweiligen Prognoseregeln im Modell.
# Ausgabe einer zusammengefassten Ergebnisszusammenfassung für die restlichen Ziele
for j in [j for j in np.arange(len(endo)) if j not in [0,9]]:
a=modellist_1[j]
if len(a.LawList[0])>0:
print("#################################")
print(endo[j])
print("#################################")
for i in np.arange(len(a.LawList[0].obj)):
# Index, In-sample Korrelation, Out-of-sample Korrelation nach Anwendung der Prognosregel, Emergentes Gesetz gilt weiter
print(i+1,a.LawList[0].R_S[i],a.LawList[0].R_E[i],a.LawList[0].Verified[i])
print()
Bereits diese kleine Auswahl von Indizes (Aktien und Häuserpreise) und unterschiedlichen Geldmengenaggregaten zeigt sehr interessante Ergebnisse.
Für die korrekte Interpretation ist sicherlich noch eine tiefere Erklärung der einzelnen Schritte und Ergebnisse notwendig. Unsere Erfahrungen in Lehrveranstaltungen zeigen aber, dass bereits nach kurzer Einübung der Begriffe und Anleitungen zur richtigen Interpretation der Ergebnisse, interessante und entscheidungsrelevante Ergebnisse abgeleitet werden können.
Wie gezeigt können die erstellten Modelle direkt zur Ableitung von Entscheidungsregeln verwendet werden. Auch eine Erweiterung auf Sektorprognosen z.B. für Ratingsysteme oder detailliertere Prognosen für Investitionsentscheidungen (bzw. Asset-Allocation) auf dem Aktienmarkt sind ohne weiteres möglich.
Bald werden wir überprüfen, ob weitere Größen (wie z.B. Zinssätze auf dem Kapitalmarkt, Arbeitslosenzahlen usw.) die Prognosequalität noch weiter verbessern und die möglichen Anwendungsgebiete erweitern.
Außerdem scheint es uns sehr hilfreich emergente Gesetze über Gesamtwirtschaftliche Zusammenhänge im Rahmen von Lehrveranstaltungen zur Darstellungen von empirischen Zusammenhängen zu verwenden.
Unter den angegebenen E-Mail Adressen können Sie bei Fragen oder Anmerkungen gerne mit uns Kontakt aufnehmen.