estrutura e desenvolvimento do simulador atuarial ... · desenvolvido por eugene a. hammel e...
TRANSCRIPT
Estrutura e desenvolvimento do Simulador Atuarial-Demográfico de
Regimes Próprios de Previdência Social (Sadeprev)
Resumo
Este trabalho apresenta o Simulador Atuarial-Demográfico de Regimes
Próprios de Previdência Social (Sadeprev), um software que utiliza dados e
premissas populacionais para, a partir da microssimulação dos eventos
demográficos que ocorrem na população de servidores municipais e de cálculos
atuariais, projetar a capacidade de solvência de um Regime Próprio de Previdência
Social (RPPS), considerando as contribuições e os benefícios futuros a serem
pagos. Esse software foi desenvolvido na linguagem R, popular nas Ciências
Atuariais e Estatística. Por se tratar de um programa de microssimulação, o
Sadeprev tem uma demanda computacional alta e requer grande tempo de
processamento. O presente trabalho se dedica a apresentar a estrutura
computacional deste programa, assim como a analisar sua eficiência computacional,
comparando-a antes e depois das modificações de implementação do paralelismo,
compilações de funções e vetorização. Os resultados evidenciam um ganho de
eficiência de até 55,2% após essas modificações, sem perda de precisão de
informação ou alteração dos resultados. Esses resultados contribuem tanto para
demonstrar como boas práticas de programação são importantes para resolver
problemas nas mais diferentes áreas de conhecimento, quanto para apresentar a
estrutura de elaboração do Sadeprev, permitindo maior conhecimento sobre esse
software e seu desenvolvimento.
Palavra-chave: Microssimulação, previdência, paralelismo, paradigma.
1. INTRODUÇÃO
No Brasil, a previdência social está estruturada em regimes diferenciados
para servidores públicos e para os demais trabalhadores, os Regimes Próprios de
Previdência Social (RPPS) e o Regime Geral de Previdência Social (RGPS),
respectivamente. Cada ente federativo pode ter um RPPS para seus servidores e,
portanto, casa município e estado pode ter um RPPS. A população coberta pelos
RPPS reflete a população de servidores de cada ente federativo, sendo maior nos
estados e menor nos municípios com pequenas populações.
Atualmente, muito se fala na reestruturação e reforma do regime
previdenciário no Brasil. Com o objetivo de desafogar o sistema geral de
previdência, existem grandes incentivos para a criação e manutenção dos RPPS
(Myrrha & Ojima, 2016). Por outro lado, implantar RPPS em municípios pequenos,
que não possuem capacidade de gestão e orçamentária para uma boa
administração pode ser um grande erro (Myrrha & Ojima, 2016).
Cerca de 60% dos RPPS tem menos de 500 servidores ativos (Corrêa, 2014).
Quanto menor a população, maior a variabilidade aleatória dos eventos
demográficos e maior a possibilidade de observação de valores de eventos mais
distantes dos valores esperados (Corrêa, 2014).
Outro fator que pode levar a resultados distantes dos esperados no estudo
analítico de solvência de um RPPS é a metodologia adotada de cálculo. Além disso,
escolhas indevidas das premissas atuariais, como idade de aposentadoria,
probabilidades de morte e invalidez (refere-se à incapacidade de um servidor realizar
seu trabalho), podem alterar significativamente as projeções para uma mesma
população.
O Sadeprev surge com o objetivo de ser um software para auxiliar na análise
da solvência dos RPPS considerando o tamanho da população e a variabilidade dos
eventos demográficos. Ele se baseia na microssimulação, pela qual cada indivíduo
da população é submetido aos possíveis eventos demográficos ao longo de 75 anos
por um grande número de vezes, o que permite obter uma distribuição de resultados
possíveis. Ao final da simulação, o Sadeprev gera resultados relacionados à
capacidade de solvência do plano, além de propor uma alíquota de risco
demográfico capaz de amortizar o déficit esperado.
Este trabalho mostra o funcionamento como um todo do Sadeprev,
descrevendo as metodologias utilizadas (seção 2), como o programa realiza as
simulações (seção 3) e o paradigma de programação escolhido. Apresenta também
os problemas encontrados durante o desenvolvimento e como cada um dos
problemas foi abordado, mostrando testes e resultados que validaram as soluções
escolhidas (seção 4). Além disso, apresenta exemplos dos dados gerados pelo
resultado da simulação.
2. A MICROSSIMULAÇÃO
De forma genérica, uma simulação computacional consiste em modelar
computacionalmente um “mini-mundo” (abstração do mundo real) onde objetos,
eventos e ambientes do mundo real têm suas características e comportamento
modelados virtualmente (Maia, 2007). A simulação computacional é uma ferramenta
que permite, a diversos profissionais, a possibilidade da observação prévia de
circunstâncias que envolvem seus projetos, através de um ambiente simulado onde
observações e conclusões antecipadas podem ser de grande importância para o
desenvolvimento dos seus trabalhos (Maia, 2007).
Elas possibilitam observar, em poucos minutos, eventos correspondentes a
um longo período de tempo no mundo real. Permitem, ainda, explorar o efeito da
mudança de uma ou mais variáveis no comportamento do sistema, ajudando a
entender a causa de ocorrência de alguns fenômenos, auxiliando no diagnóstico de
problemas e na proposição de medidas de otimização do sistema real (Banks, 1998).
Além disso, por admitirem um grande número de variáveis e estados, as simulações
permitem a análise de problemas complexos, inviáveis ou impossíveis de serem
resolvidos por outros métodos (Vos & Palloni, 1989), tal como neste trabalho.
Os modelos de simulação podem ser classificados em relação ao nível em
que os cálculos são realizados, podendo ser analíticos, de macro, ou de
microssimulações. Pelo modelo analítico, a unidade de cálculo é a população inteira,
sendo esse modelo indicado para situações em que não há mudanças complexas na
estrutura populacional (Vos & Palloni, 1989).
Pela macrossimulação a unidade de cálculo é um grupo populacional, como
um grupo etário ou de raça, ou um indivíduo médio representativo deste grupo (Vos
& Palloni, 1989). Os cálculos são feitos grupo a grupo e a cada período de tempo
(por exemplo, um ano) até completar todo o período de análise, utilizando, em geral,
taxas de transição entre os estados. Dessa forma, não importa quantas vezes o
experimento é repetido, o resultado da simulação sempre será o mesmo se as taxas
de transição aplicadas se mantêm. Pode-se dizer, portanto, que macrossimulações
são modelos determinísticos (Vos & Palloni, 1989).
Pela microssimulação a unidade de cálculo é o indivíduo (Vos & Palloni,
1989). Por esses modelos constroem-se histórias individuais, avaliando a ocorrência
ou não dos eventos de forma aleatória a cada período de tempo para cada indivíduo
(Vos & Palloni, 1989; Zhao, 2006). Após cada um dos indivíduos serem expostos
aos eventos demográficos, passa-se ao tempo de simulação seguinte e o processo é
repetido. As repetições serão tantas quanto for a quantidade de períodos desejado
para a projeção. Ao final, a população resultante equivale à população projetada
com todas suas características, como composição etária, relações de parentesco e
sexo (Mason, 2010; Zhao, 2006). Como a ocorrência ou não dos eventos é aleatória,
cada rodada da microssimulação pode ter um resultado diferente, podendo, portanto,
ser chamada de estocástica (Mason, 2010; Vos & Palloni, 1989; Zhao, 2006).
Uma vantagem da microssimulação é que ela permite obter projeções para a
população final e para as populações em períodos de tempo intermediários,
acompanhando a evolução da população desde seu início até o fim do período
projetado, podendo também ser utilizada para indicar os efeitos líquidos das
mudanças das taxas demográficas, o que seria difícil ou impossível pelos modelos
analíticos (Zhao, 2006). Além disso, por armazenar dados individuais, permite
analisar a variabilidade e distribuição de probabilidade dos eventos na população de
interesse, o que não seria possível pela macrossimulação.
Para a análise de microssimulações é comum o uso do método de Monte
Carlo (Mason, 2010; Vos & Palloni, 1989; Zhao, 2006), como feito neste trabalho,
que se baseia em repetições de amostragem aleatórias um número elevado de
vezes para a estimação de uma distribuição de interesse (Hromkovič, 2003). Por
esse método são feitas várias amostragens aleatórias da população inicial. As
simulações são, então, realizadas para essas amostragens de população e os
resultados são armazenados. Como o número de repetições é grande, pode-se, por
esses resultados, fazer inferências sobre a distribuição do parâmetro de interesse
e suas probabilidades (Banks, 1998; Hromkovič, 2003; Souza, 2012). Esse método é
útil quando a função de interesse é complexa e não é possível estimar
analiticamente a distribuição (Banks, 1998; Hromkovič, 2003; Souza, 2012), como no
caso dos planos previdenciários”.
A aplicabilidade da microssimulação abrange áreas como a biologia,
demografia e arquitetura, entre outras. Um exemplo está no trabalho de MALUCELLI
(2013), que mostra um planejamento feito para a Avenida Manual Ribas, no
município de Campo Magro, região metropolitana de Curitiba, frente ao crescimento
acelerado do tráfego de veículos. O estudo e o planejamento das reformas
necessárias para a avenida foram feitos com base em uma microssimulação
computacional do tráfego naquela localidade. A utilização de uma simulação deste
tipo pode agregar alguns valores ao projeto como um todo, diminuindo alguns
custos, tempo de análise, entre outros fatores que existiriam nesta fase de estudos e
início de desenvolvimento da reforma, em relação à análise feita com a observação
do tráfego real, por exemplo.
Existem programas desenvolvidos especificamente para a resolução de
problemas por microssimulação populacional, como o Socsim, o Camsim e o
Sadeprev, sendo este último o objeto principal deste artigo. Apesar de ter em comum
o uso da metodologia de microssimulação, cada software tem particularidades em
seus objetivos. O Socsim (Social Simulation) e o Camsim (Cambridge Simulation)
têm o objetivo de projetar ou retroprojetar redes familiares para um conjunto de
funções de fecundidade, mortalidade e nupcialidade. Originalmente o Socsim foi
desenvolvido por Eugene A. Hammel e Kenneth Wachter, em 1960, em Berkeley,
California. O Camsim foi um projeto baseado no Socsim, desenvolvido por Laslett,
James Smith e Jim Oeppen, como projeto de pesquisa na Universidade do Sul da
Califórnia, entre os anos de 1980 e 1984.
O Sadeprev, único representante brasileiro dos citados aqui, também projeta
uma população, mas a população de servidores de planos de RPPS para projetar
seus recursos disponíveis e compromissos futuros assumidos pelo RPPS, e, por
isso, não se ocupa das relações de parentesco entre os indivíduos iniciais. Ele foi
criado a partir do projeto “Desenvolvendo a gestão de RPPS: Um programa para
auxílio dos gestores de previdência de servidores públicos”, um projeto de extensão
liderado pela professora Cristiane Corrêa, na Universidade Federal do Rio Grande
do Norte, em Natal.
Com objetivos diferentes, cada programa tem também uma forma diferente de
simulação. No caso do Socsim, a simulação começa gerando uma população de
indivíduos não relacionados como uma amostra de uma população real de um país
em um determinado momento. Então, eventos demográficos (casamento, morte,
maternidade, entre outros) são criados para cada indivíduo no decorrer do tempo de
simulação e de acordo com suas respectivas probabilidades de ocorrência. Os
eventos demográficos continuam acontecendo no decorrer do tempo até o final do
período determinado na simulação. Todos os eventos e indivíduos são registrados
durante a simulação e qualquer indivíduo pode ser selecionado como uma
referência, e as informações sobre a estrutura familiar deste podem ser observadas.
O Camsim começa sua simulação com uma pessoa de referência, esta
pessoa também é referida como um “ego” e tratada como a figura central em seu
conjunto de parentesco. Então, o sistema simula todos os eventos demográficos que
o ego pode experimentar, como o casamento, a maternidade e a morte. Após a
construção da história demográfica do ego, o sistema usa um procedimento
semelhante para simular seus parentes (se houver). O tipo e o número de parentes a
serem simulados são controlados por parâmetros de entrada e podem ser alterados
de acordo com a finalidade da investigação. Quando a simulação do primeiro ego e
seu conjunto de parentesco é finalizada, o sistema coloca os registros em
armazenamento e começa a simular o segundo ego e seu conjunto de parentesco.
Este procedimento pode ser repetido até que o número de egos necessário seja
cumprido. No caso do Camsim, os egos simulados podem ser considerados como
uma amostra de indivíduos não relacionados. Na população simulada, os parentes
do ego estão relacionados uns aos outros por definição, mas eles não se ligam a
nenhum indivíduo que pertence ao conjunto de parentesco de qualquer outro ego.
Se os egos simulados (ou pessoas selecionadas de acordo com outros critérios) são
vistos como cabeças de linhagem e seus descendentes como membros da
linhagem, então a população simulada pode ser considerada como uma amostra de
linhagens não relacionadas. Consequentemente, pode-se sugerir que a simulação
Camsim usa uma abordagem "genealógica" ou "egocêntrica".
No caso do Sadeprev, a população inicial retrata a população dos
contribuintes e beneficiários de um RPPS com o detalhe da possibilidade desta
população ser real (dados reais dos servidores) ou gerada hipoteticamente.
Informações como idade, sexo, salário e situação no RPPS (ativo, aposentado,
inválido, cônjuge pensionista ou filho pensionista) são requeridas. O indivíduo é
submetido a um fluxo de mudanças de estados, onde a cada momento de mudança
(dependendo da idade e do sexo do indivíduo) é feito um sorteio aleatório baseado
no teste de Bernoulli para determinar o próximo estado. Consideram-se aleatórias
simultaneamente as premissas de morte, invalidez, probabilidade de ter cônjuge e
filho, e idade do cônjuge e do filho. Assim, o Sadeprev simula a população segurada
do RPPS a cada tempo por 75 anos. O interesse é em estimar pagamentos de
benefícios e contribuições, portanto, as relações de parentesco iniciais não foram
consideradas.
Uma questão importante nas simulações destes softwares é o momento em
que é simulado um casamento entre indivíduos da população. No Socsim, acontece
de forma simples, a partir do instante de tempo que o indivíduo está programado
para se casar, o sistema escolhe um indivíduo existente da população. No Camsim e
no Sadeprev, um cônjuge com certas características é gerado e adicionado à
população existente pelo sistema quando ele ou ela é necessário.
Como exemplo de um software que utiliza microssimulação, porém com
outras finalidades e em outra área, diferente dos já mostrados aqui, o AimSun é um
software Brasileiro desenvolvido e mantido pela empresa Fratar, empresa
especializada em estudos de Engenharia de Tráfego, Transportes, Pedestres e
Logística, que utiliza ferramentas analíticas e de microssimulação em seus estudos.
O Aimsun tem como possibilidades principais a análise de tráfego e transporte,
realizando o estudo da capacidade de rodovias, plano de mobilidade e otimização
semafórica, pesquisa de tráfego, consultoria logística e fluxo de multidões.
Pode-se perceber, portanto, que a microssimulação é uma ferramenta com
grande diversidade de aplicações e que cada programa se dedica a resolver um tipo
de problema específico. Percebe-se, também, que a forma de construção de cada
algoritmo pode acarretar vantagens ou desvantagens metodológicas na resolução de
cada problema, sendo, portanto, relevante à compreensão desses algoritmos para a
análise dos resultados dele provenientes. Nesse sentido, a próxima seção de dedica
à análise mais detalhada do funcionamento do Sadeprev.
3. SADEPREV E AS METODOLOGIAS EMPREGADAS
3.1. Estrutura do Sadeprev
O Sadeprev é um software livre que tem como área de atuação o Regime
Próprio de Previdência Social (RPPS), que são as previdências de servidores
públicos municipais. A licença do software está registrada em nome da Universidade
Federal do Rio Grande do Norte e permite que ele seja modificado por
colaboradores em parceria com a instituição.
O Sadeprev é um software desktop (softwares executados localmente em
computadores, que não são para dispositivos móveis ou sistemas web),
desenvolvido na linguagem R, utilizando bibliotecas existentes no CRAN (repositório
público de pacotes/bibliotecas para a linguagem R), além do framework Shiny para
construção de uma interface visual com o usuário.
As simulações realizadas pelo software dependem da qualidade dos dados
referente aos indivíduos de uma população. Atualmente o Sadeprev importa essas
informações por meio de arquivos no formato .xls ou .csv. Os resultados, que são
gerados localmente (na máquina em que o programa foi executado) estão também
nestes formatos e no formato de imagem (.bmp e .jpg).
3.2. O paradigma de programação
Um paradigma de programação define a forma como um programa vai ser
modelado e codificado. A escolha da linguagem de programação leva em
consideração também o paradigma aceito. Essa escolha vai depender tanto de qual
paradigma se adequa melhor a situação real que será modela computacionalmente,
quanto por fatores tecnológicos e técnicos (Tucker & Nooman, 2009). Atualmente
são mais comumente utilizados para o desenvolvimento de software em geral dois
paradigmas de programação, o imperativo e o orientado a objeto. Existe também a
possibilidade do uso de mais de um paradigma em linguagens multiparadigma.
O paradigma orientado a objeto é um paradigma que, além de definir a forma
do código se construir, é um modelo de análise e projeto de um sistema de software.
Isso significa que antes da codificação, na fase de modelagem e projeto, o
paradigma já começa a ser utilizado a partir de ferramentas e linguagens como a
UML (Linguagem Universal de Modelagem), que modela o programa em um nível
mais abstrato, sem códigos, através de diagramas e com uma forma de pensar mais
próxima do mundo real (Tucker & Nooman, 2009).
Apesar de suportado, a sintaxe para o uso do paradigma orientado a objetos
na linguagem R, diferente de linguagens orientadas a objeto, é um pouco confusa e
pouco legível, por vezes parecendo uma “gambiarra”1. Além disso, o R não
implementa alguns conceitos essenciais para o desenvolvimento orientado a objeto,
como os conceitos de interface, sobrescrita de métodos e encapsulamento. Talvez
sejam estes alguns dos motivos de não encontrarmos muitas implementações de
programas R neste paradigma.
O paradigma imperativo descreve a computação como ações que mudam o
estado do programa. Estas ações são definidas na forma de funções que são
chamadas durante o programa, com o objetivo principal de manipular variáveis,
mudando o estado destas e, consequentemente, do programa (Tucker & Nooman,
2009). Este é um paradigma que tem sua origem com a origem da computação. Por
ser um paradigma antigo, é talvez o paradigma mais bem difundido e estabelecido
no mundo da computação. Tem um entendimento simples e um desenvolvimento
mais rápido, que não requer tanta modelagem prévia do software.
O Sadeprev foi desenvolvido em R, linguagem classificada como
multiparadigma, mas com a grande maioria das bibliotecas e dos programas
construídos no paradigma imperativo. A exemplo da maioria das aplicações em R, o
Sadeprev foi desenvolvido sob o paradigma imperativo, o qual se aproxima mais da
estrutura de equações e resoluções de problemas matemáticos e funções
estatísticas, largamente utilizados nestas áreas.
3.3. A simulação no Sadeprev
O Sadeprev simula uma população fechada, o que significa que esta
população não admite entrada de novos servidores (Corrêa, 2014), logo, quando um
servidor passa para a situação de inatividade, a população não é reposta com um
servidor ativo. Este modelo de população reflete uma situação de extinção de um
RPPS e é o modelo utilizado, em geral, nas avaliações atuariais (Corrêa, 2014).
No Sadeprev as simulações podem ser realizadas com dados de uma
população real ou uma população fictícia gerada. Se é necessário gerar uma
população fictícia, a população inicial é gerada com 500 servidores (para o caso de 1 termo usado na computação que significa que determinado trecho de código parece ser feito de uma forma menos formal e adequada, como se o programador desse um “jeitinho” para que o código funcionasse, não utilizando boas práticas.
uma população fictícia). São considerados os seguintes dados para a população:
sexo, idade, remuneração, data de nascimento, situação no RPPS (ativo,
aposentado, inválido ou pensionista), data de ingresso no ente federativo. Os dados
para simulação com populações fictícias são gerados por meio de funções que
“sorteiam” as informações considerando o perfil dos servidores municipais na
população brasileira estimado previamente por Corrêa (2014).
Construída a população ou a partir dos dados de uma população real, os
indivíduos são submetidos aos eventos demográficos. Considerando a população de
ativos, a entrada nessa população se dá pela posse de cargo efetivo no serviço
público e a saída se dá por morte, invalidez ou aposentadoria programada.
Considerando a população de inativos, a entrada nessa população se dá por
aposentadoria ou invalidez, ou por morte do titular, no caso de cônjuge ou filho
dependentes, enquanto a saída se dá por morte ou por sobrevivência até os 21
anos, se filho dependente.
Na microssimulação os eventos demográficos são experimentados
individualmente, embora sejam modelados por uma distribuição de probabilidade
coletiva. Os indivíduos iniciais podem estar na condição de ativo, inválido,
aposentado ou pensionista. Se um indivíduo inicia sua “jornada” na simulação como
“Ativo”, se mantém neste estado por um tempo até sua morte, invalidez, ou
aposentadoria.
Durante a sua execução, o Sadeprev manipula algumas matrizes (estrutura
de dados para armazenamento de varias informações). Essas matrizes armazenam
os dados da população e dados referentes ao plano, e estarão sujeitas a
modificações em função dos acontecimentos demográficos ao longo do tempo, e de
cálculos sobre as mesmas. Na microssimulação, como são realizadas várias
rodadas de simulações, uma das dimensões de cada matriz é o número de rodadas
e a outra é o tempo, que se refere ao tempo em anos a partir do início da simulação
até o limite fixado em 75 anos. Além disso, nas duas primeiras matrizes elaboradas
se armazenam as informações de cada indivíduo, sendo o número do indivíduo uma
terceira dimensão dessas matrizes.
Para a execução do software, primeiramente estima-se a idade mínima de
elegibilidade à aposentadoria. Depois, sorteia-se aleatoriamente o tempo até a sua
morte ou invalidez com probabilidade de saída definida por uma tabela de múltiplos
decrementos para estas duas causas. Para o armazenamento desta informação,
temos a matriz “estados do servidor”, que tem três dimensões (tamanho da
população X tempo X rodadas). Para cada posição da matriz temos o estado de um
indivíduo no RPPS em função do tempo. O tempo de contribuição (tempo em que o
servidor se encontra no estado “ativo”) de cada indivíduo é sorteado previamente.
No decorrer da simulação, a partir do momento em que um indivíduo atinge o fim do
tempo de atividade, se o tempo até a aposentadoria for menor que o tempo até
morte ou invalidez, o indivíduo se aposenta. Caso contrário, um novo sorteio
acontece para decidir se ele estará invalido ou morto. Para os casos de
aposentadoria ou invalidez é estimado um tempo aleatório até a morte com base em
uma tabela de vida.
No momento da morte, mais um sorteio é realizado, a fim de saber se o
indivíduo deixou dependente (cônjuge ou filhos) ou não. Para o caso de deixar
dependentes, é gerada uma idade aleatória e um tempo aleatória até a morte para
os dependentes, os quais recebem benefício até o momento da morte, se cônjuge,
ou até os 21 anos, se filho. Se o servidor não deixou dependente, ao fim do
recebimento de benefício pelos cônjuges e filhos, não haverá mais pagamento de
benefício pelo plano.
A análise do número ou percentual de indivíduos a cada estado permite
análises do perfil populacional dos participantes do plano a cada tempo. O Gráfico 1
apresenta o número médio de servidores em cada estado a cada tempo de
simulação para um universo de 500 servidores iniciais. Nota-se que no tempo t=0 há
cerca de 250 servidores ativos, 130 aposentados, além de inválidos e cônjuges e
filhos beneficiários. Com o passar do tempo diminui a quantidade de ativos, já que a
população é fechada e não há reposição, mas aumenta a quantidade de
beneficiários em cada categoria. Contudo, com a morte desses o número de
indivíduos em cada categoria de benefício diminui até chegar a praticamente zero
após os 75 anos de simulação. Uma vez que trata-se de um programa de
microssimulação, a cada simulação observa-se um número de indivíduos diferentes
em cada estado. Pode-se, portanto, estimar o desvio padrão do número de
indivíduos em cada estado para cada plano e tempo.
Gráfico 1. Número médio de servidores por estado a cada tempo.
No intervalo de tempo em que o servidor está ativo, o RPPS recebe as suas
contribuições, e em contrapartida, paga os benefícios no intervalo de tempo em que
o individuo está aposentado ou invalido, até o ano de sua morte. Esses dados são
armazenados na matriz “benefícios e salários de contribuição do servidor”, também
com três dimensões (tamanho da população X tempo X rodadas), armazena os
valores dos pagamentos ao longo do tempo, podendo ser positivo ou negativo,
representando uma contribuição ou um benefício previdenciário. Utilizando essa
matriz, todos os valores dos pagamentos da população são somados, gerando as
matrizes “benefícios pagos pelo plano” e “salários de contribuição do plano”, com
duas dimensões (tempo x rodadas), que representam o montante de pagamentos da
população a cada tempo e rodada.
Com o fim do ciclo de eventos demográficos, aos quais os indivíduos são
submetidos, o Sadeprev continua a manipular outras matrizes importantes para a
construção dos resultados finais. As matrizes “valor presente de benefício futuro” e
“valor presente do salário de contribuição futura” são bidimensionais (tempo X
rodadas) e são resultado das duas primeiras. De acordo com o estado do servidor e
do valor que cada indivíduo contribui para o fundo ou recebe de benefício em um
determinado momento do tempo, podemos somar todos estes valores, a cada tempo
e rodada, obtendo a matriz chamada “BeneficioPagoPlano”, que se refere aos
valores calculados através da matriz de pagamentos de benefícios ao longo do
tempo, e a matriz “SalarioContribuicao”, onde são guardados os valores de salários
de contribuições totais de todos os servidores do plano a cada tempo e rodada.
A soma desses valores são, então, levados a valores presentes atuais,
descontando-se, para cada valor, a taxa de juros daquele período com o objetivo de
se ter o valor do pagamento, que foi feito em momento tempo futuro, no momento
inicial, os chamados Valores Presentes dos Salários de Contribuição Futuros e
Valores Presentes dos Benefícios Futuros.
A alíquota sugerida é calculada de forma que, aplicada ao valor presente dos
salários de contribuição futuro, mais o fundo inicial, sejam suficientes para cobrir o
valor presente dos benefícios futuros. Para cada rodada é estimada uma alíquota de
equilíbrio atuarial, as quais são armazenadas em um vetor. Porém, para todo plano
utiliza-se a alíquota média entre as alíquotas estimadas em cada rodada.
Na visão prospectiva, a soma das contribuições passadas menos os
benefícios passados em valores atuarias a cada tempo t é o Fundo do RPPS, ou
seja, o valor que o RPPS tem em ativos a cada tempo. A matriz chamada “Fundo”,
gerada através da função “estimaFundo”, contém duas dimensões (tempo x
rodadas). Esta matriz se baseia em toda movimentação feita com os recursos do
plano durante o tempo. Ele é composto pelas contribuições anteriores menos os
benefícios pagos acrescido dos retornos dos investimentos realizados.
Ao final dos 75 anos, se o fundo estiver equilibrado, seu valor deve,
idealmente ser zero, significando que não faltou nem sobrou recursos no plano. Se o
fundo é negativo, assume-se que há déficit financeiro, e, caso seja positivo, há
superávit financeiro, indicando que naquele ano há mais recursos disponíveis que o
necessário. Exemplos destes dois cenários são apresentados na Figura 1, que
demonstra o valor do Fundo RPPS de um RPPS fictício no decorrer do tempo com
uma alíquota fictícia praticada pelo RPPS. O eixo horizontal representa o tempo, que
varia de 0 a 75 anos após o início das projeções. O eixo vertical representa o valor
monetário do fundo em reais. A linha preta contínua representa o valor médio
estimado que o Fundo irá assumir a cada tempo. O Sadeprev, contudo, não avalia
apenas o valor médio, mas também a variação das funções demográficas a ser
observada, qual a variabilidade de cada resultado em torno do valor médio e as
probabilidades associadas a cada resultado. As linhas azuis representam os valores
máximos e mínimos a serem observados com 95% de probabilidade, ou seja,
espera-se que, a cada 100 planos como o simulado, mantidas as condições pré-
estabelecidas, em 95 deles observe-se os valores de Fundo contidos entre as linhas
azuis tracejadas. As linhas amarelas pontilhadas, por sua vez, indicam os valores
extremos estimados pelo Sadeprev, que acontecem com pequena probabilidade.
Figura 1 – Valor médio, intervalo de confiança de 95% e valores extremos simulados para fundo com Déficit e com Superávit após 75 anos.
Além do fundo com a atual alíquota do RPPS, o Sadeprev também estima o
fundo futuro com alíquota sugerida, que representa os valores esperados do
fundo, em cada tempo t, com a adoção da alíquota ou do fundo sugeridos pelo
Sadeprev. Ele mostra o comportamento desejado dos recursos do fundo do plano
em cada momento do tempo t, pois ele representa o comportamento de um plano
equilibrado. Ao final dos pagamentos das obrigações futuras, o valor do fundo tende
a zero, como mostra a Figura 2.
Figura 2 – Valor médio, intervalo de confiança de 95% e valores extremos simulados em milhões de reais, para o fundo com alíquota sugerida
a cada tempo.
De forma retrospectiva, a soma dos benefícios futuros menos as contribuições
futuras em valores atuarias a cada tempo t é a Reserva do RPPS, que é o montante
correspondente aos encargos acumulados, destinados a pagamentos de benefícios
que seriam necessários para cobrir os benefícios futuros.
A matriz “Reserva” que representa a reserva matemática, também tem duas
dimensões (tempo x rodada) e representa o valor que o plano deveria ter no fundo
em determinado momento do tempo para cobrir os benefícios futuros.
Idealmente, deveríamos observar valores iguais nas matrizes “Fundo” e
“Reserva, o que caracteriza o equilíbrio atuarial. Para facilitar a análise dos valores
observados em relação aos que se deveria observar, foi criada a matriz Diferença,
que expressa a diferença Fundo – Reserva. A matriz “diferença” é uma matriz de
duas dimensões (tempo x rodada). Caso o plano esteja em equilíbrio o valor no final
do período deve ser zero, podendo variar nos períodos anteriores. Valores positivos
da Matriz Diferença representam superávit, enquanto os negativos identificam os
déficits atuariais
O Sadeprev gera vários resultados relacionados à saúde financeira e atuarial
do RPPS. Após a microssimulação, as matrizes citadas neste processo são
utilizadas para alguns cálculos que geram novas matrizes e vetores, como os
valores do VaR, CVaR, entre outras medidas de solvência.
4. DESAFIOS DO DESENVOLVIMENTO DO SADEPREV
Durante o desenvolvimento do Sadeprev foi necessário definir soluções para
limitações de memória e tempo de execução.
A linguagem R estabelece um limite na alocação memória (R Core Team,
2017c), ou seja, qualquer variável instanciada não pode ocupar um espaço maior
que o espaço determinado pela função “memory.limit()”. O tamanho de memória
alocável depende da arquitetura do hardware da máquina, do sistema operacional
sobre o qual o programa R está sendo executado e da compilação (versão) do R (R
Core Team, 2017c).
Na implementação do Sadeprev, a função que continha os algoritmos de
simulação e cálculos atuariais retornava uma lista de dados que extrapolava o limite
máximo de espaço alocável para um objeto. Entre as soluções possíveis verificamos
a possibilidade de utilizar pacotes como “ff” (Adler, Gläser, Nenadic, Oehlschlägel, &
Zucchini, 2014), “bigmemory” (Kane, Emerson, Haverty, & Jr, 2016) ou “SOAR”
(Venables & Brahm, 2013), que economizam memória RAM, arquivando parte dos
dados no disco (HD). Este processo é feito através de um algoritmo parecido com a
paginação (Tanenbaum, 2009), realizada pelos sistemas operacionais, processo no
qual usa-se o disco (HD) como uma extensão da memória RAM. Porém, manipular
dados no disco é um processo mais custoso que manipular dados em memória RAM
(Tanenbaum, 2009), e, ao verificar se o desempenho do programa, constatamos que
o tempo de processamento dessas soluções para memória era alto e inviabilizava o
procedimento.
Para solucionar este problema, dividimos as simulações em blocos. Por
exemplo, se antes fazíamos 1.000 rodadas de simulação e tínhamos como retorno
uma lista que extrapolava o limite de memória, decidimos dividir as 1.000 rodadas
por 20, executando os blocos de 50 simulações separadamente e tendo como
retorno uma lista de dados menor a cada rodada. Assim, trabalhamos com as
matrizes por partes. Além disso, para evitar problemas de baixa memória disponível
para as matrizes geradas pelo Sadeprev deve-se utilizar uma versão do R de acordo
com a arquitetura do sistema operacional.
Outra atitude importante para evitar este problema é analisar se a estrutura de
dados utilizada causa problema na alocação do objeto em memória. Um vetor pode
gerar um problema de alocação não por indisponibilidade do espaço total que o
objeto ocupa, mas por falta de espaço contínuo em memória, já que um vetor
precisa de um espaço contínuo livre, ao contrário de uma lista, que pode ser alocada
em espaços não contíguos de memória (Celes & Rangel, 2002).
Para minimizar problemas de alocação de memória no R no Sadeprev,
utilizamos, ainda, a prática de solicitar que o sistema operacional limpe objetos
alocados que não estão mais sendo utilizados, através da função “gc()” (R Core
Team, 2017b). Além disso, apagamos explicitamente no código objetos alocados em
memória que não seriam mais utilizados, por meio da função “remove(objeto)” (R
Core Team, 2017e).
Solucionada a dificuldade de alocação de memória, o Sadeprev ainda
demandava muito tempo de execução, chegando a levar horas para executar tarefas
que atualmente são realizadas em poucos segundos. Para superar essa limitação
foram utilizados recursos de vetorização, compilação de funções e paralelismo.
As funções vetorizadas são mais uma alternativa na melhoria de
desempenho, quando precisamos, por exemplo, percorrer vetores ou qualquer
estrutura parecida. A função sum() (R Core Team, 2017d) é um exemplo, ela é uma
função vetorizada que realiza a soma de todos os elementos de um vetor. A primeira
ideia que se tem ao realizar uma operação como essa é percorrer todos os
elementos por meio de um laço de repetição, porém, funções vetorizadas
conseguem aplicar operações nos vários objetos de um vetor em uma mesma
operação, sendo, portanto, mais ágeis que laços de repetição. As funções da família
“apply” (apply, tapply, sapply e rapply), disponíveis na biblioteca/pacote Base (R
Core Team, 2017a) também são vetorizadas e podem ser alternativas ao uso de
laços de repetição quando precisamos realizar operações sobre estruturas como um
vetor ou matriz. Como o Sadeprev manipula algumas matrizes, várias destas
funções foram utilizadas, por exemplo, a função “mean()”, “sum()”, e a sample().
Para agilizar a execução das funções do Sadeprev utilizou-se, ainda,
compilações de funções. Existem as linguagens compiladas, interpretadas e as
híbridas, que se utilizam dos dois primeiros tipos. Basicamente, nas linguagens
interpretadas, um software chamado interpretador faz a execução do código, lendo o
código e o executando interativamente. Por isso se pode utilizar linguagens
interpretadas (Python e R, por exemplo) como uma linha de comando, utilizando-as
como uma calculadora, por exemplo. Já nas linguagens compiladas a execução é
feita depois que o compilador “transforma” o código fonte (código escrito pelo
programador) em um código de mais baixo nível (que está mais próximo da
linguagem de máquina que da linguagem humana), chamado byte code, para o
sistema operacional poder executá-lo. A execução de programa em linguagens
compiladas é naturalmente mais rápida que em programas de linguagens
interpretadas, pois executar um byte code é mais rápido que interpretar um código.
A implementação da compilação de funções no R foi feita através do pacote
“compiler”, utilizando a função “cmpfun()”. Esta função tem como parâmetro uma
função qualquer escrita em R, e retorna o byte code da mesma função, ou seja, a
função compilada. A partir disso a execução da função é feita a partir do byte code e
por isso é mais rápida.
REcoreu-se, ainda, aos recursos de paralelismo. O R é nativamente mono-
thread (Lim & Tjhi, 2015). Isso significa que todo programa R é executado em
apenas uma linha de execução, se não for modificado explicitamente no código. Isso
significa que o código do programa será interpretado linha por linha,
sequencialmente, sem a possibilidade de execuções de tarefas simultâneas.
Algumas linguagens de programação atuais dão suporte ao paralelismo
implicitamente, onde o programador não precisa se preocupar com a implementação
em muitas partes do código para que seu programa execute operações em paralelo.
A linguagem R não é uma delas.
Para a implementação do paralelismo, o R dispõe também de algumas
bibliotecas, como Parallel (Calaway, Analytics, Weston, & Tenenbaum, 2015) e
snow (Tierney, Rossini, Li, & Sevcikova, 2016). No Sadeprev, escolhemos a função
foreach, da biblioteca foreach (Calaway, Analytics, & Weston, 2015) (Contida como
dependência da biblioteca Parallel). O objetivo desta função é criar uma linha de
processamento independente para cada iteração de um laço de repetição. Portanto,
cada bloco de simulações que tínhamos criado anteriormente não precisa esperar
toda a ordem de execução de um laço de repetição para ser executado, sendo
possível que mais de um bloco seja executado simultaneamente, dependendo da
quantidade de núcleos de processamento do computador.
Após a implementação, os testes foram feitos para o laço de repetição
principal do programa, que é um laço que basicamente chama três funções e
preenche uma matriz a cada iteração. Os parâmetros utilizados nas funções
chamadas são: tamanho da população, número de rodadas, blocos e tempo. Para
estes testes, fixamos os parâmetros em: Número de repetições das simulações de
Monte Carlo igual a 10.000, 10 blocos e horizonte de projeções de 75 anos.
Foram realizados testes com populações iniciais de 100 e de 1.000
indivíduos. Para cada um destes testes verificou-se o tempo de execução do
programa sem compilação ou paralelismo, com paralelismo, e com compilação e
paralelismo. Os resultados são apresentados na Tabela 3.
Tabela 3: Tempo de execução e ganho de eficiência para simulações com 100 e 1000 indivíduos iniciais.
Tempo de execução (min)
Ganho em eficiência
População inicial 100 1000 100 1000 Sequencial (Comando “for”) 3,29 15,67
Em paralelo (Comando “foreach”) 1,53 8,13 53,6% 48,1% Em paralelo + compilação de funções 1,48 7,28 55,2% 53,5%
Como mostra a Tabela 3, o tempo de execução está diretamente relacionado
ao tamanho inicial da população. Quando o programa SADEPREV utiliza apenas
comandos sequenciais o tempo de execução de 10.000 repetições de Monte Carlo é
de 15,67 minutos para uma população inicial de 1.000 indivíduos, mas de apenas
3,29 minutos para uma população inicial de 100 pessoas. Portanto, quanto maior a
população inicial, maior o tempo de processamento.
Ademais, percebe-se, também pela tabela, que o paralelismo e a compilação
diminuem o tempo de processamento do programa. Considerando a população de
100 indivíduos iniciais, enquanto o modelo sequencial foi executado em 3,29
minutos, o modelo em paralelo foi executado em 1,53 minutos, uma redução de
53,6% do tempo gasto. A compilação das funções aprimorou ainda mais a eficiência
do programa, que demorou apenas 1,48 minutos para ser executado nessa situação,
um ganho de 55,2% em relação ao modelo sequencial, e de 3,4% em relação ao
modelo com paralelismo, apenas.
Ressalta-se, ainda, que o ganho de eficiência foi maior para uma população
inicial menor (55,2% para 100 indivíduos) que para a maior (53,5% para 1000
indivíduos) ao se incorporar o paralelismo e a compilação. Apesar disso, foi
significativo nas duas situações, já que com o tempo de execução caiu em mais de
50% nas duas situações.
É interessante observar que o uso do paralelismo melhorou o modelo de
simulação do Sadeprev, pois como antes tínhamos as simulações sequenciais, um
indivíduo não poderia morrer ao “mesmo tempo” que outro, por exemplo, o que não
condiz com a realidade. Portanto, implementando paralelismo nos aproximamos um
pouco mais do real.
5. CONCLUSÃO
Este trabalho mostra a ferramenta Sadeprev, idealizada e construída com o
objetivo de fazer uma projeção informatizada da saúde futura de um RPPS,
baseando-se em informações reais do mesmo. Fundamentado na metodologia de
microssimulação e em um profundo conhecimento de métodos estatísticos e
atuariais, o programa simula os eventos demográficos em uma população fictícia ou
real, sorteando as mudanças de evento e armazenando os dados em estruturas de
dados adequadas até que se chegue aos cálculos e resultados finais previstos pelo
software, de valores associados à capacidade de solvência de um plano
previdenciário.
São apresentados também outros trabalhos importantes que utilizam a
microssimulação, mostrando cada vez mais a importância desta metodologia em
aplicações que simulam a realidade para predições ou estudos analíticos por meio
de simulações que, por exemplo, teriam um alto risco de acidentes humanos, ou
teriam um alto custo de tempo e financeiros para serem realizados através de
observações não computadorizadas.
Foi apresentado o uso de paralelismo no Sadeprev, recurso que se estende
para qualquer outra aplicação desenvolvida na linguagem R, mostrando em
resultados comparativos com aplicações que não utilizam paralelismo, a viabilidade
do uso dos pacotes de paralelismo e como isso afeta o desempenho dos programas
(com ganhos de tempo de cerca de 50%), visto que o tempo de execução pode ser
um fator crítico para a aplicação.
Assim como o paralelismo, foram abordadas outras questões importantes
para o desenvolvimento de software na linguagem R, como o uso de funções
compiladas e vetorizadas, bem como a importância de conhecer os paradigmas de
programação mais utilizados, suas vantagens e desvantagens, pois programar bem
requer muitas outras habilidades além do conhecimento da sintaxe (palavras chave
e definições estruturais das sentenças que formam os comandos da linguagem) da
linguagem de programação.
Reformulações futuras como a segregação de massa, refatoração (processo
de modificar um sistema de software para melhorar a estrutura interna do código
sem alterar seu comportamento externo) do código, adição de novas funcionalidades
e várias outras modificações estão sendo pensadas para o Sadeprev com o objetivo
que ele seja cada vez mais difundido e utilizado, seja no mercado previdenciário ou
no meio acadêmico.
REFERÊNCIAS
Adler, D., Gläser, C., Nenadic, O., Oehlschlägel, J., & Zucchini, W. (2014). ff:
memory-efficient storage of large data on disk and fast access functions (Versão 2.2-
13). Recuperado de https://cran.r-project.org/web/packages/ff/index.html
Banks, J. (1998). Handbook of simulation: principles, methodology, advances,
applications, and practice. USA: Wiley-IEEE. Recuperado de
http://books.google.com.br/books?id=dMZ1Zj3TBgAC&printsec=frontcover&source=
gbs_v2_summary_r&cad=0#v=onepage&q&f=false
Booch, G. ([s.d.]). UML - Guia Do Usuário (2a Edição).
Calaway, R., Analytics, R., & Weston, S. (2015). foreach: Provides Foreach Looping
Construct for R (Versão 1.4.3). Recuperado de https://cran.r-
project.org/web/packages/foreach/index.html
Calaway, R., Analytics, R., Weston, S., & Tenenbaum, D. (2015). doParallel: Foreach
Parallel Adaptor for the “parallel” Package (Versão 1.0.10). Recuperado de
https://cran.r-project.org/web/packages/doParallel/index.html
Celes, W., & Rangel, J. L. (2002). Estruturas de Dados.
Corrêa, C. S. (2014). Tamanho populacional e aleatoriedade de eventos
demográficos na solvência de RPPS municipais capitalizados. UFMG/Cedeplar, Belo
Horizonte, MG.
Hromkovič, J. (2003). Algorithmics for hard problems: introduction to combinatorial
optimization, randomization, approximation, and heuristics (2nd ed). Berlin ; New
York: Springer-Verlag.
Kane, M. J., Emerson, J. W., Haverty, P., & Jr, and C. D. (2016). bigmemory:
Manage Massive Matrices with Shared Memory and Memory-Mapped Files (Versão
4.5.19). Recuperado de https://cran.r-
project.org/web/packages/bigmemory/index.html
Lim, A., & Tjhi, W. (2015, janeiro 30). R High Performance Programming.
Recuperado 8 de maio de 2017, de http://www.barnesandnoble.com/w/r-high-
performance-programming-aloysius-lim/1120930067
Maia, F. V. B. (2007). CALIBRAÇÃO E VALIDAÇÃO DE MODELOS DE MESO E
MICROSSIMULAÇÃO DO TRÁFEGO PARA A AVALIAÇÃO DE INTERVENÇÕES
TÁTICO-OPERACIONAIS NA MALHA VIÁRIA URBANA. Universidade Federal do
Ceará, Fortaleza - CE. Recuperado de
http://livros01.livrosgratis.com.br/cp053304.pdf
MALUCELLI., F. C. (2013). Estudo de Caso: uso de micro simulação de tráfego para
revisão do projeto da Av. Manoel Ribas, em Curitiba, com inclusão de ciclofaixa.
Recuperado de https://www.sinaldetransito.com.br/artigos/estudo_Manoel_Ribas.pdf
Mason, C. (2010, junho 11). Socsim Oversimplified.
Myrrha, L., & Ojima, R. (2016, janeiro). DINÂMICA DEMOGRÁFICA, GESTÃO
PÚBLICA E REGIMES PRÓPRIOS DE PREVIDÊNCIA SOCIAL: OPORTUNIDADES
E DESAFIOS PARA OS SERVIDORES E MUNICIPIOS, v. 17, 59–74.
Pereira, S. do L. (2015). Estruturas de Dados em C. Uma Abordagem Didática (1a).
Érica.
R Core Team, R. C. T. (2017a). R: The R Base Package. R Core Team. Recuperado
de https://stat.ethz.ch/R-manual/R-devel/library/base/html/00Index.html
R Core Team, R. C. T. (2017b, junho 5). R: Garbage Collection. R Core Team <R-
[email protected]. Recuperado de https://stat.ethz.ch/R-manual/R-
devel/library/base/html/gc.html
R Core Team, R. C. T. (2017c, junho 5). R: Memory Limits in R. R Core Team <R-
[email protected]. Recuperado de https://stat.ethz.ch/R-manual/R-
devel/library/base/html/Memory-limits.html
R Core Team, R. C. T. (2017d, junho 5). R: Sum of Vector Elements. R Core Team
<[email protected]. Recuperado de https://stat.ethz.ch/R-manual/R-
devel/library/base/html/sum.html
R Core Team, R. C. T. (2017e, junho 5). Remove Objects from a Specified
Environment. R Core Team <[email protected]. Recuperado de
https://stat.ethz.ch/R-manual/R-devel/library/base/html/rm.html
Souza, R. (2012). Notas de aula. Inferência Estatística Não Paramétrica - Capítulo
15 - Métodos Monte Carlo. In Princípios e Técnicas da Análise Estatística
Experimental. Disciplina de Princípios e Técnicas da Análise Estatística Experimental
do curso de Pós-graduação no Centro de Informática (UFPE): Centro de Informática
- UFPE.
Tanenbaum, A. S. (2009). Sistemas Operacionais Modernos (3a). Pearson.
Tierney, L., Rossini, A. J., Li, N., & Sevcikova, H. (2016). snow: Simple Network of
Workstations (Versão 0.4-2). Recuperado de https://cran.r-
project.org/web/packages/snow/index.html
Tucker, A. B., & Nooman, R. E. (2009). Linguagens de Programação - Princípios e
Paradigmas (2a Ed). Amgh.
Venables, B., & Brahm, based on original code by D. (2013). SOAR: Memory
management in R by delayed assignments (Versão 0.99-11). Recuperado de
https://cran.r-project.org/web/packages/SOAR/index.html
Vos, S. D., & Palloni, A. (1989). Formal Models and Methods for the Analysis of
Kinship and Household Organization. Population Index. Office of Population
Research, 55, 174–198.
Zhao, Z. (2006). Computer microsimulation and historical study of social structure: A
comparative review of SOCSIM and CAMSIM. Revista de Demografía Histórica, 2,
59–88.