コード例 #1
0
ファイル: estoques.py プロジェクト: cpatrickalves/simprev
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
コード例 #2
0
ファイル: estoques.py プロジェクト: LPRAD-UFPA/SimPrev
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
コード例 #3
0
ファイル: estoques.py プロジェクト: LPRAD-UFPA/SimPrev
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
コード例 #4
0
ファイル: probabilidades.py プロジェクト: LPRAD-UFPA/SimPrev
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
コード例 #5
0
ファイル: estoques.py プロジェクト: cpatrickalves/simprev
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
コード例 #6
0
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
コード例 #7
0
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
コード例 #8
0
ファイル: probabilidades.py プロジェクト: LPRAD-UFPA/SimPrev
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
コード例 #9
0
ファイル: probabilidades.py プロジェクト: LPRAD-UFPA/SimPrev
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