Skip to content

Medium O sistema de analise da complexidade financeira de projetos culturais

Victor Moura edited this page Nov 11, 2019 · 1 revision

Introdução

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.

O sistema de calcular complexidade financeira de projetos culturais

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.

Features levantadas e validadas, e agora?

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

  1. 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 que x acontecer nesta distribuição. Aqui x se refere a uma feature e p a probabilidade (entre 0 e 1) de um valor maior que x ocorrer para aquela feature. Depois de calcular esta probabilidade você pode definir uma constante arbitrária para funcionar como um limiar ou threshold de probabilidade. Por exemplo: se a probabilidade de um item com valor x acontecer é menor que 5% 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 que 6.7%. Ou seja, se um projeto apresentou 100 itens, valor maior que 57.23 + 1.5 * 20.5 = 87.98, consideramos este projeto outlier (anormal) nesta feature, pois a probabilidade disto acontecer é menor que 6.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.

Unindo os resultados das análises de features em uma pontuação só

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?

Conclusão

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:

Clone this wiki locally