def calc_estoq_apos_acumulado(estoques, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Adiciona o ano de 2014 na lista de anos anos = [2014] + periodo # Dicionário que armazena o Estoque acumulado est_acumulado = {} # As chaves do dicionário são as clientelas for clientela in ['UrbPiso', 'UrbAcim', 'Rur']: # Cria o DataFrame est_acumulado[clientela + 'H'] = pd.DataFrame(0.0, index=range(0, 91), columns=anos) est_acumulado[clientela + 'M'] = pd.DataFrame(0.0, index=range(0, 91), columns=anos) # Obtém todas as aposentadorias e faz o somatório por clientela, sexo e idade for beneficio in dados.get_id_beneficios(ids_apos): # Verifica se o estoque para o benefício existe if beneficio in estoques.keys(): sexo = beneficio[-1] if dados.get_clientela(beneficio) == clientela: est_acumulado[clientela + sexo] += estoques[beneficio] return est_acumulado
def calc_estoq_aux(est, prob, seg, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() for benef in dados.get_id_beneficios(['Auxd', 'Auxa']): # Verifica se existe no Estoque if benef in est: sexo = benef[-1] id_seg = 'Ocup' + dados.get_clientela( benef) + sexo # ex: OcupUrbPisoH ou CaUrbH # Para os Rurais se utiliza toda a população (Fonte: planilhas do MF) if 'Rur' in benef: id_seg = 'PopRur' + sexo for ano in periodo: est[benef][ano] = seg[id_seg][ano] * prob[benef][ano] # Eq. 17 for benef in dados.get_id_beneficios(['Auxr']): # Verifica se existe no Estoque if benef in est: sexo = benef[-1] id_seg = 'Ocup' + dados.get_clientela( benef) + sexo # ex: OcupUrbPisoH ou CaUrbH # Para os Rurais se utiliza toda a população (Fonte: planilhas do MF) if 'Rur' in benef: id_seg = 'PopRur' + sexo for ano in periodo: # Cria uma nova entrada est[benef][ano] = 0 for idade in range(0, 91): # Na planilha são aplicados deslocamentos nas idades deslocamento = 0 if idade < 61 and sexo == 'H': deslocamento = 25 elif idade < 61 and sexo == 'M': deslocamento = 18 # Eq. 17 est[benef].loc[idade, ano] = seg[id_seg][ano][ idade + deslocamento] * prob[benef][ano][idade] # OBS: Nas planilhas o cálculo do deslocamento está errado para as URbAcimM (usa-se 25 ao invés de 18) return est
def calc_estoq_apos(est, conc, prob, seg, periodo): # Identificações das aposentadorias ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtem as aposentadorias para todas as clientelas e sexos lista_benef = dados.get_id_beneficios(ids_apos) for benef in lista_benef: # Verifica se o beneficio existe no Estoque if benef in est: sexo = benef[-1] # Obtém o Sexo id_prob_morte = 'Mort' + sexo # ex: MortH id_fam = 'fam' + benef # fator de ajuste de mortalidade id_seg = 'Ocup' + dados.get_clientela( benef) + sexo # ex: OcupUrbPisoH ou CsmUrbH # Para os Rurais se utiliza toda a população (Fonte: planilhas do MF) if 'Rur' in benef: id_seg = 'PopRur' + sexo for ano in periodo: # Adiciona uma nova coluna (ano) no DataFrame com valores zero est[benef][ano] = 0 # 1 a 90 anos - Equação 11 da LDO de 2018 for idade in range(1, 91): est_ano_anterior = est[benef][ano - 1][idade - 1] prob_sobreviver = 1 - prob[id_prob_morte][ano][ idade] * prob[id_fam][ano][idade] entradas = seg[id_seg][ano][idade] * prob[benef][ano][idade] if idade == 90: est_ano_anterior = est[benef][ano - 1][ idade - 1] + est[benef][ano - 1][idade] # Eq. 11 est[benef].loc[ idade, ano] = est_ano_anterior * prob_sobreviver + entradas # Eq. 11 # Salva a quantidade de concessões para uso posterior conc[benef].loc[idade, ano] = entradas # Calculo para a idade zero est[benef].loc[0, ano] = seg[id_seg][ano][0] * prob[benef][ano][0] # Salva a quantidade de concessões para uso posterior conc[benef].loc[0, ano] = est[benef].loc[0, ano] return est
def calc_prob_apos_MF(segurados, concessoes, periodo): probabilidades = {} # Dicionário que salvas as prob. para cada benefício ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtém a lista de aposentadorias e itera sobre cada tipo for beneficio in dados.get_id_beneficios(ids_apos): # Verifica se existem dados de concessões do benefício if beneficio in concessoes.keys(): sexo = beneficio[-1] clientela = dados.get_clientela(beneficio) id_popOcup = 'Ocup' + clientela + sexo # OBS: Para clientela Rural utiliza-se toda a população if clientela == 'Rur': id_popOcup = 'PopRur' + sexo # OBS: A implementação descritas nas planilhas do DOC110/MF usa uma equação diferente da Eq. 16 # prob_entrada = concessoes/PopOcupada prob_entrada = concessoes[beneficio] / segurados[id_popOcup] # Trata divisões por zero prob_entrada.replace([np.inf, -np.inf], np.nan, inplace=True) # De acordo com as planilhas do DOC110/MF o valor do ano inicial da projeção (2015), deve ser igual a média dos anos anteriores prob_entrada[2015] = prob_entrada.loc[:, :2014].mean(axis=1) # Repete a última probabilidade(2015) nos anos seguintes(2016-2060) for ano in periodo[1:]: prob_entrada[ano] = prob_entrada[ano - 1] # Substitui os NaN (not a number) por zeros prob_entrada.fillna(0, inplace=True) # Adiciona no dicionário probabilidades[beneficio] = prob_entrada return probabilidades
def calc_concessoes_pensao(populacao, concessoes, estoques, segurados, probabilidades, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtém o conjunto de benefícios do tipo pensão lista_pensoes = dados.get_id_beneficios('Pe') # Obtém estoque acumulado de aposentadorias por ano, clientela, idade e sexo estoq_acum = calc_estoq_apos_acumulado(estoques, periodo) # Eq. 26 # Hipótese de que o diferencial de idade médio entre cônjuges é de 4 anos (pag. 45 LDO de 2018) Dit = 4 # Calcula concessões de pensões do tipo B for benef in lista_pensoes: sexo = benef[-1] # Obtém o Sexo sexo_oposto = 'M' if sexo == 'H' else 'H' # Obtém o oposto id_mort_sex_op = 'Mort' + sexo_oposto # ex: MortM # Sempre são usados os segurados do sexo masculino id_seg = dados.get_id_segurados(benef).replace( sexo, 'H') # Obtem o Id do segurado trocando o sexo clientela = dados.get_clientela(benef) id_prob_entr = benef.replace(sexo, sexo_oposto) for ano in periodo: # Tipo de Pensão válida a partir de 2015 if ano < 2015: continue # Pula anos inferiores a 2015 # Cria nova entrada no DataFrame concessoes[benef][ano] = 0 # Calcula concessões # Idades de 0 a 90 anos. for idade in range(0, 91): # Determina o valor de Dit baseado na idade (relação baseada nas planilhas do MF) if idade > 20 and idade < 87: Dit = 4 elif idade == 87: Dit = 3 elif idade == 88: Dit = 2 elif idade == 89: Dit = 1 else: Dit = 0 # A soma ou subtração depende do sexo if sexo == 'H': i_Dit = idade - Dit else: i_Dit = idade + Dit prob_entrada = probabilidades[id_prob_entr][i_Dit] pmort = probabilidades[id_mort_sex_op][ano][i_Dit] # Para os urbanos com idade de 15 anos e para os rurais utiliza-se toda a população por clientela simples (Urb ou Rur) if idade < 16 or clientela == 'Rur': clientela_simples = clientela[0:3] potGeradoresPensoes = populacao['Pop' + clientela_simples + sexo_oposto][ano][i_Dit] else: seg = segurados[id_seg][ano][i_Dit] est_ac = estoq_acum[clientela + sexo_oposto][ano][i_Dit] potGeradoresPensoes = seg + est_ac # Eq. 24 e 25 concessoes[benef].loc[ idade, ano] = prob_entrada * potGeradoresPensoes * pmort return concessoes
def calc_prob_pensao(concessoes, segurados, populacao, estoque, prob_morte, periodo): # A LDO de 2018 não descreve como calcular as probabilidades para pensões # As equações abaixo foram extraídas das planilhas do MF probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_estoque = periodo[0] - 1 # 2014 # Eq. 26: Dit = Idh - Idm # Hipótese de que o diferencial de idade médio entre cônjuges é de 4 anos (pag. 45 LDO de 2018) Dit = 4 lista = LerTabelas() est_apos_acumulado = calc_estoq_apos_acumulado(estoque, periodo) for beneficio in lista.get_id_beneficios('Pe'): # Cria Objeto do tipo Serie que armazena as probabilidades probabilidades[beneficio] = pd.Series(0.0, index=range(0, 91)) sexo = beneficio[-1] # Última letra do benefício sexo_oposto = 'M' if sexo == 'H' else 'H' # Obtém o oposto clientela = lista.get_clientela(beneficio) id_conc = beneficio.replace(sexo, sexo_oposto) # Troca o sexo do benefício # OBS: Sempre são usados os segurados do sexo masculino id_segurados = lista.get_id_segurados(beneficio).replace(sexo, 'H') # Para cada idade i for idade in range(0, 91): if idade > 20 and idade < 87: Dit = 4 elif idade == 87: Dit = 3 elif idade == 88: Dit = 2 elif idade == 89: Dit = 1 else: Dit = 0 # A soma ou subtração depende do sexo if sexo == 'M': i_Dit = idade + Dit else: i_Dit = idade - Dit # Trata valores negativos e maiores que 90 para i_Dit if i_Dit < 0: i_Dit = 0 if i_Dit > 90: i_Dit = 90 conc = concessoes[id_conc][ano_estoque][i_Dit] pmorte = prob_morte['Mort' + sexo][ano_estoque][idade] # Para os urbanos com idade de 15 anos e para os rurais utiliza-se toda a população por clientela simples (Urb ou Rur) if idade < 16 or clientela == 'Rur': clientela_simples = clientela[0:3] potGeradoresPensoes = populacao['Pop' + clientela_simples + sexo][ano_estoque][idade] else: seg = segurados[id_segurados][ano_estoque][idade] est_ac = est_apos_acumulado[clientela + sexo][ano_estoque][idade] potGeradoresPensoes = seg + est_ac # Evita divisões por zero if potGeradoresPensoes == 0: probPensao = 0 else: # Equação baseada nas Eq. 24 e 25 # OBS: Essa equação gera probabilidades maiores que 1 probPensao = conc / (potGeradoresPensoes * pmorte) probabilidades[beneficio][idade] = probPensao return probabilidades
def calc_fat_ajuste_mort(estoques, cessacoes, probMort, periodo): # ano utilizado para cálculo ano_prob = periodo[0] - 1 #2014 # Dicionário que armazena as probabilidades fat_ajuste = {} # Calculada para aposentadorias, pensões e assistênciais tags = [ 'Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd', 'Pens', 'LoasDef', 'LoasIdo', 'Rmv' ] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Calcula o fator de ajuste para cada tipo de aposentadoria for beneficio in dados.get_id_beneficios(tags): sexo = beneficio[-1] # Verifica se existem dados de estoque e cessações do benefício if beneficio in estoques.keys() and beneficio in cessacoes.keys(): # A Equação utilizada nas planilhas do MF é diferente da descrita na LDO de 2018 (Eq. 14 e 15) # fam = 1, se Cessações = 0 # fam = (Cessações/Estoque)/txMort txCes = cessacoes[beneficio] / estoques[beneficio] fam = txCes / probMort['Mort' + sexo] # Elimina colunas com dados ausentes fam.dropna(how='all', axis=1, inplace=True) # Elimina o ano de 2010 (não é utilizado nas planilhas) if 2010 in fam.columns: fam.drop(2010, axis=1, inplace=True) # Trata divisões por zero (gera o valo inf) fam.replace([np.inf, -np.inf], np.nan, inplace=True) # Garante que não existe valor zero fam.replace(0, 1.0, inplace=True) # Substitui os NaN por 1.0 fam.fillna(1.0, inplace=True) # Para o primeiro ano de projeção (2015), o FAM é igual a média dos anos anteriores # Exceto para os Rurais e assistenciais, onde o FAM é igual ao do ano anterior if dados.get_clientela(beneficio) == 'Rur' or 'Loas' in beneficio: fam[ano_prob + 1] = fam[ano_prob] else: fam[ano_prob + 1] = fam.loc[:, :ano_prob].mean(axis=1) # Para os anos seguintes o FAM é constante for ano in periodo[1:]: fam[ano] = fam[ano - 1] # Lógica usada nas planilhas do MF para as Pensões # Garante que o beneficiário pare de receber pensão aos 21 anos # fam = 1/ProbMorte if 'Pens' in beneficio: for ano in periodo: fam.loc[21, ano] = 1 / probMort['Mort' + sexo].loc[21, ano] # Salva no dicionário fat_ajuste['fam' + beneficio] = fam return fat_ajuste
def calc_prob_pensao_LDO2018(concessoes, segurados, estoque, prob_morte, periodo): # A LDO de 2018 não descreve como calcular as probabilidades para pensões # As equações abaixo são resultado de manipulações das Equações 24 e 25 da LDO # Onde-se isolou-se a variável v para se chegar na equação de calculo das probabilidades probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_estoque = periodo[0] - 1 # 2014 # Eq. 26: Dit = Idh - Idm # Hipótese de que o diferencial de idade médio entre cônjuges é de 4 anos (pag. 45 LDO de 2018) Dit = 4 lista = LerTabelas() est_apos_acumulado = calc_estoq_apos_acumulado(estoque, periodo) for beneficio in lista.get_id_beneficios('Pe'): # Cria Objeto do tipo Serie que armazena as probabilidades probabilidades[beneficio] = pd.Series(0.0, index=range(0, 91)) sexo = beneficio[-1] # Última letra do benefício sexo_oposto = 'M' if sexo == 'H' else 'H' # Obtém o oposto clientela = lista.get_clientela(beneficio) id_conc = beneficio.replace(sexo, sexo_oposto) # Troca o sexo do benefício id_segurados = lista.get_id_segurados(beneficio) # Para cada idade i for idade in range(0, 91): # A soma ou subtração depende do sexo if sexo == 'M': i_Dit = idade - Dit else: i_Dit = idade + Dit # Trata valores negativos e maiores que 90 para i_Dit if i_Dit < 0: i_Dit = 0 if i_Dit > 90: i_Dit = 90 conc = concessoes[id_conc][ano_estoque][idade] seg = segurados[id_segurados][ano_estoque][i_Dit] est_ac = est_apos_acumulado[clientela + sexo][ano_estoque][i_Dit] pmorte = prob_morte['Mort' + sexo][ano_estoque][i_Dit] # Se a quantidade de segurados e estoque for zero a prob daria infinito if seg == 0 and est_ac == 0: probPensao = 0 else: # Equação baseada nas Eq. 24 e 25 # OBS: Essa equação pode gerar probabilidades maiores que 1 para idades menores que 20 probPensao = conc / ((seg + est_ac) * pmorte) probabilidades[beneficio][i_Dit] = probPensao return probabilidades
def calc_prob_aux_MF(segurados, estoques, concessoes, periodo): probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_prob = periodo[0] - 1 # ano utilizado para cálculo (2014) # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # De acordo com as planilhas do DOC110/MF # ProbAuxDoenca = Concedidos/popOcupada # ProbAuxAcidente = Estoque/popOcupada # ProbAuxReclusão = Estoque/popOcupada(somando a idade com 25) # O cálculo do Auxílio doença e diferente dos demais auxílios for beneficio in dados.get_id_beneficios(['Auxd']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys() and beneficio in concessoes.keys(): sexo = beneficio[-1] clientela = dados.get_clientela(beneficio) # concessões conhecidas dos últimos 4 anos (2011-2014) conc = concessoes[beneficio].loc[:, (ano_prob - 3):] # OBS: Para clientela Rural utiliza-se toda a população if clientela == 'Rur': # dados de população dos últimos 4 anos popOcup = segurados['PopRur' + sexo].loc[:, (ano_prob - 3):] else: popOcup = segurados['Ocup' + clientela + sexo].loc[:, (ano_prob - 3):] prob_auxd = conc / popOcup # Substitui os NaN por zero prob_auxd.replace([np.inf, -np.inf], np.nan, inplace=True) prob_auxd.fillna(0, inplace=True) # Remove colunas com todos os valores iguais a zero prob_auxd = prob_auxd.loc[:, (prob_auxd != 0).any(axis=0)] # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: prob_auxd[ano] = prob_auxd[ano - 1] probabilidades[beneficio] = prob_auxd # Calcula probabilidades de entrada em auxílio acidente for beneficio in dados.get_id_beneficios(['Auxa']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys(): sexo = beneficio[-1] clientela = dados.get_clientela(beneficio) # estoques conhecidos dos últimos 4 anos (2011-2014) est = estoques[beneficio].loc[:, (ano_prob - 3):] # OBS: Para clientela Rural utiliza-se toda a população if clientela == 'Rur': # dados de população dos últimos 4 anos popOcup = segurados['PopRur' + sexo].loc[:, (ano_prob - 3):] else: popOcup = segurados['Ocup' + clientela + sexo].loc[:, (ano_prob - 3):] prob_auxa = est / popOcup # Substitui os inf e NaN por zero prob_auxa.replace([np.inf, -np.inf], np.nan, inplace=True) prob_auxa.fillna(0, inplace=True) # Remove colunas com todos os valores iguais a zero prob_auxa = prob_auxa.loc[:, (prob_auxa != 0).any(axis=0)] # para o ano seguinte ao do estoque (2015) a probabilidade é a média dos anos anteriores # OBS: Para algumas clientelas as Planilhas repetem o último ano prob_auxa[2015] = prob_auxa.loc[:, :2014].mean(axis=1) # Repete a última probabilidade(2015) nos anos seguintes(2016-2060) for ano in periodo[1:]: prob_auxa[ano] = prob_auxa[ano - 1] probabilidades[beneficio] = prob_auxa # Calcula probabilidades de entrada em auxílio reclusão for beneficio in dados.get_id_beneficios(['Auxr']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys(): sexo = beneficio[-1] clientela = dados.get_clientela(beneficio) # Cria objeto do tipo DataFrame prob_auxr = pd.DataFrame(0.0, index=range(0, 91), columns=[ano_prob] + periodo) deslocamento = 0 for idade in range(0, 91): est = estoques[beneficio][ano_prob][idade] # Na planilha são aplicados deslocamentos nas idades if idade < 61 and sexo == 'H': deslocamento = 25 elif idade < 61 and sexo == 'M': deslocamento = 18 else: deslocamento = 0 # OBS: para o AuxReclusao o sexo utilizado na popOcup é sempre masculino if clientela == 'Rur': id_popOcup = 'PopRurH' else: id_popOcup = 'Ocup' + clientela + 'H' popOcup = segurados[id_popOcup][ano_prob][idade + deslocamento] if popOcup == 0: prob_auxr[ano_prob][idade] = 0 else: prob_auxr[ano_prob][idade] = est / popOcup # Substitui os NaN por zero prob_auxr.replace([np.inf, -np.inf], np.nan, inplace=True) prob_auxr.fillna(0, inplace=True) # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: prob_auxr[ano] = prob_auxr[ano - 1] probabilidades[beneficio] = prob_auxr return probabilidades