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 = dados.get_id_segurados(benef) # ex: CsmUrbH 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 = dados.get_id_segurados(benef) # ex: CsmUrbH 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_prob_aux_LDO2018(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 # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # 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(): conc = concessoes[beneficio][ano_prob] id_seg = dados.get_id_segurados(beneficio) seg_ano_ant = segurados[id_seg][ano_prob - 1] prob_auxd = conc / (seg_ano_ant + (conc / 2)) # Eq. 18 # Substitui os NaN por zero prob_auxd.fillna(0, inplace=True) probabilidades[beneficio] = prob_auxd # Calcula probabilidades de entrada em auxílios reclusão e acidente for beneficio in dados.get_id_beneficios(['Auxa', 'Auxr']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys(): est = estoques[beneficio][ano_prob] id_seg = dados.get_id_segurados(beneficio) seg = segurados[id_seg][ano_prob] # OBS: para o caso do Auxr tem-se muitas divisões por zero, gerando inf prob_aux_ar = est / seg # Eq. 19 # Substitui os NaN por zero prob_aux_ar.fillna(0, inplace=True) probabilidades[beneficio] = prob_aux_ar return probabilidades
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 = dados.get_id_segurados(benef) # ex: CsmUrbH 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_estoq_salMat(est, pop, seg, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # 2014, 2015, ... anos = [(periodo[0] - 1)] + periodo for benef in dados.get_id_beneficios('SalMat'): # Armazena valores do ano est_acumulado = pd.Series(index=anos) # Obtem o tipo de segurado a partir do benefício id_seg = dados.get_id_segurados(benef) # Os estoques de SalMat são agrupados por ano no modelo (não por idade) # OBS: O calculo dos estoques de SalMat não dependem da existência de estoques anteriores # Realiza projeção for ano in anos: est_acumulado[ano] = 0 # Cria um novo ano nascimentos = pop['PopIbgeM'][ano][0] + pop['PopIbgeH'][ano][0] # Acumula mulheres de 16 a 45 anos seg_16_45 = 0 pop_16_45 = 0 # O calculo para os rurais usa a População Rural e não os segurados rurais # OBS: o cálculo para os rurais ainda não bate com os da planilha do MF por causa do # cálculo da taxa de ruralização ser diferente if 'Rur' in benef: for idade in range(16, 46): seg_16_45 += pop['PopRurM'][ano][idade] pop_16_45 += pop['PopIbgeM'][ano][idade] else: for idade in range(16, 46): seg_16_45 += seg[id_seg][ano][idade] pop_16_45 += pop['PopIbgeM'][ano][idade] # Eq. 20 est_acumulado[ano] = (seg_16_45 / pop_16_45) * nascimentos # Cria uma nova entrada no dicionário para armazenar os estoques acumulados est[benef] = est_acumulado return est
def calc_prob_apos_LDO2018(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(): # Cria o DataFrame prob_entrada = pd.DataFrame(0.0, index=range(0, 91), columns=([2014] + periodo)) # Eq. 16 # A versão da LDO trabalha com estoques (variável Q), porém o correto seriam os segurados ano_prob = periodo[0] - 1 # ano utilizado para cálculo (2014) id_segurado = dados.get_id_segurados(beneficio) prob_entrada[ano_prob] = concessoes[beneficio][ano_prob] / ( segurados[id_segurado][ano_prob - 1] + (concessoes[beneficio][ano_prob] / 2)) # Trata divisões por zero prob_entrada.replace([np.inf, -np.inf], np.nan, inplace=True) # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: 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_prob_apos(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(): id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # 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_seg] # 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_aux(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(): id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # concessões conhecidas dos últimos 4 anos (2011-2014) conc = concessoes[beneficio].loc[:, (ano_prob - 3):] seg = segurados[id_seg].loc[:, (ano_prob - 3):] prob_auxd = conc / seg # 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(): id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # estoques conhecidos dos últimos 4 anos (2011-2014) est = estoques[beneficio].loc[:, (ano_prob - 3):] seg = segurados[id_seg].loc[:, (ano_prob - 3):] prob_auxa = est / seg # 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] id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # 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 id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # OBS: para o AuxReclusao o sexo utilizado na popOcup é sempre masculino if 'Rur' in id_seg: id_seg = 'RurH' seg = segurados[id_seg][ano_prob][idade + deslocamento] if seg == 0: prob_auxr[ano_prob][idade] = 0 else: prob_auxr[ano_prob][idade] = est / seg # 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
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_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