Maschinelles Lernen im Handel: Theorie, Modelle, Praxis und Algo-Trading - Seite 136

 

Und wie genau berechnet man R^2, welche Funktion?

Ich habe versucht, verschiedene Modelle durch Rattle zu trainieren, es zählte "pseudo r^2" durch Korrelation, nämlich cor(fitpoints[,1], fitpoints[,2])^2, aber ich möchte r^2 mit der gleichen Methode berechnen, wie Sie es für den Vergleich getan haben.

Wird dieser Code [1 - sum((y-x)^2)/sum((y-mean(y))^2)] funktionieren?

 
Dr. Trader:

Und wie genau berechnet man R^2, welche Funktion?

Ich habe versucht, verschiedene Modelle durch Rattle zu trainieren, es zählte "pseudo r^2" durch Korrelation, nämlich cor(fitpoints[,1], fitpoints[,2])^2, aber ich möchte r^2 mit der gleichen Methode berechnen, wie Sie es für den Vergleich getan haben.

Wird dieser Code [1 - sum((y-x)^2)/sum((y-mean(y))^2)] funktionieren?


Ganz genau. X ist ein Modell.

 
Dr. Trader:

Je mehr Neuronen in der versteckten Schicht - desto komplexere Funktionen kann das Neuron beschreiben, man braucht mehr versteckte Schichten und Neuronen darin.

Das Problem ist dann aber, dass das Neuron aufeinanderfolgende Additionen und Multiplikationen (und z.B. Sigmoide für die Aktivierungsfunktion) verwendet, um das Ziel zu beschreiben, d.h. es wird offensichtlich nicht Ihre Originalfunktion sein, sondern eine Art Annäherung. Und es kann sich herausstellen, dass sich diese Annäherung an einige Merkmale in den Trainingsdaten erinnert, so dass sie mit neuen Daten nicht korrekt funktioniert. Manchmal muss man also das Training abbrechen, um zu sehen, ob der Fehler in der Testprobe zurückgegangen ist, und das Training fortsetzen, wenn alles in Ordnung ist. Irgendwann beginnen die Fehler bei den Testdaten zu wachsen, dann muss das Training komplett eingestellt werden.

Außerdem wird die Ausgabe eines Neurons durch die Aktivierungsfunktion begrenzt. Für popular - sigmoid ist (0;1), relu ist [0;inf). Die Zielwerte müssen auf ein anderes Intervall skaliert werden, Ihre Ausgaben im Intervall (-7;7) sind für viele Pakete einfach unerreichbar.

Ich skaliere alle Daten mit cf 0 st.off 1.

ist es möglich, das Ziel -1;1 zu erreichen. Dies ist jedoch nur erforderlich, wenn das Ausgangsneuron eine tangentiale Aktivierung hat.

0:;1 für sigmoid in einem ähnlichen Fall.

Und wenn es eine Identität gibt, muss man das nicht tun, aber man muss die tatsächliche Verbreitung der Daten berücksichtigen. Die Gewichte dürfen nicht in diesem Umfang gesättigt sein.

Und ich lerne mit Leistungskurven auf dem Trayne und teste und sehe, wo ich aufhören muss.
 

Noch einmal rattle genommen, nnet trainiert, den fertigen Code aus dem Protokoll genommen. Rattle funktioniert nicht ganz korrekt mit nnet, ich habe etwas mehr Code hinzugefügt, um das Training rechtzeitig zu stoppen.

Bester R^2 auf neuen Daten = 0,18. Die beste Netzwerkkonfiguration kam ziemlich komisch heraus, mit einem Neuron in der einzigen inneren Schicht. Ich könnte zwei Neuronen mehr in der inneren Schicht haben, das Ergebnis wäre ungefähr dasselbe. Wenn wir die Anzahl der Neuronen weiter erhöhen, deutet das Diagramm darauf hin, dass das Netz sehr schnell umlernt und bei neuen Daten immer weniger gut abschneidet.

Die blaue Linie im rechten Diagramm zeigt die neuen Daten des Modells ab Zeile 20001. Der Rest ist Schulung und Kreuzvalidierung.

Das Faltungsnetz scheint hier die Nase vorn zu haben.

Dateien:
 
Dr.Trader:

Noch einmal rattle genommen, nnet trainiert, den fertigen Code aus dem Protokoll genommen. Rattle funktioniert nicht ganz korrekt mit nnet, ich habe etwas mehr Code hinzugefügt, um das Training rechtzeitig zu stoppen.

Bester R^2 auf neuen Daten = 0,18. Die beste Netzwerkkonfiguration kam ziemlich komisch heraus, mit einem Neuron in der einzigen inneren Schicht. Ich könnte zwei Neuronen mehr in der inneren Schicht haben, das Ergebnis wäre ungefähr dasselbe. Wenn wir die Anzahl der Neuronen weiter erhöhen, zeigt das Diagramm, dass das Netz sehr schnell umlernt und bei neuen Daten immer schlechtere Leistungen erbringt.

Die blaue Linie im rechten Diagramm zeigt die neuen Daten des Modells ab Zeile 20001. Der Rest ist Schulung und Kreuzvalidierung.

Das Faltungsnetz scheint hier die Nase vorn zu haben.

Das Ergebnis ist gut! Glückwunsch, Sie haben meinen einfachen NS geschlagen.

Haben Sie die Pommes frites vorbereitet oder haben Sie sie so gefüttert, wie sie sind? Es scheint, dass dieses Problem nicht mit reinen Verzögerungen gelöst werden kann. Die Späne müssen vorbereitet werden.

Eine weitere Beobachtung - es sieht so aus, als ob die Ausgabe Ihres Netzwerks strikt -1;1 ist. Entweder haben Sie eine Tangentenaktivierung durchgeführt und dann die Ausgabekonvertierung nicht rückgängig gemacht oder etwas anderes.

Und nur zum Vergleich. Konvergentes Netzwerk (Deep Learning) im Paket mxnet. Bislang nur die Version mit Git. Aber die grundlegenden Dinge funktionieren.
 
Alexey Burnakov:

Und nur zum Vergleich. Konvergentes Netzwerk (Deep Learning) im Paket mxnet. Bislang nur die Version mit Git. Aber im Grunde funktioniert alles.

nur eine Beobachtung, die nicht zum Thema gehört, aber.... als ich um hilfe bei mxnet bat und auf das mxnet-paket hinwies, schwiegen alle und sagten nichts. jetzt interessieren sich plötzlich alle für das, was ich vor 50 seiten dazu gesagt habe. warum ist das so? :) Ich frage mich, ob nach 100 Seiten jemandem das Paket quantstrat auffällt, auf das ich auch schon vor langer Zeit geachtet habe....

Sie werden sagen - ha, gut, gehen Sie und machen Sie es selbst, wenn Sie so klug sind, die Tatsache ist, dass ich nicht bin und ich bin nicht klug und ich verstehe nicht viel und Englisch ist auch sehr schlecht und Ihre vier Zeilen Code mit Erklärungen für mich könnte Wochen dauern, um es richtig, und selbst dann nicht immer gelingt es mir ...

 
mytarmailS:

nur eine Beobachtung, die nicht zum Thema gehört, aber.... als ich um hilfe für das faltungsnetzwerk bat und auf das mxnet-paket hinwies, schwiegen alle und sagten nichts. jetzt interessiert sich plötzlich jeder für das, worüber ich vor 50 seiten gesprochen habe. warum ist das so? :) Ich frage mich, ob nach 100 Seiten jemandem das Paket quantstrat auffällt, auf das ich auch vor langer Zeit aufmerksam geworden bin....

Sie werden sagen - ha, gut, gehen Sie und machen Sie es selbst, wenn Sie so klug sind, die Tatsache ist, dass ich nicht bin und ich bin nicht klug und ich verstehe nicht viel und Englisch ist auch sehr schlecht und Ihre vier Zeilen Code mit Erklärungen für mich könnte Wochen dauern, um es richtig, und selbst dann nicht immer gelingt es mir ...

Einfach ein toller Kommentar, Kollege! ) Ha

Lassen Sie mich Punkt für Punkt entsprechend meiner Vision antworten:

1) 90 % der Menschen hier sind vom Eigeninteresse, der Denkphase und der Experimentierphase getrieben. Daher werden einige gute Ideen lange Zeit beiseite gelegt. Da Sie keine interessanten Beispiele und Herausforderungen genannt haben, ist niemand daran interessiert. Einfach, nicht wahr?

2) Es gibt zwei Strategien, um Wissen zu erlangen: das Graben und der quälende Versuch, etwas zu tun (wir alle tun das in unterschiedlichem Ausmaß). Ich erinnere mich zum Beispiel an den Kerl im Thread "Learn to Earn, Villagers!", der mehrere Jahre seines Lebens damit verbrachte, die Funktionsfähigkeit der verfügbaren Expert Advisors zu testen. Und sie sind alle gescheitert). Eine andere Möglichkeit ist es, zu warten und zu hoffen, dass jemand hilft und ein fertiges Exemplar zur Verfügung stellt. Wenn Sie sich also aufgrund Ihrer Umstände für die zweite Strategie entschieden haben, kann die Wartezeit für einen fertigen EA sehr lang sein.

Was mxnet anbelangt, so habe ich nichts dagegen, den Code zu veröffentlichen, der übrigens im Internet fast identisch ist, da ich mich dafür interessiere:

install.packages("drat", repos="https://cran.rstudio.com")
drat::: addRepo("dmlc") 

install.packages("mxnet") 

 

 

train.x = data.matrix(dat_ready_scale[1:(nrow(dat_ready_scale) / 2), 1:100])

train.y = dat_ready_scale[1:(nrow(dat_ready_scale) / 2), 101]

test.x = data.matrix(dat_ready_scale[!rownames(dat_ready_scale) %in% rownames(train.x), 1:100])

test.y = dat_ready_scale[!rownames(dat_ready_scale) %in% rownames(train.x), 101]



########

train.x <- t(train.x)

test.x <- t(test.x)


dim(train.x) <- c(100, 1, 1, ncol(train.x))

dim(test.x) <- c(100, 1, 1, ncol(test.x))

#########



############ BUILD NET


library(mxnet)


# first conv layer


data <- mx.symbol.Variable('data')


conv1 <- mx.symbol.Convolution(data = data,

  kernel=c(14, 1),

  stride=c(1, 1),

  num.filter = 1)


tanh1 <- mx.symbol.Activation(data = conv1, 

 act.type = 'relu')


pool1 <- mx.symbol.Pooling(data = tanh1, 

     pool_type = "avg",

     kernel=c(5, 1), 

     stride=c(1, 1))



# second conv layer


conv2 <- mx.symbol.Convolution(data = conv1,

  kernel=c(12, 1),

  stride=c(1, 1),

  num.filter = 1)


tanh2 <- mx.symbol.Activation(data = conv2, 

 act.type = 'relu')


pool2 <- mx.symbol.Pooling(data = tanh2, 

     pool_type = "avg",

     kernel=c(5, 1), 

     stride=c(1, 1))



# third conv layer


conv3 <- mx.symbol.Convolution(data = conv2,

  kernel=c(10, 1),

  stride=c(1, 1),

  num.filter = 1)


tanh3 <- mx.symbol.Activation(data = conv3, 

 act.type = 'relu')


pool3 <- mx.symbol.Pooling(data = tanh3, 

     pool_type = "avg",

     kernel=c(2, 1), 

     stride=c(1, 1))



# first fully connected layer


flatten <- mx.symbol.Flatten(data = conv3)


fc1 <- mx.symbol.FullyConnected(data = flatten

   , num_hidden = 10)


tanh4 <- mx.symbol.Activation(data = fc1, act.type = 'tanh')



# second fully connected layer


fc2 <- mx.symbol.FullyConnected(data = tanh4, num_hidden = 1)


lenet <- mx.symbol.LinearRegressionOutput(data = fc2)


#### train


device <- mx.cpu()

log <- mx.metric.logger$new()


model <- mx.model.FeedForward.create(lenet, 

 X = train.x,

 y = train.y,

 ctx = device, 

 num.round = 100, 

 array.batch.size = 128,

 learning.rate = 0.01, 

 momentum = 0.9,

 eval.metric = mx.metric.rmse,

 eval.data = list(data = test.x, label = test.y),

 optimizer = 'sgd',

 initializer = mx.init.uniform(0.5),

 #array.layout = 'rowmajor',

 epoch.end.callback = mx.callback.log.train.metric(1, log))


plot(log$train, type = 'l', col = 'blue', ylim = c(min(c(log$train, log$eval)), max(c(log$train, log$eval))))

lines(log$eval, type = 'l', col = 'red')


mx.ctx.internal.default.value = list(device="cpu",device_id=0,device_typeid=1)

class(mx.ctx.internal.default.value) = "MXContext"


preds <- as.numeric(predict(model, test.x))

1 - sum((test.y - preds)^2) / sum((test.y - mean(test.y))^2)

Natürlich ist es nur ein Fisch, der die grundlegende Logik zeigt.

 
Alexey Burnakov:
Wurden die Pommes frites zubereitet oder wurden sie wie Lags gefüttert? Es scheint, dass diese Aufgabe nicht mit reiner Verzögerung gelöst werden kann. Die Vorbereitung der Späne ist notwendig.

Eine weitere Beobachtung - es sieht so aus, als ob Ihre Nettoausgabe strikt -1;1 ist. Entweder haben Sie die Tangentenaktivierung genommen und dann keine umgekehrte Ausgabekonvertierung vorgenommen, oder etwas anderes.

Ich habe alles so eingespeist, wie es im Original steht, keine Änderungen. Ich bin mir sicher, dass ich ein besseres Ergebnis hätte erzielen können, wenn ich die Werte der richtigen Indikatoren berechnet und sie auch für die Vorhersage verwendet hätte. Aber welche sind die richtigen Indikatoren? (rhetorische Frage, keine Antwort).

Alles ist komisch an "-1;1" in der Antwort. Die Ausgabe am letzten Neuron ist dort linear, ohne Aktivierungsfunktion, d.h. sie ist durch nichts begrenzt. Ich habe auch versucht, die Zielwerte im Bereich -1;1 zu skalieren, aber danach beginnt das Netz, Ergebnisse im Bereich (-0,2;0,2) zu liefern. Aus irgendeinem Grund liegen die Ergebnisse immer in einem engeren Bereich als erforderlich, was wahrscheinlich darauf zurückzuführen ist, dass der Lernprozess mit nur 250 Iterationen schnell zum Stillstand kommt.
Wenn wir weitere Neuronen hinzufügen und nicht mit dem Lernen aufhören, wird das Netz am Ende die richtige Invariante lernen. 100 Neuronen in der inneren Schicht reichen fast aus, um eine 100%ige Genauigkeit bei den Trainingsdaten zu erreichen. Dem Protokoll zufolge betrug die Summe der Residuen aller 20000*0,7 (später korrigierten) Ergebnisse etwa 200. Aber in diesem Fall korrelieren die Ergebnisse der Kreuzvalidierung überhaupt nicht mehr mit den benötigten Ergebnissen, sondern sind nur noch zufällige Werte, die allerdings im benötigten Intervall liegen.

 
Dr. Trader:

Ich habe alles so eingereicht, wie es im Original steht, ohne irgendwelche Änderungen. Ich bin mir sicher, dass ich ein besseres Ergebnis erzielen könnte, wenn ich die Werte der richtigen Indikatoren berechne und sie auch für die Vorhersage verwende. Doch welche sind die richtigen Indikatoren? (rhetorische Frage, noch keine Antwort).

Das mit dem "-1;1" in der Antwort ist nur ein Scherz. Die Ausgabe des letzten Neurons dort ist linear, ohne Aktivierungsfunktion, d.h. durch nichts begrenzt. Ich habe versucht, die Zielwerte auch in -1;1 zu skalieren, aber danach beginnt das Netz, Ergebnisse im Bereich (-0,2;0,2) auszugeben. Aus irgendeinem Grund liegen die Ergebnisse immer in einem engeren Bereich als erforderlich, was wahrscheinlich darauf zurückzuführen ist, dass der Lernprozess mit nur 250 Iterationen schnell zum Stillstand kommt.
Wenn wir weitere Neuronen hinzufügen und nicht mit dem Lernen aufhören, wird das Netz am Ende die richtige Invariante lernen. 100 Neuronen in der inneren Schicht reichen fast aus, um eine 100%ige Genauigkeit bei den Trainingsdaten zu erreichen. Die Summe der Residuen für alle 20000*100 Prädiktoren lag laut Protokoll bei 200. Die Ergebnisse der Kreuzvalidierung korrelieren jedoch überhaupt nicht, sondern sind lediglich Zufallswerte, wenn auch in einem bestimmten Intervall.

Das ist witzig. Ich werde darüber nachdenken müssen.

HH: In diesem Bereich [-1;1] erhält das Netz höchstwahrscheinlich die konsistentesten Signale am Eingang, und dieses Fragment der Funktion ist am einfachsten zu modellieren (NS lernt, was am einfachsten ist). Und natürlich diese Variante, wenn der Gradientenabstieg sein Minimum findet. Dagegen lässt sich kaum etwas sagen...

OK, ich gebe Ihnen einen Tipp, wenn Sie noch üben wollen.

Erstens kann R^2 0,55 wirklich durch eine kleine funktionale Transformation der "Metafunktion" erreicht werden. Ein weiterer Punkt ist, dass die Funktion ein wenig kompliziert aussieht.

Versuchen Sie auch zu nehmen:

rowMeans(df[, 1:10])

rowMeans(df[, 1:20])

rowMeans(df[, 1:30])

...

rowMeans(df[, 1:100])

Diese 10 Metafiches enthalten die gewünschte Kombination von sinnvollen Eingaben.

Mit Hilfe von Faltungsschichten lässt sich das übrigens schon während des Lernprozesses herausfinden, wenn man weiß, wo man suchen muss.

Der Grund für meine Aufforderung: Selbst wenn Sie wissen, was Sie abbilden müssen, sollten Sie sich bemühen, die Annäherung an die Ausgabe zu reproduzieren. Und als Insider mag ich das Gefühl nicht, den Leuten ein unlösbares Problem verkaufen zu wollen.

 
Alexey Burnakov:

Einfach ein toller Kommentar, Kollege! ) Ha

Erlauben Sie mir, Punkt für Punkt aus meiner Sicht zu antworten:

Ich verstehe dich, ich hatte eine härtere Antwort erwartet, danke, dass du nicht geschlagen hast))) und danke auch für den Code, ich werde versuchen, ihn am Wochenende auszuarbeiten, da ich gerade mit einer anderen Idee beschäftigt bin....

Brauche etwas Hilfe...

Ich möchte einen Kointegrationstest in Sliding durchführen, aber es wird ein Fehler ausgegeben...

Hier ist ein einfacher Test mit statischen Daten...


library(tseries) 
ri <- cumsum(rnorm(10000))  #  типа цены
si <- cumsum(rnorm(10000))  #  типа цены
ln <- length(ri)

data <- as.data.frame(cbind(ri,si))

#проводим  линейную регрессию для определения правильного соотношения
model <- lm(  ri ~ si + 0 , data)
#вычисляем  разницу цен (спред)
spread <- ri - coef(model)[1] * si
#проводим  тест Дики-Фуллера на стационарность
test <- adf.test(as.vector(spread), k=0)

test$p.value

es funktioniert...

Aber wenn ich dasselbe in einem gleitenden Fenster mache, erhalte ich eine Fehlermeldung -Fehler in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :

0 (nicht-NA) Fälle

Schiebefenstertest

ri <- cumsum(rnorm(10000))  #  типа цены
si <- cumsum(rnorm(10000))  #  типа цены
ln <- length(ri)


data <- as.data.frame(cbind(ri,si))


test_vec <- rep(0,ln) #  тут будем хранить показатели теста 

for(i in 151:ln){
  print(i)
          idx <- (i-150):i
                #проводим  линейную регрессию для определения правильного соотношения
                model <- lm(  ri[idx] ~ si[idx] + 0 , data[idx,])
                #вычисляем  разницу цен (спред)
                spread <- ri[idx] - coef(model)[1] * si[idx]
                #проводим  тест Дики-Фуллера на стационарность
                test <- adf.test(as.vector(spread), k=0)
                
                test_vec[i] <- test$p.value
                
}

auf Stack Overflow in ähnliche Probleme sagt, es ist aufgrund von "NA" in den Daten, aber ich habe es nicht, das ist sicher...

Was ist das Problem? Bitte helfen Sie mir.