Você está na página 1de 59

PONTIFÍCIA UNIVERSIDADE CATÓLICA DE MINAS GERAIS

NÚCLEO DE EDUCAÇÃO A DISTÂNCIA


Pós-graduação Lato Sensu em Ciência de Dados e Big Data

Gláucia de Oliveira Dias

ANÁLISE DO INDICADOR DE SITUAÇÃO PREVIDENCIÁRIA

Belo Horizonte
2021
Gláucia de Oliveira Dias

ANÁLISE DO INDICADOR DE SITUAÇÃO PREVIDENCIÁRIA

Trabalho de Conclusão de Curso apresentado


ao Curso de Especialização em Ciência de
Dados e Big Data como requisito parcial à
obtenção do título de especialista.

Belo Horizonte
2021
SUMÁRIO

1. Introdução..................................................................................................................4
1.1. Contextualização..................................................................................................4
1.2. O problema proposto...........................................................................................4
2. Coleta de Dados......................................................................................................4
3. Processamento/Tratamento de Dados.................................................................5
4. Análise e Exploração dos Dados...........................................................................5
5. Criação de Modelos de Machine Learning...........................................................5
6. Apresentação dos Resultados...............................................................................5
7. Links.........................................................................................................................6
REFERÊNCIAS.............................................................................................................7
APÊNDICE....................................................................................................................8
4

1 Introdução
O trabalho visa à análise do Indicador de Situação Previdenciária (ISP)
relacionado ao Regime Próprio de Previdência Social, no intuito de dar ampla
visibilidade à situação do sistema de previdência dos servidores públicos e oferecer
insights para a melhoria da gestão previdenciária.

Para isso, o estudo foi estruturado em seis partes. Na introdução, será


apresentada a contextualização do assunto tratado e o problema proposto. Na
sequência, serão apresentadas as informações acerca da coleta dos dados
(Capítulo 2) e os passos realizados para o tratamento inicial (Capítulo 3). Passo
seguinte, serão efetuadas a análise e a exploração desses dados, com vistas à
obtenção de informações estatísticas relevantes (Capítulo 4). Em seguida, será
apresentado o método de machine learning com objetivo de encontrar similaridade
entre os dados da amostra (Capítulo 5). Por fim, serão apresentados os resultados
obtidos (Capítulo 6).

1.1 Contextualização
Com o objetivo de atender ao art. 40 da Constituição Federal, os Regimes
Próprios de Previdência Social (RPPS) foram instituídos pelos entes federativos para
dar cobertura a servidores públicos titulares de cargos efetivos, bem como a
membros da magistratura, do Ministério Público, da Defensoria Pública e dos
Tribunais de Contas.

Atualmente, a Subsecretaria dos Regimes Próprios de Previdência Social


(SRPPS) do Ministério da Economia é responsável por orientar, fiscalizar,
supervisionar e acompanhar os RPPS, além de estabelecer e publicar os
parâmetros e diretrizes gerais para seu cumprimento, e receber dados e
informações sobre esses regimes e seus segurados

Para cumprir com sua responsabilidade, a SRPPS instituiu o Indicador de


Situação Previdenciária (ISP). O objetivo do ISP é promover a visibilidade da
situação do sistema de previdência dos servidores públicos, fornecer critério objetivo
de comparabilidade entre os RPPS, possibilitar o controle social e incentivar a
melhoria da gestão previdenciária
5

1.2 O problema proposto


O Indicador de Situação Previdenciária - ISP é apurado e divulgado
anualmente pela Subsecretaria dos Regimes Próprios de Previdência Social -
SRPPS tendo por base as informações encaminhadas pelos entes federativos por
meio do CADPREV e do SICONFI.

Para dar ampla visibilidade do ISP aos entes federativos houve a necessidade
de analisar os dados históricos do ISP combinando com os dados de população,
com objetivo de criar um painel de visualização de classificação dos entes.

Para facilitar o entendimento do problema e da solução a ser proposta


utilizamos a tecnica do 5WS, que consiste em responder as seguintes perguntas:

 Why? Auxiliar a Subsecretaria dos Regimes Próprios de Previdência


Social - SRPPS a identificar os entes que estão melhores ou piores na
classificação do ISP, a fim de direcionar esforços em ofertar vantagens
aos melhores e apoio aos piores.

 Who? Subsecretaria dos Regimes Próprios de Previdência Social -


SRPPS.

 What? Dar ampla visibilidade da classificação do ISP, identificado


quais são os melhores e piores classificados, fazendo uma relação
com a quantidade da população.

 Where? Os dados são referentes aos entes federativos do Brasil e o


resultado será apresentado em um painel de visualização online.

 When? Em relação aos dados analisados, foi utilizado um subset


relativo ao período de dois anos, 2019 e 2020.

2 Coleta de Dados
Nesse trabalho foram utilizadas três fontes de dados: a primeira é referente
aos indicadores gerados pela Subsecretaria dos Regimes Próprios de Previdência
Social – SRPPS, a segunda é referente às informações dos entes, como nome e
código ibge, disponibilizadas pelo IBGE, e a última refere-se aos dados de
população dos entes federativos, também disponibilizados pelo IBGE.
6

A seguir são detalhados a origem, o formato e a estrutura dos datasets.

2.1 Dataset do SRPPS


Os dados adquiridos são provenientes do “site” da Previdência Social
(https://www.gov.br/previdencia/pt-br/assuntos/previdencia-no-servico-publico/
indicador-de-situacao-previdenciaria) no formato Microsoft Excel®.
Foram 2 arquivos com dados sobre os indicadores da situação previdenciária
dos entes federativos, um referente ao ano de 2019 e o outro referente ao ano de
2020:
 Ano 2019: isp-rpps-2019-11-08-2020.xlsx
 Ano 2020: isp-rpps-2020-16-12-2020.xlsx
Cada arquivo possui várias planilhas, onde serão lidas 8 delas, conforme
apresentado a seguir. Os arquivos se encontram se encontram no repositório
.../fonte_de_dados.

Tabela 2.1: Planilha Divisão por Grupos


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
SUBGRUPO Classificação do Subgrupo Texto
QUANTIDADE DE SEGURADOS Quantidade de segurados ativos Inteiro
ATIVOS
QUANTIDADE DE APOSENTADOS Quantidade de aposentados Inteiro
QUANTIDADE DE PENSIONISTAS Quantidade de pensionistas Inteiro

Tabela 2.2: Planilha Indicador de Regularidade


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
ACESSO DOS SEGURADOS ÀS Status do critério (Regular, Texto
INFORMAÇÕES DO REGIME Irregular, com Decisão Judicial,
Em Análise)
ADOÇÃO DO PLANO DE CONTAS E Status do critério (Regular, Texto
DOS PROCEDIMENTOS CONTÁBEIS Irregular, com Decisão Judicial,
APLICADOS AO SETOR PÚBLICO Em Análise)
APLICAÇÕES FINANCEIRAS DE Status do critério (Regular, Texto
ACORDO COM RESOLUÇÃO DO CMN Irregular, com Decisão Judicial,
- PREVISÃO LEGAL Em Análise)
APLICAÇÕES FINANCEIRAS RESOL. Status do critério (Regular, Texto
CMN - ADEQUAÇÃO DAIR E POLÍTICA Irregular, com Decisão Judicial,
INVESTIMENTOS - DECISÃO Em Análise)
7

ADMINISTRATIVA
ATENDIMENTO AO AUDITOR FISCAL Status do critério (Regular, Texto
EM AUDITORIA DIRETA NO PRAZO Irregular, com Decisão Judicial,
Em Análise)
ATENDIMENTO AO MPS EM Status do critério (Regular, Texto
AUDITORIA INDIRETA NO PRAZO Irregular, com Decisão Judicial,
Em Análise)
CARÁTER CONTRIBUTIVO (ENTE E Status do critério (Regular, Texto
ATIVOS - ALÍQUOTAS) Irregular, com Decisão Judicial,
Em Análise)
CARÁTER CONTRIBUTIVO (INATIVOS Status do critério (Regular, Texto
E PENSIONISTAS- ALÍQUOTAS) Irregular, com Decisão Judicial,
Em Análise)
CARÁTER CONTRIBUTIVO Status do critério (Regular, Texto
(REPASSE) - DECISÃO Irregular, com Decisão Judicial,
ADMINISTRATIVA Em Análise)
COBERTURA EXCLUSIVA A Status do critério (Regular, Texto
SERVIDORES EFETIVOS Irregular, com Decisão Judicial,
Em Análise)
CONCESSÃO DE BENEFÍCIOS NÃO Status do critério (Regular, Texto
DISTINTOS DO RGPS - PREVISÃO Irregular, com Decisão Judicial,
LEGAL Em Análise)
CONTAS BANCÁRIAS DISTINTAS Status do critério (Regular, Texto
PARA OS RECURSOS Irregular, com Decisão Judicial,
PREVIDENCIÁRIOS Em Análise)
DEMONSTRATIVO DA POLÍTICA DE Status do critério (Regular, Texto
INVESTIMENTOS - DPIN - Irregular, com Decisão Judicial,
CONSISTÊNCIA Em Análise)
DEMONSTRATIVO DA POLÍTICA DE Status do critério (Regular, Texto
INVESTIMENTOS - DPIN - Irregular, com Decisão Judicial,
ENCAMINHAMENTO À SPPS Em Análise)
DEMONSTRATIVO DAS APLICAÇÕES Status do critério (Regular, Texto
E INVESTIMENTOS DOS RECURSOS Irregular, com Decisão Judicial,
- DAIR - CONSISTÊNCIA Em Análise)
DEMONSTRATIVO DAS APLICAÇÕES Status do critério (Regular, Texto
E INVESTIMENTOS DOS RECURSOS Irregular, com Decisão Judicial,
- DAIR - ENCAMINHAMENTO A Em Análise)
PARTIR DE 2017
DEMONSTRATIVO DE Status do critério (Regular, Texto
INFORMAÇÕES PREVIDENCIÁRIAS E Irregular, com Decisão Judicial,
REPASSES - DIPR - CONSISTÊNCIA E Em Análise)
CARÁTER CONTRIBUTIVO
DEMONSTRATIVO DE Status do critério (Regular, Texto
INFORMAÇÕES PREVIDENCIÁRIAS E Irregular, com Decisão Judicial,
REPASSES - DIPR - Em Análise)
ENCAMINHAMENTO À SPPS
ENCAMINHAMENTO DA LEGISLAÇÃO Status do critério (Regular, Texto
À SPS Irregular, com Decisão Judicial,
Em Análise)
EQUILÍBRIO FINANCEIRO E Status do critério (Regular, Texto
ATUARIAL - ENCAMINHAMENTO NTA, Irregular, com Decisão Judicial,
DRAA E RESULTADOS DAS Em Análise)
ANÁLISES
ESCRITURAÇÃO CONTÁBIL - Status do critério (Regular, Texto
CONSISTÊNCIA DAS INFORMAÇÕES Irregular, com Decisão Judicial,
- DECISÃO ADMINISTRATIVA Em Análise)
EXISTENCIA DE COLEGIADO OU Status do critério (Regular, Texto
INSTÂNCIA DE DECISÃO EM QUE Irregular, com Decisão Judicial,
SEJA GARANTIDA A PARTICIPAÇÃO Em Análise)
8

DOS SEGURADOS
INCLUSÃO DE PARCELAS Status do critério (Regular, Texto
REMUNERATÓRIAS TEMPORÁRIAS Irregular, com Decisão Judicial,
NOS BENEFÍCIOS Em Análise)
OBSERVÂNCIA DOS LIMITES DE Status do critério (Regular, Texto
CONTRIBUIÇÃO DO ENTE Irregular, com Decisão Judicial,
Em Análise)
OBSERVÂNCIA DOS LIMITES DE Status do critério (Regular, Texto
CONTRIBUIÇÃO DOS SEGURADOS E Irregular, com Decisão Judicial,
PENSIONISTAS Em Análise)
REGRAS DE CONCESSÃO, CÁLCULO Status do critério (Regular, Texto
E REAJUSTAMENTO DE BENEFÍCIOS Irregular, com Decisão Judicial,
Em Análise)
UNIDADE GESTORA E REGIME Status do critério (Regular, Texto
PRÓPRIO ÚNICOS Irregular, com Decisão Judicial,
Em Análise)
UTILIZAÇÃO DOS RECURSOS Status do critério (Regular, Texto
PREVIDENCIÁRIOS - DECISÃO Irregular, com Decisão Judicial,
ADMINISTRATIVA Em Análise)
UTILIZAÇÃO DOS RECURSOS Status do critério (Regular, Texto
PREVIDENCIÁRIOS - PREVISÃO Irregular, com Decisão Judicial,
LEGAL Em Análise)
PONTUAÇÃO Pontuação do Indicador de Númerico
Regularidade
CLASSIFICAÇÃO Classificação do Indicador de Caracter
Regularidade

Tabela 2.3: Planilha Indicador de Envio de Informações


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
DRAA Indicador de envio do Inteiro
demonstrativo DRAA (Se
enviado=1 e Não enviado=0)
DAIR Indicador de envio do Inteiro
demonstrativo DAIR (Pontuação 1
para cada mês enviado)
DIPR Indicador de envio do Inteiro
demonstrativo DIPR (Pontuação 2
para cada bimestre enviado)
DPIN Indicador de envio do Inteiro
demonstrativo DPIN (Se
enviado=1 e Não enviado=0)
MSC Indicador de envio do Inteiro
demonstrativo de Matriz de
Saldos Contábeis - MSC
(Pontuação 1 para cada mês
enviado)
PONTUAÇÃO Pontuação do Indicador de Envio Númerico
de Informações Previdenciárias
CLASSIFICAÇÃO Classificação do Indicador de Caracter
Envio de Informações
Previdenciárias

Tabela 2.4: Planilha Indicador de Gestão


9

Nome da coluna/campo Descrição Tipo


ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
DATA RECEBIMENTO DO TERMO DE Data de recebimento do termo de Data
ADESÃO adesão ao programa de pró-
gestão
DATA DO TERMO DE ADESÃO Data do Termo de adesão do pró Data
gestão
DATA DA CERTIFICAÇÃO Data da Certificação do pró Data
gestão
NÍVEL DA CERTIFICAÇÃO Nível da certificaçãp obtida Texto
CLASSIFICAÇÃO Classificação do Indicador de Caracter
Melhoria da Gestão ("A" SE
OBTEVE CERTIFICAÇÃO III E
IV;"B" SE OBTEVE
CERTIFICAÇÃO I E II; "C" SE
NÃO OBTEVE CERTIFICAÇÃO)

Tabela 2.5: Planilha Indicador de Suficiência Financeira


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
RECEITAS PREVIDENCIÁRIAS Total das receitas previdenciárias Numérico
após deduções
DESPESAS PREVIDENCIÁRIAS Total das despesas Numérico
previdenciárias após deduções
PONTUAÇÃO Pontuação do Indicador de Númerico
Suficiência Financeira
CLASSIFICAÇÃO Classificação do Indicado de Caracter
Suficiência Financeira r

Tabela 2.6: Planilha Indicador de Acumulação de Recursos


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
ATIVOS – SALDO DAIR – ANO Ativos (aplicações financeiras em Numérico
ANTERIOR renda fixa/variável,
investimentos, disponibilidades
financeiras)
ATIVOS – SALDO DAIR – ANO ATUAL Ativos (aplicações financeiras em Numérico
renda fixa/variável,
investimentos, disponibilidades
financeiras)
PONTUAÇÃO Pontuação do Indicador de Númerico
Acumulação de Recursos
CLASSIFICAÇÃO Classificação do Indicador de Caracter
Acumulação de Recursos

Tabela 2.7: Planilha Indicador de Cobertura dos Compromissos Previdenciários


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
10

GRUPO Classificação do Grupo Texto


PROVISÃO BENEFÍCIOS Total de provisões Numérico
CONCEDIDOS PLANO FINANCEIRO -
CIVIL
PROVISÃO BENEFÍCIOS A Total de provisões Numérico
CONCEDER PLANO FINANCEIRO -
CIVIL
PROVISÃO BENEFÍCIOS Total de provisões Numérico
CONCEDIDOS MANTIDOS PELO
TESOURO - CIVIL
PROVISÃO BENEFÍCIOS A Total de provisões Numérico
CONCEDER MANTIDOS PELO
TESOURO - CIVIL
PROVISÃO BENEFÍCIOS Total de provisões Numérico
CONCEDITOS PLANO
PREVIDENCIÁRIO - CIVIL
PROVISÃO BENEFÍCIOS A Total de provisões Numérico
CONCEDER PLANO
PREVIDENCIÁRIO - CIVIL
PONTUAÇÃO Pontuação do Indicador de Númerico
Cobertura dos Compromissos
Previdenciários
CLASSIFICAÇÃO Classificação do Indicador de Caracter
Cobertura dos Compromissos
Previdenciários

Tabela 2.8: Planilha Resultado


Nome da coluna/campo Descrição Tipo
ENTE FEDERATIVO - UF Nome do Ente e UF Texto
GRUPO Classificação do Grupo Texto
ÍNDICE DE REGULARIDADE Classificação do Indicador de Caracter
Regularidade
ÍNDICE DE ENVIO DE INFORMAÇÕES Classificação do Envio de Caracter
Informações
ÍNDICE DE GESTÃO Classificação do Indicador de Caracter
Gestão
CLASSIFICAÇÃO EM GESTÃO E Classificação em Gestão e Caracter
TRANSPARÊNCIA Transparência (combinação dos
indicadores de regularidade,
envio de informações e gestão)
ÍNDICE DE SUFICIÊNCIA FINANCEIRA Classificação do Indicador de Caracter
Suficiência Financeira
ÍNDICE DE ACUMULAÇÃO DE Classificação do Indicador de Caracter
RECURSOS Acumulação de Recursos
CLASSIFICAÇÃO EM FINANÇAS E Classificação em Finanças e Caracter
LIQUIDEZ Liquidez (combinação dos
indicadores de suficiência
financeira e acumulação de
recursos)
ÍNDICE DE COBERTURA Classificação do Indicador de Caracter
PREVIDENCIÁRIA Cobertura Previdenciária
CLASSIFICAÇÃO EM ATUÁRIA Classificação em atuária (mesmo Caracter
que o indicador de cobertura
previdenciária)
INDICADOR DE SITUAÇÃO Classificação do Indicador de Caracter
PREVIDENCIÁRIA Situação Previdênciária –
Resultado ISP
11

PERFIL ATUARIAL Perfil Atuarial Texto

2.2 Dataset do IBGE


Os dados adquiridos são provenientes do “site” do Instituto Brasileiro de
Geografia e Estatística - IBGE (fonte: https://www.ibge.gov.br/geociencias/
downloads-geociencias.html) no formato  DBF (arquivo de banco de dados padrão
usado pelo dBASE, um sistema de gerenciamento de banco de dados. Ele organiza
dados em vários registros com campos armazenados em um tipo de dados de
matriz).
Foram 2 arquivos com dados dos entes federativos, um referente aos Estados
e o outro referente aos Municípios:
 Estado: BR_UF_2019.dbf
 Município: BR_Municipios_2019.dbf

Os arquivos se encontram se encontram no repositório .../fonte_de_dados.

Tabela 2.9: Dados dos Estados


Nome da coluna/campo Descrição Tipo
CD_UF codigo_ibge Inteiro
NM_UF Nome do Ente Texto
SIGLA_UF Sigla do Estado Texto
NM_REGIAO Nome do Município Texto

Tabela 2.10: Dados dos Municípios


Nome da coluna/campo Descrição Tipo
CD_MUN codigo_ibge Inteiro
NM_MUN Nome do Ente Texto
SIGLA_UF Sigla do Estado Texto

2.3 Dataset do IBGE - População


Os dados adquiridos são provenientes do “site” do Instituto Brasileiro de
Geografia e Estatística - IBGE (fonte: https://www.ibge.gov.br/estatisticas/sociais/
populacao/9103-estimativas-de-populacao.html) no formato Microsoft Excel®..
Foram 2 arquivos com dados de população dos entes federativos, um
referente ao ano de 2019 e o outro referente ao ano de 2020:
 Ano 2019: POP2019_20210331.xlsx
12

 Ano 2020: POP2020_20210331.xlsx

Cada arquivo possui duas planilhas, onde será lida apenas 1 delas, conforme
apresentado a seguir. Os arquivos se encontram se encontram no repositório
.../fonte_de_dados.

Tabela 2.11: Planilha Municípios


Nome da coluna/campo Descrição Tipo
UF UF Texto
COD. UF Código IBGE da UF Inteiro
COD. MUNIC Código IBGE do Município Texto
NOME DO MUNICÍPIO Nome do Município Texto
POPULAÇÃO ESTIMADA Estimativa da população Inteiro

3 Processamento/Tratamento de Dados
Antes de abordar o processamento dos dados, serão apresentados a
linguagem de programação e as bibliotecas utilizadas para processar e tratar os
dados, o banco de dados utilizado para armazenar os dados tratados e o processo
de criação do banco de dados

A seção está dividida nos seguintes tópicos:

3.1. Ferramentas utilizadas para processar e tratar dados

3.1.1.Ferramenta e linguagem de programação

3.1.2.Bibliotecas

3.1.3.Banco de Dados

3.2. Processo de criação do banco de dados

3.3. Tratamento dos dados

3.1 Ferramentas utilizadas para processar e tratar dados


13

3.1.1 Ferramenta e linguagem de programação


Para processamento e tratamento dos dados foi utilizada a linguagem Python,
sendo utilizada como ferramenta para desenvolvimento dos scripts a distribuição
Anaconda, versão 2020.11 (figura 3.1), disponível em https://www.anaconda.com/
products/individual.
14

Figura 3.1: Screenshot do Anaconda Navigator

A distribuição Anaconda foi escolhida por possuir as principais ferramentas e


bibliotecas para criação de scripts de análise de dados e aprendizado de máquinas
em seu pacote, evitando assim a necessidade de instalação manual e configuração
de cada biblioteca que seria necessária, otimizando o desenvolvimento dos scripts.

O ambiente Jupyter Notebook, incluso no pacote, foi utilizado como


ferramenta de edição de código e depuração (Figura 3.2).
15

Figura 3.2: Screenshot do Jypyter Notebook

O editor Jupyter Notebook versão 6.1.4 possui o ambiente configurado para


trabalhar sob o Python 3, incluso no pacote da distribuição Anaconda 2020.11.

3.1.2 Bibliotecas

A seguir, serão listadas as bibliotecas utilizadas necessárias para o


desenvolvimento do código (Tabela 3.1).
16

Tabela 3.1: Bibliotecas


Biblioteca Descrição Comando utilizado
Pandas Biblioteca para a linguagem Python import pandas as pd
que fornece ferramentas de análise de
dados e estruturas de dados de alta
performance
NumPy Biblioteca para a linguagem Python import numpy as np
com funções para se trabalhar com
computação numérica.
Itertools Biblioteca para a linguagem Python import itertools as it
que provê uma série de funções de
manipulação de iteráveis
Sqlalchemy Framework de mapeamento objeto- Instalação: conda install -y
relacional SQL de código aberto que -c anaconda sqlalchemy
permite a manipulação dos dados do
banco Postgres através de comandos import sqlalchemy
SQL..

Instalada à parte (não inclusa do


pacote Anaconda).

Psycopg2 Adaptador PostgreSQL mais popular Instalação: pip install


para a linguagem de programação psycopg2
Python. Utilizado pela biblioteca
Sqlalchemy para fazer a conexão com import psycopg2
o banco.

* Instalada à parte (não inclusa do


pacote Anaconda).

Dbfread Biblioteca que lê arquivos DBF Instalação: pip install


(formato de arquivo usado por bancos dbfread
de dados) e retorna os dados como
tipos de dados nativos do Python. import dbfread

* Instalada à parte (não inclusa do


pacote Anaconda).
17

3.1.3 Banco de dados


Com objetivo de guardar o histórico dos dados e análises posteriores em
diferentes ferramentas de visualização, foi utilizado o banco de dados PostgreSQL
13, disponível em https://www.postgresql.org/download/.

O PostgreSQL é um sistema de gerência de bancos de dados relacional e foi


escolhido por ser um software livre bastante consolidado.

No pacote de instalação do PostgreSQL, está incluída a ferramenta de


administração do banco de dados, pgAdmin 4 (Figura 3.3), utilizada para criar o
banco do projeto e as tabelas necessárias.

Figura 3.3: Screenshot do pgAdmin


18

3.2 Processo de criação do banco de dados


Como mencionado no item 3.1.3, a criação de um banco de dados para
armazenar os dados coletados e tratados teve o objetivo de guardar o histórico dos
dados e possibilitar análises posteriores em diferentes ferramentas de visualização.

O modelo de dados foi desenhado para guardar os dados coletados do IBGE


(entes de federativos e população) e dados coletados da SPREV (indicadores do
ISP) (Figura 3.4).

O dicionário de dados descreve os nomes das tabelas, colunas e tipos de


dados (Tabela 3.2).

O banco de dados foi criado por meio da ferramenta administrativa do


Postgres (pdAdmin). O script SQL executado se encontra no repositório
.../banco_de_dados/create_bd.sql.
19

Figura 3.4: Modelo de Dados


20

Tabela 3.2: Dicionário de dados


Tabela Coluna Tipo
codigo_ibge Integer
nome_ente Character varying
ente sigla_uf Character(2)
nome_regiao Character varying
tipo_ente Character varying
ano Integer
codigo_ibge Integer
grupo Character varying
ente_rpps subgrupo Character varying
qtd_ativos Integer
qtd_aposentados Integer
qtd_pensionistas Integer
ano Integer
codigo_ibge Integer
indicador_acumulacao_ ativos_ano_anterior Double precision
recursos ativos_ano_atual Double precision
pontuacao Double precision
classificacao Character varying
ano Integer
codigo_ibge Integer
beneficios_concedidos_fi Double precision
nanceiro
beneficios_a_conceder_fi Double precision
nanceiro
beneficios_concedidos_te Double precision
indicador_cobertura_ souro
compromisso beneficios_a_conceder_t Double precision
esouro
beneficios_concedidos_pr Double precision
evidenciario
beneficios_a_conceder_p Double precision
revidenciario
pontuacao Double precision
classificacao Character varying
ano Integer
codigo_ibge Integer
draa Integer
dair Integer
indicador_envio_
dipr Integer
informacoes
dpin Integer
msc Integer
pontuacao Double precision
classificacao Character varying
ano Integer
indicador_gestao codigo_ibge Integer
data_recebimento Date
21

data_termo Date
data_certificacao Date
nivel Character varying
classificacao Character varying
ano Integer
codigo_ibge Integer
indicador_regularidade
pontuacao Double precision
classificacao Character varying
ano Integer
codigo_ibge Integer
ind_regularidade Character(1)
ind_envio_informacoes Character(1)
ind_gestao Character(1)
classificacao_gestao Character(1)
indicador_situacao_ ind_suficiencia_financeira Character(1)
previdenciaria ind_acumulacao_recurso Character(1)
s
classificacao_financas Character(1)
ind_cobertura Character(1)
classificacao_atuaria Character(1)
resultado_isp Character(1)
perfil_atuarial Character varying
ano Integer
codigo_ibge Integer
indicador_suficiencia_ receitas Double precision
financeira despesas Double precision
pontuacao Double precision
classificacao Character varying
ano Integer
populacao codigo_ibge Integer
populacao Integer
ano Integer
codigo_ibge Integer
regularidade_extrato
criterio Character varying
situacao Character varying

3.3 Tratamento dos dados


22

3.3.1 Leitura dos arquivos de origem


Para processamento, tratamento e análise de dados, foi utilizada a linguagem
Python, via Jupyter Notebooks.

A seguir, serão apresentados os tratamentos individuais de cada arquivo de


origem:

1. Informações dos entes


2. Estimativa de população dos entes
3. Indicadores da Situação Previdenciária (ISP)

3.3.1.1 Informações dos entes


Os indicadores do ISP são calculados para os Estados e Municípios. Desta
forma, foi necessária a importação dos dados do IBGE para esses dois tipos de
ente. No IBGE, os dados de Estados e Municípios estão armazenados em arquivos
diferentes:

 Estado: BR_UF_2019.dbf
 Município: BR_Municipios_2019.dbf

Os dados foram importados do formato DBF (.dbf) de um diretório


previamente definido, para um dataframe pandas, permitindo posterior manipulação.
Assim, foi necessária a importação da biblioteca pandas e dbfread:

import pandas as pd
import dbfread

from dbfread import DBF


from pandas import DataFrame

A quantidade de registros lidos do arquivo referente aos dados de Estados


foram 27 e do arquivo referente aos dados de Municípios foram 5.572. Total de
registros lidos foi de 5.599.

file_name_UF = 'D:\\Pos-EAD\\fonte-de-dados\\
br_unidades_da_federacao\\BR_UF_2019.dbf'
file_name_MU = 'D:\\Pos-EAD\\fonte-de-dados\\
br_municipios_20200807\\BR_Municipios_2019.dbf'

#LEITURA DOS DADOS DOS ESTADOS


dbf = DBF(file_name_UF,encoding='UTF-8')
df_uf = DataFrame(iter(dbf))
# O método iter() é necessário porque o Pandas
23

# não reconhece que o objeto DBF é iterável

#LEITURA DOS DADOS DOS MUNICÍPIOS


dbf = DBF(file_name_MU,encoding='UTF-8')
df_mu = DataFrame(iter(dbf))

Para armazenar esses dados no banco de dados, foi necessária a alteração


dos nomes das colunas importadas do arquivo para os nomes das colunas do banco
de dados. E ainda, foi adicionado um novo campo, que identifica o tipo do ente:
Estado ou Município.

df_uf = df_uf.rename(columns={'CD_UF': 'codigo_ibge',


'NM_UF': ‘nome_ente',
'SIGLA_UF':'sigla_uf',
'NM_REGIAO':'nome_regiao'})
df_uf['tipo_ente'] = 'Estado'

Para os dados de municípios, foram necessários dois tratamentos adicionais.


O primeiro foi identificar a região de cada município, pois no arquivo fonte não tem
essa informação e na tabela de entes esse campo é necessário. Para isso, foi feita
uma comparação da UF de cada município com a UF dos Estados, e em seguida,
buscar a região nos dados de Estados, anteriormente carregados. O segundo
tratamento foi apagar a coluna 'AREA_KM2’ carregada do arquivo, pois não é
utilizada no projeto.

#Criação de dataframe de UF e região


df_regiao = df_uf[['sigla_uf','nome_regiao']]

#Encontrar a região para cada município


df_mu=df_mu.join(df_regiao.set_index('sigla_uf'), on='SIGLA_UF')
df_mu = df_mu.rename(columns={'CD_MUN': 'codigo_ibge',
'NM_MUN': 'nome_ente',
'SIGLA_UF':'sigla_uf'})
df_mu['tipo_ente'] = 'Município'
df_mu=df_mu.drop(columns='AREA_KM2')

Para gravação no banco de dados Postgres, foi necessária a importação das


bibliotecas psycop2 e sqlalchemy.

import psycopg2 # acesso ao banco de dados postgres


import sqlalchemy # acesso ao banco de dados postgres

A biblioteca psycopg2 é necessária para permitir que o sqlalchemy obtenha


uma conexão com o Postgres. A string de conexão é definida assim:

 'postgres+psycopg2://username:password@ipaddress:port/dbname'
24

o username: nome do usuário do servidor de banco Postgres

o password: senha do usuário do servidor de banco Postgres

o ipaddress: IP do servidor do banco Postgres

o port: porta do servidor do banco Postgres

o dbname: nome do banco de dados

# CONEXÃO COM O BANCO POSTGRES


postgres_str = 'postgres+psycopg2://postgres:postgres@
localhost:5432/indicador_previdencia'

Para que o sqlalchemy saiba sobre a instância do Postgres, criamos um


mecanismo usando a string de conexão. Para criar o mecanismo, usamos o método
create_engine do sqlalchemy:

from sqlalchemy import create_engine


engine = create_engine(postgres_str)

A partir do mecanismo, podemos criar a conexão com o banco e inserir os


dados na tabela ente. O método Dataframe.to_sql permite a inclusão de registros no
banco, passando uma conexão criada pelo sqlalchemy.

#GRAVAÇÃO DOS DADOS DE ESTADOS NA TABELA ENTE


tb_ente = 'ente'
con = engine.connect()
try:
frame = df_uf.to_sql(tb_ente, con,if_exists='append',
index=False);
except ValueError as vx:
print(vx)
except Exception as ex:
print(ex)
else:
print("Dados de Estados inseridos na tabela %s com
sucesso."%tb_ente);
finally:
con.close();

#GRAVAÇÃO DOS DADOS DE MUNICÍPIOS NA TABELA ENTE


try:
frame = df_mu.to_sql(tb_ente, con,if_exists='append',
index=False);
except ValueError as vx:
print(vx)
except Exception as ex:
print(ex)
else:
25

print("Dados de Municípios inseridos na tabela %s com


sucesso."%tb_ente);
finally:
con.close();

3.3.1.2 Estimativa de população dos entes


Foram 2 arquivos com dados de população dos entes federativos, um
referente ao ano de 2019 e o outro referente ao ano de 2020:
 Ano 2019: POP2019_20210331.xlsx
 Ano 2020: POP2020_20210331.xlsx

Os dados foram importados do formato Microsoft Excel® (.xlsx) de um


diretório previamente definido, para um dataframe pandas, permitindo posterior
manipulação. Assim, foi necessária a importação da biblioteca pandas e a utilização
do método read_excel para leitura do arquivo.

A leitura dos dois arquivos seguiu o mesmo processamento. Desta forma,


será apresentado o processo apenas do arquivo de 2019. A quantidade de registros
lidos de cada arquivo foi 5.570. Total de registros lidos foi de 11.140.

Primeiro passo foi a leitura do arquivo com o método do pandas read_excel.


Foi necessária a definição do tipo texto para os dados de código da UF e código do
município para tratamento posterior.

# CARREGAR ESTIMATIVA DA POPULAÇÃO DE 2019

sheet_pop_2019 = 'Municípios'

df_pop_MU_2019 = pd.read_excel(file_pop_2019, sheet_name =


sheet_pop_2019,header=1, usecols='A:E',
dtype={'COD. UF': str, 'COD. MUNIC':str})

Como no final do arquivo possui umas linhas de comentários, o tratamento


definido foi retirar essas linhas que foram carregadas. Para isso, selecionei um
campo obrigatório, COD. UF, para verificação. Se este campo for nulo, remover a
linha.

df_pop_MU_2019 = df_pop_MU_2019.dropna(subset=['COD. UF'])


26

O código ibge dos munícipios é formado pela junção do código da UF e


código do município. Desta forma, houve a necessidade de concatenar esses dois
códigos. Por isso, no momento da leitura do arquivo, esses códigos foram lidos
como tipo texto, para permitir a concatenação.

df_pop_MU_2019['codigo_ibge'] = df_pop_MU_2019['COD. UF'] +


df_pop_MU_2019['COD. MUNIC']

Após a carga dos dados de municípios, houve a necessidade de calcular a


estimativa da população para os Estados. Para isso, foi utilizado o método groupby
do dataframe, que permite calcular a soma de um campo, de acordo com
agrupamento de outro campo. O agrupamento definido para cálculo foi COD. UF.

#Calcula populacao dos estados, somando os dados de municípios


df_pop_MU_2019_gr=df_pop_MU_2019.groupby('COD. UF')
['POPULAÇÃO ESTIMADA'].sum()

Em seguida, foi criado um novo dataframe para juntar os dados de municípios


e Estado. E ainda, a definição de um novo campo, ano, para identificar qual ano os
dados se referem.

#Juntar dados de UF e MU
df_pop_2019 = pd.concat(
[df_pop_UF_2019,df_pop_MU_2019[['codigo_ibge',
'POPULAÇÃO ESTIMADA']]])
df_pop_2019['ano'] = 2019

O mesmo processo foi seguido para os dados de 2020. Ao final da carga


destes dados, foi criado um novo dataframe para unir os dados de 2019 e 2020.

#Juntar dados de 2019 e 2020


df_pop = pd.concat([df_pop_2019, df_pop_2020])
df_pop=df_pop.reset_index(drop=True)

Por fim, os dados foram armazenados no banco de dados, na tabela


população.

#GRAVAR DADOS NA TABELA DE POPULACAO


tb_populacao = 'populacao'
con = engine.connect()

try:
frame = df_pop.to_sql(tb_populacao, con,if_exists='append',
index=False);
27

...

O código fonte completo se encontra no repositório


.../código_fonte/ArmazenarDadosIBGE.ipynb.

3.3.1.3 Indicadores da Situação Previdenciária (ISP)


Foram 2 arquivos com dados sobre os indicadores da situação previdenciária
dos entes federativos, um referente ao ano de 2019 e o outro referente ao ano de
2020:
 Ano 2019: isp-rpps-2019-11-08-2020.xlsx
 Ano 2020: isp-rpps-2020-16-12-2020.xlsx

Cada arquivo possui várias planilhas, onde serão lidas apenas 8 delas. Os
dados foram importados do formato Microsoft Excel® (.xlsx) de um diretório
previamente definido, para um dataframe pandas, permitindo posterior manipulação.
Assim, foi necessária a importação da biblioteca pandas e a utilização do método
read_excel para leitura do arquivo.

A quantidade de registros lidos do arquivo de 2019 foi 17.104 e do arquivo de


2020 foi 17.232. Total de registros lidos foi de 34.336.

Primeiro passo foi identificar qual código IBGE corresponde com o nome do
ente lido do arquivo da SPREV. O objetivo é fazer a ligação dos registros lidos do
arquivo do IBGE. Para isso, foi criado um dataframe com o código IBGE, o nome do
ente lido do IBGE e nome do ente lido da SPREV. Para fazer a correspondência dos
nomes das duas fontes de dados, foi utilizado um dos algoritmos de similaridade
previsto no modelo de machine learning. O desenvolvimento e a análise dos
algoritmos estão demonstrados no tópico 5. Criação de Modelos de Machine
Learning.

O primeiro passo foi importar o arquivo com os algoritmos de similaridade,


MedidasSimilaridade.ipynb (fonte:?????).

if 'autoreload' not in get_ipython().extension_manager.loaded:


%load_ext autoreload
%autoreload 2

import import_ipynb
28

import MedidasSimilaridade as medida

Em seguida, foi necessário a criação de uma função que recebe dois


dataframes, um com a lista dos entes do IBGE e outro com a lista dos entes da
SPREV. A função percorre a lista da SPREV, e para cada nome do ente, percorre a
lista do IBGE, calculando a similaridade com o algoritmo ngrams_similarity (detalhes
do algoritmo na seção 5.2.2.6. N-gram). Após o cálculo com todos da lista do IBGE,
a correspondência de nomes foi dada pelo valor da similaridade mais alta.

def findCodigoIBGE(df_ibge, df_sprev):

df_retorno = pd.DataFrame(columns=['codigo_ibge','tipo_ente',
'ente_sprev','ente_ibge','grau'])

for i, l1 in df_sprev.iterrows():
s1 = l1['ente_sprev']
t1 = l1['tipo_ente']
uf1 = l1['sigla_uf']

df_similaridade = pd.DataFrame(
columns = ['codigo_ibge','tipo_ente',
'ente_sprev','ente_ibge','grau'])

for j, l2 in df_ibge.iterrows():
s2 = l2['ente_ibge']
t2 = l2['tipo_ente']
uf2 = l2['sigla_uf']
cod_ibge=l2['codigo_ibge']

if t1 == t2 and uf1 == uf2 :


grau = medida.ngrams_similarity(s1,s2,5)

df = pd.DataFrame([[cod_ibge,t1,s1, s2,grau]],
columns=['codigo_ibge','tipo_ente',
'ente_sprev','ente_ibge','grau'])
df_similaridade=df_similaridade.append(df)

vmax = df_similaridade["grau"].max()

df_similaridade =
df_similaridade[df_similaridade['grau']==vmax]

df_retorno = df_retorno.append(df_similaridade)

return df_retorno

O segundo passo foi a leitura do código e nome dos entes do IBGE, a partir
do banco de dados, uma vez que já foram carregados do arquivo e gravados
(3.3.1.1 Informações do Ente).

# Conexão com o Banco Postgres


postgres_str = 'postgres+psycopg2://
29

postgres:postgres@localhost:5432/indicador_previdencia'
engine = create_engine(postgres_str)

#CARGA DOS ENTES IBGE


tb_ente = 'ente';
df_ibge = pd.read_sql_table(tb_ente,engine)

Foi necessário criar o nome do IBGE, concatenando o nome do ente com a


sigla da UF, uma vez que o nome da SPREV é formado pelo esses dois campos.

df_ibge['ente_ibge'] = (df_ibge['nome_ente']+' - '+


df_ibge['sigla_uf']).str.upper()

O terceiro passo foi a leitura dos dados da SPREV, a partir dos arquivos de
origem, com o método do pandas read_excel. Os dados necessários para a
montagem deste dataframe foram obtidos da planilha ‘Resutlado’. Os campos
carregados foram o nome do ente, a sigla da UF e o grupo.

# Carga do arquivo ISP 2019 e 2020


# fonte: https://www.gov.br/previdencia/pt-br/assuntos/
#previdencia-no-servico-publico/indicador-de-situacao-previdenciaria

file_name_2019 = 'D:\\Pos-EAD\\fonte-de-dados\\
isp-rpps-2019-11-08-2020.xlsx'
file_name_2020 = 'D:\\Pos-EAD\\fonte-de-dados\\
isp-rpps-2020-16-12-2020.xlsx'

#CARGA DOS ENTES SPREV-ISP

# Dados de 2019
sheet_2019 = 'Resultado'

df_2019 = pd.read_excel(file_name_2019, sheet_name = sheet_2019,


usecols='A,B,D')

df_2019=df_2019.rename(columns={df_2019.columns[0]: 'ente_sprev',
df_2019.columns[1]: 'sigla_uf',
df_2019.columns[2]: 'grupo'})

#Dados de 2020
sheet_2020 = 'RESULTADO'

df_2020 = pd.read_excel(file_name_2020, sheet_name = sheet_2020,


usecols='A,B,D')

df_2020=df_2020.rename(columns={df_2020.columns[0]: 'ente_sprev',
df_2020.columns[1]: 'sigla_uf',
df_2020.columns[2]: 'grupo'})

Como foram lidos dois arquivos, foi feita a unificação dos registros de 2019 e
2020.
30

# Unificando os registros
df_sprev = df_2019.copy()
df_sprev = df_sprev.append(df_2020)

Em seguida, foi feita a identificação dos entes que são Estado e Município e a
remoção dos nomes duplicados.

#Classificação dos entes em Estados e Municípios


condicao = [df_sprev['grupo'] == 'ESTADO/DF',
df_sprev['grupo'] != 'ESTADO/DF']

resultados = ['Estado', 'Município']

df_sprev['tipo_ente'] = np.select(condicao, resultados)

df_sprev = df_sprev[['ente_sprev', 'sigla_uf', 'tipo_ente']]

df_sprev = df_sprev.drop_duplicates()
df_sprev = df_sprev.reset_index(drop=True)

Por fim, foi feita a chamada do método para descobrir o código IBGE para os
entes da SPREV. O retorno do método é um dataframe (df_cod_ibge) que contém o
código IBGE, o nome do ente do IBGE e o nome do ente da SPREV. Esse
dataframe será utilizado posteriormente, na carga das planilhas do arquivo do ISP

#Identificando o código ibge


df_cod_ibge = findCodigoIBGE(df_ibge,df_sprev)

Os próximos passos foram a leitura de cada planilha do arquivo fonte do ISP.


Os registros de cada planilha foram gravados nas tabelas do banco de dados
correspondentes.

A leitura e o tratamento de cada planilha seguiram o mesmo processamento.


Desta forma, será apresentado o processo apenas da primeira planilha.

A primeira planilha foi a relacionada aos grupos dos entes. No arquivo de


2019, a planilha é “Divisão por Grupos” e, no arquivo de 2020, é “GRUPOS”. Foram
lidos somente os dados necessários para as análises. A leitura do arquivo foi feita
com o método do pandas read_excel.

####### DADOS DE 2019 ############


sheet_grupos_2019 = 'Divisão por Grupos'

df_grupos_2019 = pd.read_excel(file_name_2019,
sheet_name = sheet_grupos_2019,
header=1, usecols='A,D:H')
31

df_grupos_2019 = df_grupos_2019.rename(columns={
df_grupos_2019.columns[0]:'ente_uf',
df_grupos_2019.columns[1]: 'grupo',
df_grupos_2019.columns[2]: 'subgrupo',
df_grupos_2019.columns[3]: 'qtd_ativos',
df_grupos_2019.columns[4]: 'qtd_aposentados',
df_grupos_2019.columns[5]: 'qtd_pensionistas'})

####### DADOS DE 2020 ############


sheet_grupos_2020 = 'GRUPOS'

df_grupos_2020 = pd.read_excel(file_name_2020,
sheet_name = sheet_grupos_2020,
usecols='A:F')

df_grupos_2020=df_grupos_2020.rename(columns={
df_grupos_2020.columns[0]: 'ente_uf',
df_grupos_2020.columns[1]: 'grupo',
df_grupos_2020.columns[2]: 'subgrupo',
df_grupos_2020.columns[3]: 'qtd_ativos',
df_grupos_2020.columns[4]: 'qtd_aposentados',
df_grupos_2020.columns[5]: 'qtd_pensionistas'})

Após a leitura de cada arquivo, foi adicionado um campo a mais para


identificar o ano as quais os registros se referem e feita a junção dos registros de
2019 com o de 2010 no mesmo dataframe.

df_grupos_2019['ano'] = 2019

df_grupos_2020['ano'] = 2020

#Juntar dados de 2019 e 2020


df_grupos = pd.concat([df_grupos_2019, df_grupos_2020])

Em seguida, foi feita a identificação dos entes que são Estado e Município.

#Classificação dos entes em Estados e Municípios


condicao = [df_grupos['grupo'] == 'ESTADO/DF',
df_grupos['grupo'] != 'ESTADO/DF']

resultados = ['Estado', 'Município']

df_grupos['tipo_ente'] = np.select(condicao, resultados)


32

Em seguida, foi feita a busca pelo código IBGE de cada ente, utilizando o
dataframe carregado previamente (df_cod_ibge).

#Carga do código ibge


df_grupos=df_grupos.join(df_cod_ibge.set_index(['ente_sprev',
'tipo_ente']), on=['ente_uf','tipo_ente'])

Por fim, os dados foram armazenados no banco de dados, na tabela


ente_rpps.

#GRAVAR DADOS NA TABELA DE ENTES-RPPS


tb_ente_rpps = 'ente_rpps';
con = engine.connect()

try:
df_entes_rpps = df_grupos[['ano', 'codigo_ibge', 'grupo',
'subgrupo', 'qtd_ativos',
'qtd_aposentados', 'qtd_pensionistas']]

frame = df_entes_rpps.to_sql(tb_ente_rpps, con,


if_exists='append',index=False);
except ValueError as vx:
print(vx)
except Exception as ex:
print(ex)
else:
print("Dados inseridos na tabela %s com sucesso."%tb_ente_rpps);
finally:
con.close();

As demais planilhas seguiram o mesmo processamento e carregadas nas


seguintes tabelas do banco de dados:

Tabela 3.3: Correspondência das planilhas com as tabelas


Planilha
Tabela
isp-rpps-2019 isp-rpps-2020
Divisão por Grupos GRUPOS ente_rpps
Ind. de Regularidade CRITÉRIOS regularidade_extrato
Ind. de Regularidade REGULARIDADE indicador_regularidade
Ind. de Envio de ENVIOS indicador_envio_informacoes
Informações
Ind. de Gestão GESTÃO indicador_gestao
Ind. de Suficiência SUFICIÊNCIA indicador_suficiencia_financeira
Finance
Ind. de Acumulação de ACUMULAÇÃO indicador_acumulacao_recursos
Recursos
Ind. Cobertura COBERTURA indicador_cobertura_compromiss
Previdenciária o
Resultado RESULTADO indicador_situacao_previdenciaria
O código fonte completo se encontra no repositório
.../código_fonte/ArmazenarDadosISP.ipynb.
33

4 Análise e Exploração dos Dados


Como o projeto foi desenvolvido para atender à Subsecretaria dos Regimes
Próprios de Previdência Social – SRPPS, no intuito de dar visibilidade aos entes
sobre o Indicador de Situação Previdenciária, a análise e exploração seguiu as
métricas apresentadas pela área. São elas:
 Percentual dos entes com RPPS em relação ao total de entes (Estados
e Municípios);
 Percentual de segurados ativos, aposentados e pensionistas em
relação à população;
 Percentual dos entes classificados por grupo e subgrupo em relação ao
total de entes RPPS;
 Para o indicador de regularidade, percentual das classificações (A, B,
C) em relação ao total de entes RPPS;
 Para o indicador de envio de informações, percentual do envio de
demonstrativos em relação ao total de demonstrativos;
 Para o indicador de gestão, quantidade de entes com nível de
certificação I, II, III e IV;
 Para o indicador de suficiência financeira:
o percentual das classificações (A, B, C) em relação ao total de
entes RPPS
o média da pontuação por região e UF
o total de receitas e despesas por região e UF
 Para o indicador de acumulação de recursos:
o percentual das classificações (A, B, C) em relação ao total de
entes RPPS
o média da pontuação por região e UF
o total dos ativos por região e UF
 Para o indicador de cobertura de compromisso:
o percentual das classificações (A, B, C) em relação ao total de
entes RPPS
o média da pontuação por região e UF
34

o total dos benefícios por região e UF

A análise foi feita através da ferramenta de visualização, Power BI. O resultado


será apresentado na seção 6 (Apresentação dos Resultados).

4.1 Percentual dos entes com RPPS em relação ao total de entes (Estados e
Municípios)
Primeiro, foi calculado o total de entes com RPPS, obtido da tabela ente_rpps.
Em seguida, dividiu-se esse número pelo total geral de entes, obtido da tabela entes.

4.2 Percentual de segurados ativos, aposentados e pensionistas em relação à


população
A estimativa da população foi calculada através do somatório do campo obtido
do arquivo de população do IBGE. O percentual dos segurados é calculado dividindo
o somatório dos segurados ativos, aposentados e pensionistas pela estimativa da
população do ente.

4.3 Percentual dos entes classificados por grupo e subgrupo em relação ao to-
tal de entes RPPS
Para o primeiro percentual, foi calculada a quantidade de entes classificados
por grupo (pequeno porte, médio porte, grande porte, Estados/DF, não
classificados). Em seguida, dividiu-se a quantidade de cada grupo pelo número de
entes com RPPS.
Para o segundo percentual, obtêm-se a quantidade de entes classificados por
subgrupo (menor maturidade, maior maturidade). Em seguida, dividiu-se a
quantidade de cada subgrupo pelo número de entes com RPPS.

4.4 Para o indicador de regularidade, percentual das classificações (A, B, C)


em relação ao total de entes RPPS
Primeiro, foi calculada a quantidade de entes classificados em A, B e C. Em
seguida, dividiu-se a quantidade de cada classificação pelo número de entes com
RPPS.
35

4.5 Para o indicador de envio de informações, percentual do envio de demon-


strativos em relação ao total de demonstrativos
Cada demonstrativo tem uma quantidade máxima que deve ser enviado por
ano (DAIR:12, DIPR:1, DPIN:12, DRAA:1, MSC:12).
Para cada demonstrativo, o percentual é obtido com o somatório da quantidade
de demonstrativos enviados, dividindo pela quantidade máxima.

4.6 Para o indicador de gestão, quantidade de entes com nível de certificação


I, II, III e IV
Para essa métrica, foi calculado o somatório dos entes por nível de certificação
(I, II, III e IV).

4.7 Para o indicador de suficiência financeira: percentual das classificações


em relação ao total de entes RPPS, média da pontuação por região e UF,
total de receitas e despesas por região e UF
Para a primeira métrica, foi calculada a quantidade de entes classificados em
A, B e C. Em seguida, dividiu-se a quantidade de cada classificação pelo número de
entes com RPPS.
Para a segunda métrica, foi calculada a média da pontuação dos entes para
esse indicador.
Para a terceira métrica, foi calculado o somatório das receitas e despesas dos
entes.

4.8 Para o indicador de acumulação de recursos: percentual das classifi-


cações em relação ao total de entes RPPS, média da pontuação por
região e UF, total dos ativos por região e UF
Para a primeira métrica, foi calculada a quantidade de entes classificados em
A, B e C. Em seguida, dividiu-se a quantidade de cada classificação pelo número de
entes com RPPS.
Para a segunda métrica, foi calculada a média da pontuação dos entes para
esse indicador.
Para a terceira métrica, foi calculado o somatório das ativos dos entes.
36

4.9 Para o indicador de cobertura de compromisso: percentual das classifi-


cações em relação ao total de entes RPPS, média da pontuação por
região e UF, total dos benefícios por região e UF
Para a primeira métrica, foi calculada a quantidade de entes classificados em
A, B e C. Em seguida, dividiu-se a quantidade de cada classificação pelo número de
entes com RPPS.
Para a segunda métrica, foi calculada a média da pontuação dos entes para
esse indicador.
Para a terceira métrica, foi calculado o somatório dos benefícios dos entes.

5 Criação de Modelos de Machine Learning


Modelo de machine learning foi utilizado no trabalho para permitir a
combinação dos dados obtidos das diferentes fontes, site do IBGE
(https://www.ibge.gov.br) e da SPREV
(https://www.gov.br/previdencia/pt-br/assuntos/previdencia-no-servico-publico/
indicador-de-situacao-previdenciaria).
Nos dados do IBGE, cada registro representa os dados dos entes (Estados ou
Municípios) e possuem uma identificação única, o código IBGE. Nos dados da
SPREV, a identificação dos registros é feita pela junção do nome do Município e
sigla do Estado (ex.: São Paulo – SP).
Para possibilitar a análise dos entes entre as fontes, foi necessário descobrir
quais registros da base do IBGE refere-se aos entes da base da SPREV. A
informação mais semelhante entre as duas fontes é o nome do Município e o nome
do Estado. Observando os registros de ambas as fontes, notou-se que alguns
nomes representando o mesmo ente, possuem grafia diferente nas bases. Exemplo:
o município “BRASÓPOLIS - MG” na fonte da SPREV está como “BRAZÓPOLIS –
MG” na fonte IBGE.
Os algoritmos de similaridades apresentados nos modelos de machine
learning permitem a descoberta de nomes semelhantes entre duas fontes distintas.
Desta forma, neste tópico, serão analisados alguns algoritmos de similaridade para
escolher qual melhor atenda a proposta do projeto.
37

5.1 Algoritmos de Similaridade


As palavras podem ser semelhantes de duas maneiras, lexicamente e
semanticamente. As palavras são lexicalmente semelhantes se têm uma sequência
de caracteres semelhante. Palavras são semanticamente semelhantes se tem o
mesmo sentido, podendo ter grafia diferente.
Em [REF1], são apresentados os algoritmos de similaridade mais comuns. A
semelhança lexical pode ser obtida através de algoritmos baseados em caracteres
ou baseados em termos, e a semelhança semântica pode ser feita pelos algoritmos
baseados em corpo (corpus-based) e baseados em conhecimento.
Os algoritmos de similaridade discutido neste trabalho levará em
consideração apenas a semelhança lexical. E ainda, como os termos analisados
possuem tamanho pequeno, o foco será nos algoritmos baseados em caracteres.
De acordo com [REF1], os algoritmos baseados em caracteres, que mede a
semelhança ou dissimilaridade (distância) entre duas strings são (Figura 5.1):

Figura 5.1: Medidas de Similaridade baseada em caractere

Fonte [REF1]

 LCS - Longest Common SubString (sequência comum mais longa): o


algoritmo considera que a similaridade entre duas strings é baseada no
38

comprimento da sequência comum de caracteres que existe em ambas as


strings.
 Damerau-Levenshtein: define a distância entre duas strings contando o número
mínimo de operações necessárias para transformar uma string em outra, onde
uma operação é definida como uma inserção, exclusão ou substituição de um
único caractere, ou uma transposição de dois caracteres adjacentes.
 Jaro: baseado no número e na ordem do caracter comum entre duas strings;
leva em consideração desvios ortográficos típicos.
 Jaro – Winkler: extensão da distância Jaro; usa uma escala de prefixo que dá
classificações mais favoráveis às strings que correspondem desde o início até
um comprimento de prefixo definido.
 Needleman-Wunsch: exemplo de programação dinâmica e foi a primeira
aplicação para comparação de sequência biológica. Executa um alinhamento
global para encontrar o melhor alinhamento em toda as duas sequências. É
adequado quando as duas sequências são de comprimento semelhante e com
um grau significativo de semelhança.
 Smith-Waterman: outro exemplo de programação dinâmica. É realizado um
alinhamento local para encontrar o melhor alinhamento sobre duas sequências.
Isto é útil para sequências diferentes que podem conter regiões semelhantes.
 N-gram: é uma sub-sequência de n itens de uma determinada sequência de
texto. Algoritmos de similaridade de N-gram comparam os n-gramas de cada
caractere ou palavra em duas strings. A distância é calculada dividindo o número
de n-gramas semelhantes por número máximo de n-gramas.

5.2 Análise dos algoritmos


O objetivo do tópico é analisar e testar os algoritmos apresentados para
selecionar o melhor que atenda a necessidade do escopo do projeto.
O algoritmo de Needleman-Wunsch não foi analisado, pois é apropriado para
sequências biológicas e de tamanhos semelhantes. Os termos que serão analisados
no presente trabalho não se referem a essas sequências.
39

5.2.1 Dados de Teste


A fonte de dados do IBGE possui 5.599 entes e a fonte da SPREV trabalha
com 2.154 entes. Desta forma, é necessário achar os 2.154 entes da SPREV
correspondentes com os entes do IBGE.
Para escolher o algoritmo, o teste será feito utilizando apenas dez nomes de
entes da fonte do IBGE e cinco nomes de entes da fonte do SPREV. O objetivo é
encontrar os cinco nomes da fonte SPREV semelhantes com os nomes da fonte
IBGE.

Entrada de dados
 Nomes da fonte IBGE
1. BAHIA – BA
2. DISTRITO FEDERAL – DF
3. GOIÁS – GO
4. RIO DE JANEIRO - RJ
5. RIO GRANDE DO NORTE – RN
6. RIO GRANDE DO SUL – RS
7. SANTA CATARINA – SC
8. JANUÁRIO CICCO – RN
9. SÃO LUÍS DO QUITUNDE – AL
10. SÃO LUIS DO CURU – CE
 Nomes da fonte SPREV
1. GOVERNO DO DISTRITO FEDERAL – DF
2. GOVERNO DO ESTADO DA BAHIA – BA
3. GOVERNO DO ESTADO DE GOIÁS – GO
4. BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN
5. SÃO LUIZ DO QUITUNDE – AL

Resultado esperado
NOME SPREV NOME IBGE
GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF
GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA
GOVERNO DO ESTADO DE GOIÁS – GO GOIÁS - GO
BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – JANUÁRIO CICCO – RN
RN
SÃO LUIZ DO QUITUNDE – AL SÃO LUÍS DO QUITUNDE – AL
40

5.2.2 Implementação do Teste


Os algoritmos de similaridade e o teste foram desenvolvidos na linguagem
Python estão disponíveis em ????????.

O primeiro passo foi desenvolver cada algoritmo. O código-fonte será


apresentado no tópico de cada algoritmo.

Em seguida, foi desenvolvido o algoritmo de teste:

def findSimilaridade(df_all, df_find,tipo):

df_retorno = pd.DataFrame(
columns=['SPREV','IBGE','SIMILARIDADE'])

for s1 in df_find:
df_similaridade = pd.DataFrame(
columns=['s1','s2','grau'])

for s2 in df_all:

if tipo == 'levenshtein':
grau = medida.levenshtein_similarity(s1,s2)
elif tipo == 'hamming':
grau = medida.hamming_similarity(s1,s2)
elif tipo == 'jaro':
grau = medida.jaro_similarity(s1,s2)
elif tipo == 'jaro_winkler':
grau = medida.jaro_winkler_similarity(s1,s2)
elif tipo == 'lcf':
grau = medida.lcf_similarity(s1,s2)
elif tipo == 'ngram':
grau = medida.trigrams_similarity(s1,s2)
elif tipo == 'smith_waterman':
grau = medida.smith_waterman_similarity(s1,s2)
else :
grau=0

df = pd.DataFrame([[s1, s2,grau]],
columns=['s1','s2','grau'])
df_similaridade=df_similaridade.append(df)

vmax = df_similaridade["grau"].max()

df_similaridade = df_similaridade[
df_similaridade['grau']== vmax]

nomes = df_similaridade["s2"].str.cat(sep=';')

df = pd.DataFrame([[s1, nomes, vmax]],


columns=['SPREV','IBGE','SIMILARIDADE'])
df_retorno = df_retorno.append(df)

return df_retorno
41

O teste consiste em receber duas listas de nomes: um com todos os nomes


dos entes e o outro com os nomes dos entes cuja semelhança será buscada. O
teste ainda recebe um parâmetro adicional, para indicar qual algoritmo será usado
para o cálculo de similaridade.

Para cada nome da lista de busca, é calculada a similaridade com cada um


da lista com todos os nomes. O nome mais semelhante é aquele cuja similaridade
possui o maior valor.

O retorno será uma lista de nomes semelhantes entre as duas listas.

Demonstrando o algoritmo com os dados de testes e com o método de LCS,


temos:

Loop 1
Nome para GOVERNO DO DISTRITO FEDERAL – DF
pesquisa:
SPREV IBGE SIMILARIDADE
0 GOVERNO DO DISTRITO FEDERAL – DF BAHIA – BA 0.09375
1 GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.65625
2 GOVERNO DO DISTRITO FEDERAL – DF GOIÁS – GO 0.06250
3 GOVERNO DO DISTRITO FEDERAL – DF RIO DE JANEIRO – RJ 0.09375
Cálculo da 4 GOVERNO DO DISTRITO FEDERAL – DF RIO GRANDE DO NORTE – RN 0.12500
Similaridade 5 GOVERNO DO DISTRITO FEDERAL – DF RIO GRANDE DO SUL – RS 0.12500
6 GOVERNO DO DISTRITO FEDERAL – DF SANTA CATARINA – SC 0.09375
7 GOVERNO DO DISTRITO FEDERAL – DF JANUÁRIO CICCO – RN 0.09375
8 GOVERNO DO DISTRITO FEDERAL – DF SÃO LUÍS DO QUITUNDE – AL 0.12500
9 GOVERNO DO DISTRITO FEDERAL – DF SÃO LUIS DO CURU – CE 0.12500

Retorno : maior SPREV IBGE SIMILARIDADE


0 GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.65625
similaridade
Loop 2
Nome para GOVERNO DO ESTADO DA BAHIA – BA
pesquisa:
SPREV IBGE SIMILARIDADE
0 GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA 0.322581
1 GOVERNO DO ESTADO DA BAHIA – BA DISTRITO FEDERAL – DF 0.096774
2 GOVERNO DO ESTADO DA BAHIA – BA GOIÁS – GO 0.064516
3 GOVERNO DO ESTADO DA BAHIA – BA RIO DE JANEIRO – RJ 0.096774
Cálculo da 4 GOVERNO DO ESTADO DA BAHIA – BA RIO GRANDE DO NORTE – RN 0.129032
Similaridade 5 GOVERNO DO ESTADO DA BAHIA – BA RIO GRANDE DO SUL – RS 0.129032
6 GOVERNO DO ESTADO DA BAHIA – BA SANTA CATARINA – SC 0.129032
7 GOVERNO DO ESTADO DA BAHIA – BA JANUÁRIO CICCO – RN 0.096774
8 GOVERNO DO ESTADO DA BAHIA – BA SÃO LUÍS DO QUITUNDE – AL 0.129032
9 GOVERNO DO ESTADO DA BAHIA – BA SÃO LUIS DO CURU – CE 0.129032

SPREV IBGE SIMILARIDADE


Retorno : maior 0 GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.656250
similaridade 1 GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA 0.322581

Loop 3
Nome para GOVERNO DO ESTADO DE GOIÁS – GO
pesquisa:
SPREV IBGE SIMILARIDADE
0 GOVERNO DO ESTADO DE GOIÁS – GO BAHIA – BA 0.096774
1 GOVERNO DO ESTADO DE GOIÁS – GO DISTRITO FEDERAL – DF 0.096774
2 GOVERNO DO ESTADO DE GOIÁS – GO GOIÁS – GO 0.193548
3 GOVERNO DO ESTADO DE GOIÁS – GO RIO DE JANEIRO – RJ 0.161290
Cálculo da 4 GOVERNO DO ESTADO DE GOIÁS – GO RIO GRANDE DO NORTE – RN 0.129032
Similaridade 5 GOVERNO DO ESTADO DE GOIÁS – GO RIO GRANDE DO SUL – RS 0.129032
6 GOVERNO DO ESTADO DE GOIÁS – GO SANTA CATARINA – SC 0.096774
7 GOVERNO DO ESTADO DE GOIÁS – GO JANUÁRIO CICCO – RN 0.096774
8 GOVERNO DO ESTADO DE GOIÁS – GO SÃO LUÍS DO QUITUNDE – AL 0.129032
9 GOVERNO DO ESTADO DE GOIÁS – GO SÃO LUIS DO CURU – CE 0.129032

SPREV IBGE SIMILARIDADE


Retorno : maior 0 GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.656250
1 GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA 0.322581
similaridade 2 GOVERNO DO ESTADO DE GOIÁS – GO GOIÁS – GO 0.193548
42

Loop 4
Nome para BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN
pesquisa:
SPREV IBGE SIMILARIDADE
0 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN BAHIA – BA 0.078947
1 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN DISTRITO FEDERAL – DF 0.078947
2 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN GOIÁS - GO 0.052632
3 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN RIO DE JANEIRO – RJ 0.105263
Cálculo da 4 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN RIO GRANDE DO NORTE – RN 0.131579
Similaridade 5 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN RIO GRANDE DO SUL – RS 0.105263
6 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN SANTA CATARINA – SC 0.078947
7 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN JANUÁRIO CICCO – RN 0.368421
8 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN SÃO LUÍS DO QUITUNDE – AL 0.078947
9 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN SÃO LUIS DO CURU – CE 0.078947

SPREV IBGE SIMILARIDADE


0 GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.656250
Retorno : maior 1 GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA 0.322581
similaridade 2 GOVERNO DO ESTADO DE GOIÁS – GO GOIÁS – GO 0.193548
3 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN JANUÁRIO CICCO – RN 0.368421

Loop 5
Nome para SÃO LUIZ DO QUITUNDE – AL
pesquisa:
SPREV IBGE SIMILARIDADE
0 SÃO LUIZ DO QUITUNDE – AL BAHIA – BA 0.12
1 SÃO LUIZ DO QUITUNDE – AL DISTRITO FEDERAL – DF 0.12
2 SÃO LUIZ DO QUITUNDE – AL GOIÁS – GO 0.04
3 SÃO LUIZ DO QUITUNDE – AL RIO DE JANEIRO – RJ 0.12
Cálculo da 4 SÃO LUIZ DO QUITUNDE – AL RIO GRANDE DO NORTE – RN 0.16
Similaridade 5 SÃO LUIZ DO QUITUNDE – AL RIO GRANDE DO SUL – RS 0.16
6 SÃO LUIZ DO QUITUNDE – AL SANTA CATARINA – SC 0.12
7 SÃO LUIZ DO QUITUNDE – AL JANUÁRIO CICCO – RN 0.12
8 SÃO LUIZ DO QUITUNDE – AL SÃO LUÍS DO QUITUNDE – AL 0.68
9 SÃO LUIZ DO QUITUNDE – AL SÃO LUIS DO CURU – CE 0.28

SPREV IBGE SIMILARIDADE


0 GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.656250
Retorno : maior 1 GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA 0.322581
2 GOVERNO DO ESTADO DE GOIÁS – GO GOIÁS – GO 0.193548
similaridade 3 BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN JANUÁRIO CICCO – RN 0.368421
4 SÃO LUIZ DO QUITUNDE – AL SÃO LUÍS DO QUITUNDE – AL 0.680000

A seguir, será apresentado o resultado para cada um dos algoritmos


analisados.

5.2.2.1 Algoritmo LCS - Longest Common SubString (sequência comum mais


longa):dadas duas strings 'X' e 'Y', encontrar o comprimento da substring
comum mais longa [REF2].

def lcf_distance(s1, s2):

m = len(s1)
n = len(s2)

# Criação de tabela para armazenar a sequência comum mais


# longa das substrings
# LCSuff: tabela com valores 0 em cada célula
LCSuff = [[0 for k in range(n+1)] for l in range(m+1)]

# Resultado para armazenar o tamanho da substring


# mais longa
result = 0
43

for i in range(m + 1):


for j in range(n + 1):
if (i == 0 or j == 0):
LCSuff[i][j] = 0
elif (s1[i-1] == s2[j-1]):
LCSuff[i][j] = LCSuff[i-1][j-1] + 1
result = max(result, LCSuff[i][j])
else:
LCSuff[i][j] = 0
return result

O cálculo da similaridade é feito obtendo o tamanho da sequência comum


mais longa entre as duas strings, dividindo pelo tamanho da maior string.

def lcf_similarity(s1,s2):
lcf_length = lcf_distance(s1,s2)
return lcf_length / max(len(s1),len(s2))

Resultado

5.2.2.2 Damerau-Levenshtein: calcula o número de operações necessárias para


transformar uma string em outra [REF3]:
def levenshtein_distance(s1, s2):
size_x = len(s1) + 1
size_y = len(s2) + 1

#Iniciando uma matriz vazia que tem o tamanho


# do comprimento das strings.
matrix = np.zeros ((size_x, size_y))

#A primeira linha e a primeira coluna são preenchidas


#com valores sequenciais, começando do zero.
for x in range(size_x):
matrix [x, 0] = x
for y in range(size_y):
matrix [0, y] = y

#Em seguida, seguem-se dois loops para comparar as


#strings letra por letra - linha e coluna.
# - Se duas letras são iguais, o novo valor na
# posição [x, y] é o mínimo entre o valor da
# posição [x-1, y] + 1, posição [x-1, y-1] e
44

# posição [x, y-1] + 1.


# - Caso contrário, é o mínimo entre o valor da
# posição [x-1, y] + 1, posição [x-1, y-1] + 1
# e posição [x, y-1] + 1.
for x in range(1, size_x):
for y in range(1, size_y):
if s1[x-1] == s2[y-1]:
matrix [x,y] = min(
matrix[x-1, y] + 1,
matrix[x-1, y-1],
matrix[x, y-1] + 1
)
else:
matrix [x,y] = min(
matrix[x-1,y] + 1,
matrix[x-1,y-1] + 1,
matrix[x,y-1] + 1
)

#A distância é o valor na última posição da matriz


return (matrix[size_x - 1, size_y - 1])

Segundo, [REF3], o cálculo da função de similaridade de levenshtein é feito


pela fórmula:

def levenshtein_similarity(s1,s2):
return 1 –
(levenshtein_distance(s1,s2)/max(len(s1), len(s2)))

Resultado

Foi observado que para o caso do nome “GOVERNO DO ESTADO DA


BAHIA” foi encontrado 4 nomes do IBGE com mesma similaridade. Desta forma,
esse algoritmo não atende ao objetivo do trabalho.
45

5.2.2.3 Jaro: estabelece que dadas duas strings, x e y, a similaridade de Jaro é


calculada usando a fórmula [REF3]:

onde:
 m é o número de correlações entre caracteres;
 |x| e |y| são os tamanhos de x e y, respectivamente;
 t é o número de transposições.

def jaro_similarity(s1, s2):

# Retorna 1 se as duas strings são iguais


if (s1 == s2):
return 1.0

# Tamanho das strings


len1 = len(s1)
len2 = len(s2)

# Distância máxima o qualé permitido


max_dist = floor(max(len1, len2) / 2) - 1

# Números de correspondências
match = 0

# Hash para correspondências


hash_s1 = [0] * len(s1)
hash_s2 = [0] * len(s2)

# Percorrendas strings procurando as correspondências


for i in range(len1):

for j in range(max(0, i - max_dist),


min(len2, i + max_dist + 1)):

if (s1[i] == s2[j] and hash_s2[j] == 0):


hash_s1[i] = 1
hash_s2[j] = 1
match += 1
break

# Se não houve nenhum caracter correspondente, retorna 0


if (match == 0):
return 0.0

# Número de transposições
t = 0
point = 0

# Conta o número de ocorrências onde dois caracteres


# são correspondentes
for i in range(len1):
if (hash_s1[i]):
46

while (hash_s2[point] == 0):


point += 1

if (s1[i] != s2[point]):
point += 1
t += 1
t = t//2

#Cálculo da similaridade
return (match/ len1 + match / len2 +
(match - t + 1) / match)/ 3.0

Resultado

Foi observado que para o caso do nome “GOVERNO DO ESTADO DA


BAHIA”, “GOVERNO DO ESTADO DE GOIÁS” e “JANUÁRIO CICCO”, apesar de a
similaridade ser a mais alta, não corresponde com o nome da fonte do IBGE. Desta
forma, esse algoritmo não atende ao objetivo do trabalho.

5.2.2.4 Jaro-Winkler: baseado na similaridade de Jaro. O algoritmo difere quando o


prefixo de duas strings se correspondem. Jaro - Winkler usa uma escala de
prefixo 'p' que dá uma resposta mais precisa quando as strings têm um
prefixo comum até um comprimento máximo definido [REF3]:
def jaro_winkler_similarity(s1, s2) :

jaro_dist = jaro_similarity(s1, s2);

if (jaro_dist > 0.7) :

prefix = 0;

for i in range(min(len(s1), len(s2))) :

if (s1[i] == s2[i]) :
prefix += 1;

else :
47

break;

prefix = min(4, prefix);

jaro_dist += 0.1 * prefix * (1 - jaro_dist);

return jaro_dist;

Resultado

Foi observado que para o caso do nome “GOVERNO DO ESTADO DA


BAHIA”, “GOVERNO DO ESTADO DE GOIÁS” e “JANUÁRIO CICCO”, apesar de a
similaridade ser a mais alta, não corresponde com o nome da fonte do IBGE. Desta
forma, esse algoritmo não atende ao objetivo do trabalho.

5.2.2.5 Smith-Waterman: realiza alinhamento local de sequências, construindo


uma matriz de pontuação para medir a similaridade entre os caracteres. Em
seguida, o processo de traceback começa da célula da matriz de pontuação
mais alta e continua até que uma célula com pontuação zero seja
encontrada [REF4]:
# Smith-Waterman constrói matriz de similaridade.
def sw_matrix(a, b, match_score=3, gap_cost=2):
H = np.zeros((len(a) + 1, len(b) + 1), np.int)

for i, j in it.product(range(1, H.shape[0]), range(1,


H.shape[1])):
match = H[i - 1, j - 1] + (match_score if a[i - 1] ==
b[j - 1] else - match_score)
delete = H[i - 1, j] - gap_cost
insert = H[i, j - 1] - gap_cost
H[i, j] = max(match, delete, insert, 0)
return H

def sw_traceback(H, b, b_='', old_i=0):


H_flip = np.flip(np.flip(H, 0), 1)
i_, j_ = np.unravel_index(H_flip.argmax(), H_flip.shape)
i, j = np.subtract(H.shape, (i_ + 1, j_ + 1))
if H[i, j] == 0:
return b_, j
48

b_ = b[j - 1] + '-' + b_ if old_i - i > 1 else b[j - 1] + b_


return sw_traceback(H[0:i, 0:j], b, b_, i)

#similaridade= tamanho da sequência alinhada/tamanho da maior


# string
def smith_waterman_similarity(s1, s2):
s1, s2 = s1.upper(), s2.upper()
match_score=3
gap_cost=2
H = sw_matrix(s1, s2, match_score, gap_cost)
b_, pos = sw_traceback(H, s2)

return len(b_)/max(len(s1),len(s2))

Resultado

Foi observado que para o caso do nome “GOVERNO DO ESTADO DA


BAHIA”, apesar de a similaridade ser a mais alta, não corresponde com o nome da
fonte do IBGE. Desta forma, esse algoritmo não atende ao objetivo do trabalho.

5.2.2.6 N-gram: compara os n-gramas de cada caractere ou palavra em duas


strings. A distância é calculada dividindo o número de n-gramas
semelhantes por número máximo de n-gramas [REF3]:
# ngrams gera um conjunto de todas as substrings que podem ser
# geradas a partir de uma determinada string (sequence)
def ngrams(sequence, n):
count = max(0, len(sequence) - n + 1)

grams = list()
for i in range(count):
grams.append(sequence[i:i+n])

return grams

# gera os q-grams de tamanho 3 de cada string s1 e s2.


# A similaridade é calculada dividindo a quantide de
# q-grams idênticos entre as 2 strings com a quantidade
# máxima de n-grams.
def ngrams_similarity(s1,s2,n):
grams1 = ngrams(s1,n)
grams2 = ngrams(s2,n)
49

iguais=0
for g1 in grams1:
for g2 in grams2:
if g1 == g2 :
iguais=iguais+1

return iguais/max(len(grams1),len(grams2))

Resultado

OBS: O teste foi executado para formar conjuntos com 3 ngrams.

5.3 Avaliação Final


Após os testes dos seis algoritmos de similaridade, somente dois atenderam
aos objetivos do trabalho: encontrar a maior semelhança entre apenas dois nomes,
dado dois conjuntos de nomes.
A tabela 5.1 apresenta os nomes correspondentes esperados e, para cada
algoritmo, se atendeu ou não ao esperado.

Tabela 5.1: Avaliação dos algoritmos


Levein Jaro- Smith-
NOME SPREV NOME IBGE LCS Jaro N-gram
shtein Winkler Waterman

GOVERNO DO DISTRITO DISTRITO


SIM SIM SIM SIM SIM SIM
FEDERAL – DF FEDERAL – DF

GOVERNO DO ESTADO BAHIA – BA


SIM NÃO NÃO NÃO NÃO SIM
DA BAHIA – BA

GOVERNO DO ESTADO GOIÁS - GO


SIM NÃO NÃO NÃO SIM SIM
DE GOIÁS – GO

BOA SAÚDE (ANTIGO JANUÁRIO CICCO


SIM SIM NÃO NÃO SIM SIM
JANUÁRIO CICCO) – RN – RN

SÃO LUIZ DO QUITUNDE SÃO LUÍS DO


SIM SIM SIM SIM SIM SIM
– AL QUITUNDE – AL
50

A Tabela 5.2 apresenta a similaridade dos nomes dos algoritmos que


atenderam o resultado.

Tabela 5.2: Similaridade dos algoritmos


Similaridade
NOME SPREV NOME IBGE
LCS N-gram

GOVERNO DO DISTRITO FEDERAL – DF DISTRITO FEDERAL – DF 0.656250 0.633333

GOVERNO DO ESTADO DA BAHIA – BA BAHIA – BA 0.322581 0.310345

GOVERNO DO ESTADO DE GOIÁS – GO GOIÁS - GO 0.193548 0.206897

BOA SAÚDE (ANTIGO JANUÁRIO CICCO) – RN JANUÁRIO CICCO – RN 0.368421 0.416667

SÃO LUIZ DO QUITUNDE – AL SÃO LUÍS DO QUITUNDE – AL 0.680000 0.826087

O algoritmo escolhido a ser utilizado no projeto será o N-gram, devido ao


valor da similaridade ser maior, na maioria dos casos, do que o valor do LCS.

6 Apresentação dos Resultados

A apresentação dos resultados foi feita na ferramenta de visualização de


dados Microsoft Power BI.
O Microsoft Power BI é a ferramenta de Business Intelligence da Microsoft.
Com ela é possível consolidar, tornar coerentes e visuais as informações que se
encontram em diversas fontes.
Essa ferramenta foi escolhida porque está bem consolidada no mercado,
além de ser possível a utilização gratuita da versão desktop. O download da
ferramenta pode ser feito no endereço https://powerbi.microsoft.com/pt-br/desktop/.

6.1 Visão Geral


A primeira tela apresenta a visão geral dos entes. De acordo com o IBGE, o
país está divido em 5.599 entes, entre Estados e municípios, sendo que 38,45%
possuíam RPPS dando cobertura previdenciária a seus servidores públicos titulares
de cargos efetivos.
No painel, as informações podem ser filtradas pelo ano do ISP, a região
geográfica e a sigla do Estado.
51

6.2 Segurados
A segunda tela também apresenta a visão geral do número de segurados
ativos, aposentados e pensionistas. De acordo com dados de população do IBGE, o
total de segurados RPPS representam 2,16% da população.

6.3 Grupos
Para fins de apuração do ISP, os RPPS foram segregados em cinco grupos
definidos da seguinte forma:
1. Estado/DF;
52

2. Grande Porte, municípios cuja quantidade de segurados esteja entre


os regimes que representem 5% (cinco por cento) das maiores
quantidades;
3. Médio Porte, municípios cuja quantidade de segurados esteja entre os
regimes que apresentem quantidades inferiores aos de Grande Porte e
acima da mediana;
4. Pequeno Porte, municípios não classificados nos grupos de Grande
Porte e de Médio Porte.
5. Não Classificado, entes que não encaminharam à SPREV informações
relativas à quantidade de segurado.

Além disso, os Municípios foram subdivididos em subgrupos, obtida por meio


da divisão da quantidade de segurados ativos pela quantidade de aposentados e
pensionistas, com o objetivo de captar o seu grau de maturidade ou de antiguidade,
da seguinte forma:
1. Maior Maturidade.
2. Menor Maturidade
53
54
55
56

7 Links

Aqui você deve disponibilizar os links para o vídeo com sua apresentação de
5 minutos e para o repositório contendo os dados utilizados no projeto, scripts
criados, etc.

Link para o vídeo: youtube.com/...


57

Link para o repositório: github.com/...


58

8 REFERÊNCIAS

[REF1] GOMAA, WAEL H., FAHMY, ALY A. A Survey of Text Similarity


Approaches. In Intzernational Journal of Computer Applications (0975 – 8887)
Volume 68– No.13, April 2013. From https://citeseerx.ist.psu.edu/viewdoc/download?
doi=10.1.1.403.5446&rep=rep1&type=pdf

[REF2] ICS 161: Design and Analysis of Algorithms, Lecture notes for February
29, 1996. From https://www.ics.uci.edu/~eppstein/161/960229.html

[REF3] Naumann, Felix. Similarity measures. June 2013. From


https://hpi.de/fileadmin/user_upload/fachgebiete/naumann/folien/SS13/DPDC/
DPDC_12_Similarity.pdf
[REF4] Smith, Temple F and Waterman, Michael S. (1981).Identification of
Common Molecular Sub sequences. Journal of Molecular Biology 147: 195–197.
From http://cs.brown.edu/courses/cs181/resources/ch1_readings/Smith-Waterman-
paper%202.pdf

Um projeto/relatório técnico de Ciência de Dados não requer revisão


bibliográfica. Portanto, a inclusão das referências não é obrigatória. No entanto, caso
você deseje incluir referências relacionadas às tecnologias ou às metodologias
usadas em seu trabalho, relacione-as de acordo com o modelo a seguir.

SOBRENOME DO AUTOR, Nome do autor. Título do livro ou artigo. Cidade:


Editora, ano.
SOBRENOME DO AUTOR, Nome do autor. Título do livro ou artigo. Cidade:
Editora, ano.
SOBRENOME DO AUTOR, Nome do autor. Título do livro ou artigo. Cidade:
Editora, ano.
SOBRENOME DO AUTOR, Nome do autor. Título do livro ou artigo. Cidade:
Editora, ano.
SOBRENOME DO AUTOR, Nome do autor. Título do livro ou artigo. Cidade:
Editora, ano.
SOBRENOME DO AUTOR, Nome do autor. Título do livro ou artigo. Cidade:
Editora, ano.
59

9 APÊNDICE

Programação/Scripts
Cole aqui seus scripts em Python e/ou R.

Gráficos
Cole aqui workflows (KNIME, RapidMiner, etc), gráficos e figuras que você tenha
gerado e não colocou no texto principal.

Tabelas
Cole aqui tabelas de dados que você tenha gerado e não colocou no texto principal.

Você também pode gostar