/// <summary> /// Treina as redes de captação necessárias para identificar a melhor rede para cada um dos dias de previsao /// Por exemplo: se forem permitidos 30 dias de previsao, teremos 30 redes para cada papel /// </summary> /// <param name="configuracaoCaptacao"></param> internal static void Treinar(ConfiguracaoCaptacaoRedes configuracaoCaptacao) { //Seleciona os treinamentos por dia de previsao, sendo o input os dados de entrada da rede de previsao financeira e como saida, //a taxa de acerto de cada uma das redes executadas em cada dia de previsao //OBS: A taxa de acerto da rede por dia é alimentada Dictionary<int, TrainingSet> treinamentosPorDia = SelecionarTreinamentosPorDia(configuracaoCaptacao);//dadosTreinamentoPorShift, configuracaoCaptacao.RedesPrevisao); GerarRelatorioCrossOver(String.Format("{0}_{1}_{2}", Directory.GetFiles(diretorioRelatorioCrossOver).Count() + 1, configuracaoCaptacao.Papel, DateTime.Now.ToString().Replace("/", "_").Replace(":", "_".Replace(" ", ""))), configuracaoCaptacao.RedesPrevisao); //foreach (KeyValuePair<int, TrainingSet> treinamento in treinamentosPorDia) //{ // string nomeRede = CaptacaoMelhoresRedesRN.RecuperarNomeRede(configuracaoCaptacao.Papel, treinamento.Key); // TreinarRedeDiaria(nomeRede, treinamento.Value); //} int numeroProcessadores = 4; for (int indTrein = 0; indTrein < treinamentosPorDia.Count; indTrein += numeroProcessadores) { Thread[] threads = new Thread[numeroProcessadores]; for (int indProcessador = 0; indProcessador < numeroProcessadores; indProcessador++) { if (treinamentosPorDia.Count - (indTrein + indProcessador) <= 0) continue; string nomeRede = CaptacaoMelhoresRedesRN.RecuperarNomeRede(configuracaoCaptacao.Papel, indTrein + indProcessador); TrainingSet ts = treinamentosPorDia[indTrein + indProcessador]; threads[indProcessador] = new Thread(() => TreinarRedeDiaria(nomeRede, ts));//[indTrein + indProcessador]; threads[indProcessador].Start(); } for (int indProcessador = 0; indProcessador < numeroProcessadores; indProcessador++) { if (threads[indProcessador] != null) threads[indProcessador].Join(); } } }
public void TreinarRedesCaptacao() { string papel = "PETR4"; //Lista todas as configurações de rede para o papel List<string> redes = RedeNeural_PrevisaoFinanceira.RNAssessor.ListarRedes(papel); ConfiguracaoCaptacaoRedes configuracaoCaptacao = new ConfiguracaoCaptacaoRedes(); //Recupera os dados do papel List<DadosBE> dadosBE = DataBaseUtils.DataBaseUtils.RecuperarCotacoesAtivo(papel); configuracaoCaptacao.Dados = DataBaseUtils.DataBaseUtils.NormalizarDados(dadosBE.Select(dadoBE => (double)dadoBE.PrecoAbertura).ToList(), papel); configuracaoCaptacao.Papel = papel; //Adicionar cada uma das redes ao treinamento de captação foreach (string nomeRede in redes) { //Network redeNeuralPrevisaoFinanceira = RedeNeural_PrevisaoFinanceira.RNAssessor.RecuperarRedeNeural(nomeRede); RedePrevisaoFinanceira rpf = new RedePrevisaoFinanceira(); rpf.NomeRede = nomeRede; rpf.JanelaEntrada = Convert.ToInt32(nomeRede.Split(new string[] { "_je", "_js" }, StringSplitOptions.RemoveEmptyEntries)[1]); rpf.JanelaSaida = Convert.ToInt32(nomeRede.Split(new string[] { "_js", "_nn" }, StringSplitOptions.RemoveEmptyEntries)[1]); rpf.RedeNeuralPrevisaoFinanceiraPorDivisaoCrossValidation = RedeNeural_PrevisaoFinanceira.RNAssessor.RecuperarRedesNeuraisAgrupadasPorConfiguracao(nomeRede); ; configuracaoCaptacao.RedesPrevisao.Add(rpf); } //Treina a rede de captação para a identificação da melhor dere por dia para o papel CaptacaoMelhoresRedesRN.Treinar(configuracaoCaptacao); }
/// <summary> /// Roda as redes para cada um dos treinamentos, separando os treinamentos por dia /// Calcula também a taxa média de acerto de cada rede neural por dia /// </summary> /// <param name="dadosTreinamento"></param> /// <param name="redesPrevisaoFinanceira"></param> /// <returns></returns> private static Dictionary<int, TrainingSet> SelecionarTreinamentosPorDia(ConfiguracaoCaptacaoRedes configuracaoCaptacao) { int tamanhoEntrada = configuracaoCaptacao.RedesPrevisao.Max(rp => rp.JanelaEntrada); List<Treinamento> treinamentos = DataBaseUtils.DataBaseUtils.SelecionarTreinamentos(configuracaoCaptacao.Dados, tamanhoEntrada, totalDiasPrevisao, 2); //Dictionary<int, Dictionary<List<double>, List<double>>> dadosTreinamentoPorShift = new Dictionary<int, Dictionary<List<double>, List<double>>>(); ////Resgata o maior tamanho das entradas das redes neurais ////Cria o dicionario de input output por shift //for (int numShift = 0; numShift < quantidadeShifts; numShift++) //{ // //Seleciona oa dados antes do shift // dadosTreinamentoPorShift.Add(numShift, SelecionarInput_Output(configuracaoCaptacao.Dados.Take((configuracaoCaptacao.Dados.Count / (quantidadeShifts - 1)) * numShift).ToList(), tamanhoEntrada)); // //Seleciona os dados depois do shift // dadosTreinamentoPorShift[numShift].ToList().AddRange(SelecionarInput_Output(configuracaoCaptacao.Dados.Skip((configuracaoCaptacao.Dados.Count / (quantidadeShifts - 1)) * (numShift + 1)).ToList(), tamanhoEntrada)); //} //Inicializa todos os dias da previsao for (int diaTreinamento = 0; diaTreinamento < totalDiasPrevisao; diaTreinamento++) { foreach (RedePrevisaoFinanceira redePrevisao in configuracaoCaptacao.RedesPrevisao) { redePrevisao.TaxaMediaAcertoPorDia.Add(diaTreinamento, 0); } } Dictionary<int, TrainingSet> treinamentosPorDia = new Dictionary<int, TrainingSet>(); for (int dia = 0; dia < totalDiasPrevisao; dia++) { treinamentosPorDia.Add(dia, new TrainingSet(tamanhoEntrada, configuracaoCaptacao.RedesPrevisao.Count)); } //Roda as redes para cada um dos dados de treinamento selecionados foreach (Treinamento treinamento in treinamentos) { //Guarda um historico dos outputs das redes para tratar as redes que tem output menor do que o tamanho da previsao List<List<double>> outputsRedes = new List<List<double>>(); List<double[]> taxasAcertoRedes = new List<double[]>(); foreach (RedePrevisaoFinanceira redePrevisao in configuracaoCaptacao.RedesPrevisao) { Network redeNeural = redePrevisao.RedeNeuralPrevisaoFinanceiraPorDivisaoCrossValidation[treinamento.DivisaoCrossValidation]; //Roda a rede neural, gerando a previsao \/ como a rede pode receber um input menor do que os treinamentos, pegamos apenas os ultimos registros do mesmo double[] outputPrevisao = redeNeural.Run(treinamento.Input.Skip(treinamento.Input.Count - redePrevisao.JanelaEntrada).Take(redePrevisao.JanelaEntrada).ToArray()); //Alimenta o historico de previsoes de cada rede outputsRedes.Add(outputPrevisao.ToList()); double[] taxaAcertoPorDia = new double[totalDiasPrevisao]; for (int diasPrevistosRN = 0; diasPrevistosRN < outputPrevisao.Length; diasPrevistosRN++) { //Calcula a taxa de acerto da previsao double ta = Math.Min(outputPrevisao[diasPrevistosRN], treinamento.Output[diasPrevistosRN]) / Math.Max(outputPrevisao[diasPrevistosRN], treinamento.Output[diasPrevistosRN]); taxaAcertoPorDia[diasPrevistosRN] = ta; redePrevisao.TaxaMediaAcertoPorDia[diasPrevistosRN] += ta; } taxasAcertoRedes.Add(taxaAcertoPorDia); } //Lista com o melhor desultado de cada dia (cada item da lista corresponde a um dia..) List<double> melhoresResultadosDia = new List<double>(treinamento.Input); //Trata as taxas de acerto que não foram calculadas pois a rede tem output menor do que a quantidade de dias da previsao for (int dia = 1; dia < totalDiasPrevisao; dia++) { //Recupera o indice da rede que tem a melhor taxa de acerto para o dia anterior int indMelhorRedeParaODiaAnterior = taxasAcertoRedes.IndexOf(taxasAcertoRedes.OrderByDescending(taxasAcertoRede => taxasAcertoRede[dia - 1]).First()); //Adiciona o melhor resultado a lista de melhores resultados melhoresResultadosDia.Add(outputsRedes[indMelhorRedeParaODiaAnterior][dia - 1]); for (int indRede = 0; indRede < configuracaoCaptacao.RedesPrevisao.Count; indRede++) { //Verifica se a taxa de acerto do dia para a rede ja foi calculada if (taxasAcertoRedes[indRede][dia] == 0) { //Ultiliza os ultimos melhores dados para fazer uma nova previsao double[] inputRede = melhoresResultadosDia.Skip(melhoresResultadosDia.Count - configuracaoCaptacao.RedesPrevisao[indRede].JanelaEntrada).Take(configuracaoCaptacao.RedesPrevisao[indRede].JanelaEntrada).ToArray(); double[] outputRede = configuracaoCaptacao.RedesPrevisao[indRede].RedeNeuralPrevisaoFinanceiraPorDivisaoCrossValidation[treinamento.DivisaoCrossValidation].Run(inputRede); //Adiciona o dia previsto na lista de outputs outputsRedes[indRede].Add(outputRede.Last()); //Calcula a taxa de acerto da previsao double ta = Math.Min(outputRede.Last(), treinamento.Output[dia]) / Math.Max(outputRede.Last(), treinamento.Output[dia]); //Adiciona a taxa de acerto da rede para o dia taxasAcertoRedes[indRede][dia] = ta; //Atualiza a taxa de acerto da rede configuracaoCaptacao.RedesPrevisao[indRede].TaxaMediaAcertoPorDia[dia] += ta; } } } for (int dia = 0; dia < totalDiasPrevisao; dia++) { double[] outputCaptacao = new double[configuracaoCaptacao.RedesPrevisao.Count]; for (int indRede = 0; indRede < configuracaoCaptacao.RedesPrevisao.Count; indRede++) { outputCaptacao[indRede] = taxasAcertoRedes[indRede][dia]; } TrainingSample ts = new TrainingSample(treinamento.Input.ToArray(), outputCaptacao); treinamentosPorDia[dia].Add(ts); } } //Divide a taxa de acerto pela quantidade de treinamentos para saber a taxa média foreach (RedePrevisaoFinanceira redePrevisao in configuracaoCaptacao.RedesPrevisao) { for (int i = 0; i < totalDiasPrevisao; i++) { redePrevisao.TaxaMediaAcertoPorDia[i] /= treinamentos.Count; } } return treinamentosPorDia; }