-
Notifications
You must be signed in to change notification settings - Fork 0
Medium O sistema de analise da complexidade financeira de projetos culturais
Dado que analistas técnicos irão avaliar aspectos financeiros (fase de Análise Financeira) de um projeto já executado, tem-se a seguinte pergunta: quão difícil será para estes técnicos analisarem um determindo projeto em relação à outros projetos similares àquele?
A noção de dificuldade aqui está ligado com a noção de tempo de trabalho que uma pessoa iria levar para analisar o projeto, mas também está ligado com quão difícil será este tempo de trabalho. Ou seja, quanto mais complexo o projeto, mais tempo de trabalho será necessário. E quanto mais difícil este tempo de trabalho é, mais complexo o projeto.
O Salic-ML investigou o problema de estimar complexidade de um dado projeto e também implementou uma solução (sistema) para calcular esta complexidade. Este texto irá apresentar quais foram os dados e as features (características) utilizadas neste cálculo, assim como o cálculo e o algoritmo em si.
Definição de complexidade financeira
Para implementar o sistema de análise de complexidade de projetos culturais o primeiro passo é estar bem definido o conceito de "complexidade". Entendemos por complexidade a noção de quantidade tempo de trabalho um técnico precisaria para analisar o projeto e quão difícil é analisar este projeto. Após esta definição, a equipe do Salic-ML realizou um brainstorming para levantar possíveis features que influenciam diretamente ou indiretamente na complexidade financeira.
Levantamento de features
O brainstorming de features levantou 15 features, das quais 5 foram descartadas por não necessariamente influenciarem na complexidade financeira. As 10 features restantes então foram consideradas relevantes para estimar a complexidade e estão listadas na Tabela 1. Cada feature abaixo define uma caracterísica por projeto que estamos interessado em estimar a complexidade.
Feature | Significado | Relação com complexidade |
---|---|---|
Itens orçamentários | Número de itens orçamentários | Quanto mais, mais complexo |
Itens orçamentários inesperados | Número de itens incomuns presentes no projeto e número itens comuns fora do projeto | Quanto mais, mais complexo |
Comprovantes de pagamento | Número de comprovantes fiscais | Quanto mais, mais complexo |
Preços acima da média | Número de itens orçamentários com preço aprovado maior do que o "normal" | Quanto mais, mais complexo |
Valor captado | Valor total captado do proeto | Quanto mais, mais complexo |
Projetos do mesmo proponente | Número de projetos do mesmo proponente | Quanto mais, menos complexo |
Novos fornecedores | Número de fornecedores que nunca forneceram itens para projetos | Quanto mais, mais complexo |
Total do valor comprovado do projeto | Total de valor comprovado do projeto | Quanto mais, mais complexo |
Valor aprovado | Total do valor aprovado do projeto | Quanto mais, mais complexo |
Mudanças na planilha orçamentária | Número de mudanças de preços de itens, inclusão ou remoçao de itens | Quanto mais, mais complexo |
Tabela 1: features resultantes do brainstorming de levantamento de features (18/07/2018)
Estas features fizeram parte de uma entrega do Salic-ML e foram revisadas e validadas junto aos clientes do produto e usuários finais. Após algumas rodadas de reflexão sobre estas features, algumas destas foram excluídas, outras foram adicionadas e outras modificadas.
Features adicionadas
Feature | Significado | Relação com complexidade |
---|---|---|
Comprovantes por código de operação (TED, saque, cheque) | Cada item comprado por um projeto é atrelado à exatamente um comprovante. Cada comprovante é atrelado à exatamente um código de operação (saque ou xeque por exemplo). Um comprovante pode estar atrelado à vários itens e um códgo de operação pode estar atrelado à vários comprovantes. Entretatno, num cenário ideal de "facilidade" (inverso de complexidade) haveria apenas um comprovante por código de operação e apenas um item comprado por comprovante fiscal. Portanto esta feature visa medir a "distância" entre o cenário ideal e o cenário real | Quanto maior a distância do cenário ideal, maior a complexidade |
Comprovantes com preço acima de 50% do valor aprovado | Existe uma norma que os projetos devem seguir chamada Instrução Normativa. É comum a Instrução Normativa vigente estabelecer que nenhum item pode ser comprado por um preço maior em 50% do valor aprovado para aquele item | Quanto mais, mais complxo |
Tabela 2: features novas a serem incluídas juntamente com as features da Tabela 1 (21/11/2018)
Features removidas
Feature removida | Motivo |
---|---|
Total do valor comprovado do projeto | Esta feature sozinha não exerce influência direta na complexidade financeira. A sugestão feita à equipe é que considerasse o valor comprovado em relação ao valor captado |
Mudanças na planilha orçamentária | Não haviam dados disponiveis suficiêntes |
Tabela 3: features da Tabela 1 que foram excluídas
Vale aqui uma observação sobre o processo de descoberta e validação de features: é fundamental a participação do maior número de pessoas possível que entende e participa do negócio. As pessoas que entendiam do negócio já sabiam de antemão algumas features que exercem complexidade no projeto e é fundamental que a equipe de desenvolvimento colete essas informação. Estas features por definição já são válidas, possuem valor e ainda poupam tempo da equipe da equipe de desenvolvimento.
Uma vez que as features foram levantadas e validadas é necessário analisar cada um dos projetos em relação a cada uma das features listadas. Para cada projeto então temos as seguintes perguntas:
1 - Como o projeto A
se comporta em relação à feature X
?
2 - O comportamento do projeto A
em relação à feature X
é anormal? Quão anormal?
Respondendo a primeira pergunta
No caso do Salic-ML, 100% dos dados disponíveis estavam num banco de dados. Portanto com algumas consultas ao banco de dados é possível responder a primeira pergunta. A segunda pergunta é um pouco mais complicada de se responder.
Respondendo a segunda pergunta
Observe que as features levantadas das Tabela 1 e Tabela 2 são números reais. Portanto podemos refazer a segunda pergunta da seguinte forma: "Dado uma sequência de números reais, e mais um número real P
, o valor de P
é normal nesta sequência?"
Então o Salic-ML tentou responder a pergunta reformulada diferentes métodos:
Método da Gaussiana
- Suponha que os números da sequência de entrada formam uma distribuição Gaussiana. Sendo assim, é possível calcular a probabilidade
p
de um determinado valor maior quex
acontecer nesta distribuição. Aquix
se refere a uma feature ep
a probabilidade (entre 0 e 1) de um valor maior quex
ocorrer para aquela feature. Depois de calcular esta probabilidade você pode definir uma constante arbitrária para funcionar como um limiar outhreshold
de probabilidade. Por exemplo: se a probabilidade de um item com valorx
acontecer é menor que5%
então o projeto é considerado outlier (anormal) naquela feature.
No caso do Salic-ML esta constante foi definida arbitráriamente definida como 6.5%
e funcionou bem.
Exemplo:
- Suponha que os projetos tenham em média
57.23
itens orçamentários - Suponha que o desvio padrão do número de itens orçamentários é de
20.5
- A função de distribuição (Gaussiana) acumulada diz que a probabilidade de um valor maior que
média + 1.5 * desvio padrão
é menor que6.7%
. Ou seja, se um projeto apresentou100
itens, valor maior que57.23 + 1.5 * 20.5 = 87.98
, consideramos este projeto outlier (anormal) nesta feature, pois a probabilidade disto acontecer é menor que6.7%
De início este método foi implementado em todas as features. Ou seja, assumimos que as features assumiam uma distribuição gaussiana e encontrávamos projetos anormais seguindo esta lógica.
Acontece que este método de encontrar a probabilidade de um item com valor x
seguindo uma distribuição de probabilidade depois definir uma limiar/threshold/probabilidade (6.7%
neste caso) não é particular da distribuição gaussiana. Além dela, outras distribuições de probabilidade de uma variável randômica podem ser utililizadas, mudando apenas como a probabilidade do item com valor x
'acontecer' é calculada. Além da Gaussiana (também conhecida como distribuição Normal), as distribuições Log-normal, Gamma e KDE-Gauss foram estudadas e os resultados para alguns estados podem ser verificados nos notebooks com prefixo "analysis_of" na pasta notebooks/report, como por exemplo:Análise de Valor Aprovado.
Vale lembrar que a ideia é, caso seja decidido utilizar uma distribuição de probabilidade como modelo, utilizar a distribuição que mais se 'parece' com a distribuição dos dados do seu domínio atual. Algumas técnicas podem ser utilizadas para encontrar a distribuição mais apropriada para a situação, como: visualização de dados, divisão entre conjunto de testes e validação para a realização de validação cruzada, análise de amostras etc.
Log-normal
A distribuição de probabilidade Log-normal é uma distribuição tal que o logaritmo da variável randômica sendo analisada no momento tem uma distribuição Normal (ou Gaussiana). Assim, por exemplo, se a variável randômica x
do valor do item for distribuída de forma log-normal, então y = ln(x)
. Os valores para uma variável randômica distribuída de forma log-normal são apenas reais positivos, dadas as propriedades da função logarítmica quanto a seus domínios (por exemplo, log(0)
não é definido).
Como pode ser visto no notebook de análise de valor aprovado citado no tópico anterior, muitas das operações para calcular a probabilidade de uma variável randômica x
já está implementada em pacotes como o scikit-learn
, por exemplo.
Gamma
A distribuição Gamma é uma distribuição geral de várias distribuições como a distribuição exponencial, a distribuição Erlang e a distribuição qui-quadrada.
Também foi utilizada a biblioteca scikit-learn
para a implementação dessa distribuição de probabilidade.
Kernel Density Estimation (KDE-Gauss)
Uma estimativa de densidade kernel, a grosso modo, tem como principal objetivo estimar a função de densidade de probabilidade de uma variável aleatória. Isso pode ser feito com a 'fusão' de várias distribuições de probabilidade, como é o caso da KDE-Gauss. Várias gaussianas são utilizadas para 'suavizar' as curvas da função de densidade de tal forma a melhor se ajustar à distribuição dos dados. A sua vantagem em relação à utilização de uma única gaussiana é a precisão da distribuição probabilística criada em relação à distribuição dos dados. Seu ponto negativo é o custo de computação, devido à necessidade da computação das várias gaussianas.
Como na distribuição log-normal e na gamma, a biblioteca scikit-learn
contém métodos para calcular tal estimativa e foi utilizada no contexto do projeto, podendo ser visualizada no notebook citado no tópico do método gaussiano.
LOF (Local outlier factor)
Um outro método analisado pela equipe foi o LOF. Aqui não mais precisamos assumir uma distribuição (que muitas vezes não é exatamente uma distribuição conhecida). Neste método os valores da sequência são considerados pontos num espaço N-dimensional (1-dimensional no nosso caso) e a hipótese é que pontos em regiões de baixa densidade de pontos são outliers, caso contrários são inliers (normais) e a hipótese é que pontos em regiões de baixa densidade de pontos são outliers, caso contrários são inliers (normais).
A biblioteca scikit-learn
do Python possui uma implementação do LOF, disponível neste link, esta foi a implementação utilizada pelo Salic-ML. A equipe testou o desempenho deste algoritmo em relação a Gaussiana, e este método se demonstrou superior no nosso contexto em relação à Gaussiana.
Os valores das features e a análise dos valoes das features não levam em consideração das outras features. Ou seja, pode ser que um projeto se encaixa bem em algumas features mas se encaixe mal em outras. Como calcular uma pontuação (score) única que leva em consideração o reusltado das análises individuais por features?
Para a nossa experiência o processo de levantamento e validação de features é o processo mais importante e o mais custoso (em tempo e esforço). Se boas features forem definidas os resultados finais serão melhores mesmo que o algoritmo de análise e comparação sejam menos robustos. Portanto é crucial que entendedores do negócio participem do processo de levantamento e validação de features. O método de LOF foi o método com melhor performance nas nosssas comparações. Para a implementação dos algoritmos de detecção de outliers (anormalidade), existe bastante coisa pronta nas bibliotecas do scipy
e scikit-learn
portanto damos prioridade para estas implementações que são na maior parte mais validadas, já testadas e ainda são mais genéricas.
Anexos:
Reuniões
- 2018.04.04: Entendendo o Salic
- 2018.04.11: Entendendo o Salic
- 2018.04.16: Andamento salic-ml
- 2018.04.24: Ciclo de trabalho da Sefic
- 2018.04.27: Possíveis melhorias para o Salic
- 2018.05.04: Itens de pesquisa salic-ml
- 2018.05.07: Planejamento salic-ml
- 2018.07.17: Iniciação Fase 2
- 2018.07.18: Brainstorming de features
- 2018.07.18: Planejamento Arquitetura
- 2018.11.22: Validação das métricas de complexidade financeira
Estudos
- Processo Salic
- Integração do Salic ML ao Salic
- Acesso ao DB do Salic via VPN
- Obtenção de dados do Salic
- Estratégias para disponibilizar grandes datasets para a comunidade
- Dados sobre finanças dos projetos no Salic
- Referências de Aprendizagem de Máquina
- Arquitetura ML
- Arquitetura SALIC-ML Produto
Documentação
Outros
- Estimação de métricas de Complexidade Financeira
- Estratégias para disponibilizar grandes datasets para a comunidade
- Implementando algoritmos de ML em prod
- Itens para o relatório 4 - Frente ML Pesquisa
- Itens para o relatório 5 - Frente ML Pesquisa
- Medium SalicML - Similaridade entre projetos culturais
- Medium - O sistema de a
- Obtendo datasets
- Planning arquitetura - 18.07.18
- Plano de comunicação
- Protocolo antigo de comunicação entre API e frontend
- Relatório de entrega - Jan a Mar 2019
- Um algoritmo de detecção de similaridade de projetos - Roadmap
- Roadmap do SalicML
- Sobre a metodologia
- Validação de dados utilizados em aplicações do SalicML