Aprendizado de máquina no trading: teoria, prática, negociação e não só - página 136

 

E como se calcula exactamente R^2, que função?

Eu tentei treinar modelos diferentes através de guizo, contou "pseudo r^2" através de correlação, nomeadamente cor(fitpoints[,1], fitpoints[,2])^2, mas eu quero calcular r^2 usando o mesmo método que você usou para a comparação.

Este código [1 - sum((y-x)^2)/sum((y-mean(y))^2)] vai funcionar?

 
Dr. Trader:

E como se calcula exactamente R^2, que função?

Eu tentei treinar modelos diferentes através de guizo, contou "pseudo r^2" através de correlação, nomeadamente cor(fitpoints[,1], fitpoints[,2])^2, mas eu quero calcular r^2 usando o mesmo método que você usou para a comparação.

Este código [1 - sum((y-x)^2)/sum((y-mean(y))^2)] vai funcionar?


Exactamente. X é um modelo.

 
Dr. Trader:

Quanto mais neurônios na camada oculta - a função mais complexa pode ser descrita pelo neurônio, você precisa de mais camadas e neurônios escondidos neles.

Mas então o problema será que o neurônio usa adições e multiplicações consecutivas (e por exemplo sigmóides para a função de ativação) para descrever o alvo, ou seja, você obviamente não terá sua função original, mas algum tipo de aproximação. E pode acontecer que esta aproximação se lembre de algumas características nos dados de treinamento, por isso não funcionará corretamente com novos dados. Portanto, às vezes você precisa parar o treinamento, ver se o erro na amostra de teste diminuiu, e continuar o treinamento se tudo estiver bem. Em algum momento o erro nos dados de teste começará a crescer, então o treinamento deve ser completamente interrompido.

Além disso, a saída de um neurônio é limitada pela função de ativação. Para popular - sigmoid é (0;1), relu é [0;inf). Os valores alvo precisam ser escalados para um intervalo diferente, seus outputs no intervalo (-7;7) são simplesmente inalcançáveis para muitos pacotes.

Eu escalo todos os dados com cf 0 st.off 1.

é possível atingir -1;1. Mas isto só é realmente necessário se o neurónio de saída tiver uma activação tangente.

0:;1 para sigmoid num caso semelhante.

E se há lá uma identidade, não é preciso. Mas é preciso ter em conta o intervalo de dados real. Os pesos podem não se saturar a esse nível.

E eu estou aprendendo com curvas de saída no tabuleiro e teste e veja onde parar.
 

Mais uma vez pegou o guizo, treinado nnet, tirou o código acabado do tronco. O Rattle não funciona bem com o nnet, acrescentei mais algum código para parar o treino a tempo.

Melhor R^2 em novos dados = 0,18. A melhor configuração de rede saiu bem engraçada, com um neurônio na única camada interna. Eu poderia ter mais dois neurónios na camada interior, seria mais ou menos o mesmo resultado. Se continuarmos a aumentar o número de neurónios, o gráfico sugere que a rede se retrai muito rapidamente e tem um desempenho cada vez menos bom em novos dados.

No gráfico da direita, a linha azul é um novo dado para o modelo, da linha 20001. O resto é treinamento e validação cruzada.

A rede convolucional parece estar na liderança.

Arquivos anexados:
 
Dr.Trader:

Mais uma vez pegou o guizo, treinado nnet, tirou o código acabado do tronco. O Rattle não funciona bem com o nnet, acrescentei mais algum código para parar o treino a tempo.

Melhor R^2 em novos dados = 0,18. A melhor configuração de rede saiu bem engraçada, com um neurônio na única camada interna. Eu poderia ter mais dois neurónios na camada interior, seria mais ou menos o mesmo resultado. Se continuarmos aumentando o número de neurônios, o gráfico mostra que a rede se retrai muito rapidamente e tem um desempenho cada vez pior em relação aos novos dados.

No gráfico da direita, a linha azul é um novo dado para o modelo, da linha 20001. O resto é treinamento e validação cruzada.

A rede convolucional parece estar na liderança.

O resultado é bom! Parabéns, você venceu a minha simples NS.

Preparaste as batatas fritas ou alimentaste-as quando estavam atrasadas? Parece que este problema não pode ser resolvido com puros desfasamentos. A preparação das fichas é necessária.

Outra observação - parece que a saída da sua rede é estritamente -1;1. Ou você tomou uma ativação tangente e depois não converteu a saída de volta, ou outra coisa qualquer.

E só para referência. Rede convergente (aprendizagem profunda) no pacote mxnet. Até agora a versão está apenas com o git. Mas as coisas básicas funcionam.
 
Alexey Burnakov:

E só para referência. Rede convergente (aprendizagem profunda) no pacote mxnet. Até agora, a versão só com o git. Mas, no fundo, tudo funciona.

apenas uma observação, fora do tópico mas.... Quando pedi ajuda com o mxnet e apontei para o pacote mxnet, todos ficaram calados e não disseram nada. agora todos estão de repente interessados no que eu disse sobre isso 50 páginas atrás, por que isso está acontecendo? :) Será que depois de 100 páginas alguém vai notar o pacote quantstrat, ao qual também prestei atenção há muito tempo atrás....

Você vai dizer - ha, bem, vá e faça você mesmo se você é tão inteligente, o fato é que eu não sou e eu não sou inteligente e eu não entendo muito e Inglês também é muito pobre e suas quatro linhas de código com explicações para mim poderia levar semanas para acertar, e mesmo assim nem sempre eu consigo ...

 
mytarmailS:

apenas uma observação, fora do tópico, mas.... quando eu pedi ajuda com a rede de convolução e apontei o pacote mxnet, todos ficaram calados e não disseram nada. agora todos estão de repente interessados no que eu estava falando há 50 páginas atrás, por que isso está acontecendo? :) Será que depois de 100 páginas alguém vai notar o pacote quantstrat, ao qual também prestei atenção há muito tempo atrás....

Você vai dizer - ha, bem, vá e faça você mesmo se você é tão inteligente, o fato é que eu não sou e eu não sou inteligente e eu não entendo muito e Inglês também é muito pobre e suas quatro linhas de código com explicações para mim poderia levar semanas para acertar, e mesmo assim nem sempre eu consigo ...

Só um grande comentário, colega! ) Ha

Deixa-me responder ponto por ponto, de acordo com a minha visão:

1) 90% das pessoas aqui são movidas pelo interesse próprio, a fase de pensamento e a fase experimental. Portanto, algumas boas ideias são postas de lado durante muito tempo. Como você não forneceu nenhum exemplo interessante e desafios, ninguém está interessado. Simples, não é?

2) Existem duas estratégias para obter conhecimento: cavar e tentar fazer algo de forma agonizante (todos nós o fazemos de forma diferente. Por exemplo, lembro-me do tipo do tópico "Learn to Earn, Villagers!" que passou vários anos da sua vida a testar a trabalhabilidade dos Expert Advisors disponíveis. E todos eles falharam). Outra opção - esperar na esperança de que alguém ajude e poste uma já feita. Portanto, se você escolheu a segunda estratégia devido às suas circunstâncias, o período de espera para uma EA pronta pode ser muito longo.

Em relação à mxnet, já que estou nessa, não me importo de colocar o código, que, por sinal, é quase o mesmo na 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, é apenas um peixe a mostrar a lógica básica.

 
Alexey Burnakov:
As batatas fritas foram preparadas ou foram alimentadas como se estivessem atrasadas? Esta tarefa não pode ser resolvida com puro atraso, ao que parece. A preparação de batatas fritas é necessária.

Outra observação - parece que sua saída líquida é estritamente -1;1. Ou você tomou ativação tangente e depois não fez conversão reversa de saída, ou algo mais.

Eu alimentei tudo como está no original, sem alterações. Tenho a certeza que poderia ter obtido um resultado melhor, se tivesse calculado os valores dos indicadores correctos e os tivesse utilizado também para a previsão. Mas quais são os indicadores certos? (pergunta retórica, sem resposta).

Tudo é engraçado sobre "-1;1" na resposta. A saída no último neurônio é linear ali, sem função de ativação, ou seja, não é limitada por nada. Também tentei escalar os valores alvo em -1;1, mas depois disso a rede começa a dar resultados no intervalo (-0.2;0.2). Por alguma razão os resultados estarão sempre num intervalo mais estreito do que o necessário, provavelmente devido à rápida interrupção da aprendizagem, com apenas 250 iterações.
Se adicionarmos mais neurónios e não pararmos de aprender, então no final a rede aprenderá o invariante certo. 100 neurónios na camada interior é quase suficiente para uma precisão de 100% nos dados de treino. De acordo com o log, a soma dos resíduos em todos os 20000*0,7 (corrigidos mais tarde) resultados foi de cerca de 200. Mas, neste caso, os resultados da validação cruzada deixarão de estar correlacionados com os necessários, serão apenas valores aleatórios, embora no intervalo necessário.

 
Dr. Trader:

Eu submeti tudo como está no original, sem quaisquer alterações. Estou certo de que, calculando os valores dos indicadores correctos e utilizando-os também para a previsão, eu poderia obter um resultado melhor. Mas quais são os indicadores certos? (pergunta retórica, ainda sem resposta).

Sobre o "-1;1" na resposta, é tudo engraçado. A saída no último neurônio lá é linear, sem função de ativação, ou seja, não limitada por nada. Tentei escalar os valores alvo também em -1;1, mas depois disso a rede começa a produzir resultados no intervalo (-0.2;0.2). Por alguma razão os resultados estarão sempre num intervalo mais estreito do que o necessário, provavelmente devido à rápida interrupção da aprendizagem, com apenas 250 iterações.
Se adicionarmos mais neurónios e não pararmos de aprender, então no final a rede aprenderá o invariante certo. 100 neurónios na camada interior é quase suficiente para uma precisão de 100% nos dados de treino. De acordo com o registro, a soma dos resíduos em todos os preditores de 20000*100 foi de cerca de 200. Mas os resultados da validação cruzada não se correlacionarão de forma alguma, serão apenas valores aleatórios, embora num intervalo necessário.

Isso é engraçado. Vou ter de pensar nisso.

HH: muito provavelmente, neste intervalo [-1;1] , a rede recebe os sinais mais consistentes na entrada e este fragmento da função é o mais fácil de modelar (NS aprende o que é mais fácil). E, é claro, esta variante quando a descida de gradiente encontra o seu mínimo. É difícil argumentar com isso...

Está bem, vou acrescentar uma dica para ti se ainda quiseres praticar.

Primeiro, R^2 0,55 pode realmente ser alcançado aplicando alguma pequena transformação funcional à "metafunção". Outra coisa é que a função acaba por ser um pouco complicada na aparência.

Tente também levar:

rowMeans(df[, 1:10])

rowMeans(df[, 1:20])

rowMeans(df[, 1:30])

...

rowMeans(df[, 1:100])

Estas 10 metafichas contêm a combinação desejada de entradas significativas.

A propósito, camadas convolutivas permitem escolhê-lo já no processo de aprendizagem, se você souber onde cavar.

Porque estou a pedir, na verdade - mesmo que saibas o que mapear, deves esforçar-te por reproduzir a aproximação de saída. E como infiltrado não gosto da sensação de tentar vender às pessoas um problema insolúvel.

 
Alexey Burnakov:

Só um grande comentário, colega! ) Ha

Permita-me responder ponto por ponto, de acordo com a minha visão:

Eu entendo você, eu estava esperando uma resposta mais dura, obrigado por não bater))) e obrigado também pelo código, vou tentar resolver isso no fim de semana, pois estou ocupado com outra idéia agora....

Preciso de ajuda...

Eu quero fazer um teste de cointegração no deslizamento, mas ele lança um erro...

aqui está um teste simples sobre dados 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...

Mas quando faço o mesmo numa janela deslizante, recebo um erro -Erro em lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :

0 casos (não N/A)

teste de janela 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
                
}

no excesso de pilha em problemas semelhantes diz que é devido a "NA" nos dados, mas eu não o tenho , isso é certo...

Qual é o problema? Por favor, ajude.

Razão: