Aprendizaje automático en el trading: teoría, práctica, operaciones y más - página 136

 

¿Y cómo se calcula exactamente R^2, qué función?

Intenté entrenar diferentes modelos a través de rattle, contó "pseudo r^2" a través de la correlación, es decir cor(fitpoints[,1], fitpoints[,2])^2, pero quiero calcular r^2 usando el mismo método que hiciste para comparar.

¿Funcionará este código [1 - suma((y-x)^2)/suma((y-media(y))^2)]?

 
Dr.Trader:

¿Y cómo se calcula exactamente R^2, qué función?

Intenté entrenar diferentes modelos a través de rattle, contó "pseudo r^2" a través de la correlación, es decir cor(fitpoints[,1], fitpoints[,2])^2, pero quiero calcular r^2 usando el mismo método que hiciste para comparar.

¿Funcionará este código [1 - suma((y-x)^2)/suma((y-media(y))^2)]?


Exactamente. X es un modelo.

 
Dr.Trader:

Cuantas más neuronas haya en la capa oculta, más compleja será la función que pueda describir la neurona, por lo que se necesitan más capas ocultas y neuronas en ellas.

Pero entonces el problema será que la neurona utiliza sumas y multiplicaciones consecutivas (y por ejemplo sigmoides para la función de activación) para describir el objetivo, es decir, obviamente no obtendrás tu función original, sino algún tipo de aproximación. Y puede resultar que esta aproximación recuerde algunas características de los datos de entrenamiento, por lo que no funcionará correctamente con los nuevos datos. Así que a veces hay que dejar de entrenar, ver si el error en la muestra de prueba ha disminuido, y seguir entrenando si todo va bien. En algún momento el error en los datos de prueba comenzará a crecer, entonces el entrenamiento debe ser detenido por completo.

Además, la salida de una neurona-clave está limitada por la función de activación. Para popular - sigmoide es (0;1), relu es [0;inf). Los valores objetivo deben ser escalados a un intervalo diferente, sus salidas en el intervalo (-7;7) son simplemente inalcanzables para muchos paquetes.

Escalo todos los datos con cf 0 st.off 1.

es posible apuntar a -1;1. Pero esto sólo es realmente necesario si la neurona de salida tiene una activación tangente.

0:;1 para la sigmoidea en un caso similar.

Pero hay que tener en cuenta el alcance real de los datos. Los pesos pueden no saturar hasta ese nivel.

Y estoy aprendiendo con las curvas de salida en trayne y probar y ver donde parar.
 

Una vez más tomó rattle, entrenado nnet, tomó el código terminado del registro. Rattle no funciona del todo bien con nnet, he añadido algo más de código para detener el entrenamiento a tiempo.

La mejor R^2 en los nuevos datos = 0,18. La mejor configuración de la red resultó bastante divertida, con una neurona en la única capa interna. Podría tener dos neuronas más en la capa interna, sería casi el mismo resultado. Si seguimos aumentando el número de neuronas, el gráfico sugiere que la red se reentrena muy rápidamente y rinde cada vez menos con los nuevos datos.

En el gráfico de la derecha, la línea azul son los nuevos datos del modelo, a partir de la línea 20001. El resto es formación y validación cruzada.

La red convolucional parece estar a la cabeza.

Archivos adjuntos:
 
Dr.Trader:

Una vez más tomó rattle, entrenado nnet, tomó el código terminado del registro. Rattle no funciona del todo bien con nnet, he añadido algo más de código para detener el entrenamiento a tiempo.

La mejor R^2 en los nuevos datos = 0,18. La mejor configuración de la red resultó bastante graciosa, con una neurona en la única capa interna. Podría tener dos neuronas más en la capa interna, sería casi el mismo resultado. Si seguimos aumentando el número de neuronas, el gráfico muestra que la red se reentrena muy rápidamente y rinde cada vez peor con los nuevos datos.

En el gráfico de la derecha, la línea azul son los nuevos datos del modelo, a partir de la línea 20001. El resto es formación y validación cruzada.

La red convolucional parece estar a la cabeza.

El resultado es bueno. Enhorabuena, has superado mi simple NS.

¿Preparaste las patatas fritas o las alimentaste tal y como están rezagadas? Parece que este problema no puede resolverse con puros rezagos. Es necesario preparar las fichas.

Otra observación - parece que la salida de su red es estrictamente -1;1. O bien tomó una activación tangente y luego no convirtió la salida de nuevo, o algo más.

Y sólo como referencia. Red convergente (aprendizaje profundo) en el paquete mxnet. Hasta ahora la versión es sólo con git. Pero lo básico funciona.
 
Alexey Burnakov:

Y sólo como referencia. Red convergente (aprendizaje profundo) en el paquete mxnet. Hasta ahora la versión con git solamente. Pero básicamente todo funciona.

sólo una observación, fuera de tema pero.... cuando pedí ayuda con mxnet y señalé el paquete mxnet, todo el mundo se quedó callado y no dijo nada. ahora todo el mundo se interesa de repente por lo que dije hace 50 páginas, ¿por qué ocurre esto? :) Me pregunto si después de 100 páginas alguien se dará cuenta del paquete quantstrat al que también presté atención hace tiempo....

Dirás - ja, bueno, ve y hazlo tú mismo si eres tan inteligente, el hecho es que yo no lo soy y no soy inteligente y no entiendo mucho y el inglés también es muy pobre y tus cuatro líneas de código con explicaciones para mí podrían tomar semanas para hacerlo bien, e incluso entonces no siempre lo logro ...

 
mytarmailS:

sólo una observación, fuera de tema pero.... cuando pedí ayuda con la red de convolución y señalé el paquete mxnet, todo el mundo se quedó callado y no dijo nada. ahora todo el mundo se interesa de repente por lo que yo hablaba hace 50 páginas, ¿por qué ocurre esto? :) Me pregunto si después de 100 páginas alguien se dará cuenta del paquete quantstrat al que también presté atención hace tiempo....

Dirás - ja, bueno, ve y hazlo tú mismo si eres tan inteligente, el hecho es que yo no lo soy y no soy inteligente y no entiendo mucho y el inglés también es muy pobre y tus cuatro líneas de código con explicaciones para mí podría tomar semanas para hacerlo bien, e incluso entonces no siempre lo logro ...

Un gran comentario, colega. ) Ha

Permítanme responder punto por punto según mi visión:

1) El 90% de la gente se mueve por el interés propio, la fase de pensamiento y la fase experimental. Por lo tanto, algunas buenas ideas se dejan de lado durante mucho tiempo. Como no has aportado ningún ejemplo ni reto interesante, a nadie le interesa. Simple, ¿no?

2) Hay dos estrategias para adquirir conocimientos: indagar y tratar de hacer algo agónicamente (todos lo hacemos en diferente medida. Por ejemplo, recuerdo al tipo del hilo "¡Aprended a ganar, aldeanos!", que se pasó varios años de su vida probando la viabilidad de los Asesores Expertos disponibles. Y todos fracasaron). Otra opción - esperar con la esperanza de que alguien ayude y publique uno ya hecho. Por lo tanto, si ha elegido la segunda estrategia debido a sus circunstancias, el período de espera para un EA listo puede ser muy largo.

Respecto a mxnet, ya que estoy metido en el tema, no me importa colgar el código, que por cierto, es casi el mismo en Internet:

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)

Naturalmente, es sólo un pez que muestra la lógica básica.

 
Alexey Burnakov:
¿Las fichas estaban preparadas o se alimentaban como los rezagos? Parece que esta tarea no puede resolverse con puro retraso. Es necesario preparar las fichas.

Otra observación - parece que su salida neta es estrictamente -1;1. O bien tomó la activación de la tangente y luego no hizo la conversión de la salida inversa, o algo más.

Alimenté todo como está en el original, sin cambios. Estoy seguro de que podría haber obtenido un mejor resultado si hubiera calculado los valores de los indicadores correctos y los hubiera utilizado también para la predicción. Pero, ¿cuáles son los indicadores correctos? (pregunta retórica, sin respuesta).

Todo lo que tiene de divertido es "-1;1" en la respuesta. La salida en la última neurona es lineal allí, sin función de activación, es decir, no está limitada por nada. También he probado a escalar los valores objetivo en -1;1, pero después la red empieza a dar resultados en el rango (-0,2;0,2). Por alguna razón los resultados siempre estarán en un rango más estrecho que el requerido, probablemente debido a un aprendizaje rápidamente detenido, con sólo 250 iteraciones.
Si añadimos más neuronas y no dejamos de aprender, al final la red aprenderá la invariante correcta. 100 neuronas en la capa interna es casi suficiente para una precisión del 100% en los datos de entrenamiento. Según el registro, la suma de los residuos en todos los resultados de 20000*0,7 (corregidos posteriormente) fue de alrededor de 200. Pero en este caso los resultados de la validación cruzada dejarán de estar correlacionados en absoluto con los necesarios, serán sólo valores aleatorios, aunque en el intervalo necesario.

 
Dr.Trader:

Presenté todo como está en el original, sin ningún cambio. Estoy seguro de que calculando los valores de los indicadores correctos y utilizándolos también para la predicción, podría obtener un mejor resultado. Pero, ¿cuáles son los indicadores correctos? (pregunta retórica, aún no hay respuesta).

Sobre el "-1;1" en la respuesta, es todo gracioso. La salida de la última neurona es lineal, sin función de activación, es decir, no está limitada por nada. Intenté escalar los valores objetivo también en -1;1, pero después la red empieza a dar resultados en el rango (-0,2;0,2). Por alguna razón los resultados siempre estarán en un rango más estrecho que el requerido, probablemente debido a un aprendizaje rápidamente detenido, con sólo 250 iteraciones.
Si añadimos más neuronas y no dejamos de aprender, al final la red aprenderá la invariante correcta. 100 neuronas en la capa interna es casi suficiente para una precisión del 100% en los datos de entrenamiento. Según el registro, la suma de los residuos de los 20000*100 predictores fue de alrededor de 200. Pero los resultados de la validación cruzada no se correlacionarán en absoluto, sólo serán valores aleatorios, aunque en un intervalo requerido.

Es curioso. Tendré que pensarlo.

HH: lo más probable es que en este rango [-1;1] , la red obtenga las señales más consistentes en la entrada y este fragmento de la función sea el más fácil de modelar (NS aprende lo más fácil). Y, por supuesto, esta variante cuando el descenso del gradiente encuentra su mínimo. Es difícil discutir eso...

Bien, añadiré una pista para ti si todavía quieres practicar.

En primer lugar, R^2 0,55 se puede conseguir realmente aplicando alguna pequeña transformación funcional a la "metafunción". Otra cosa es que la función resulte un poco complicada en apariencia.

Además, trata de tomar:

rowMeans(df[, 1:10])

rowMeans(df[, 1:20])

rowMeans(df[, 1:30])

...

rowMeans(df[, 1:100])

Estas 10 metafichas contienen la combinación deseada de entradas significativas.

Por cierto, las capas convolucionales permiten detectarlo ya en el proceso de aprendizaje, si se sabe dónde escarbar.

En realidad, el motivo por el que le insto es que, aunque sepa a qué corresponde el mapa, debe esforzarse por reproducir la aproximación de la salida. Y como persona de dentro no me gusta la sensación de intentar vender a la gente un problema irresoluble.

 
Alexey Burnakov:

Un gran comentario, colega. ) Ha

Permítanme responder punto por punto según mi visión:

Te comprendo, esperaba una respuesta más dura, gracias por no pegar)) y gracias también por el código, intentaré solucionarlo el fin de semana, ya que ahora mismo estoy ocupado con otra idea....

Necesito ayuda...

Quiero hacer una prueba de cointegración en deslizamiento pero arroja un error...

aquí hay una prueba sencilla con datos estáticos...


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

funciona...

Pero cuando hago lo mismo en una ventana deslizante, obtengo un error -Error en lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :

0 casos (no NA)

prueba de la ventana deslizante

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
                
}

en stack overflow en problemas similares dice que se debe a "NA" en los datos pero yo no lo tengo, eso es seguro...

¿cuál es el problema? por favor, ayuda

Razón de la queja: