Uma Implementação em R do RSF Test

Detecção de Fraude

Nesse post nosso objetivo é mostrar como implementar o Relative Size Factor Test no R, que, sem dúvida nenhuma, é uma excelente opção para análise de dados em auditoria.

Marcos F. Silva true
2021-11-24

Introdução

No Capítulo 11 do livro Forensic Analytics (1a Edição), Mark Nigrini descreve e implementa, usando Access e Excel, o denominado Relative Size Factor Test - RSF Test, um teste para detecção de outliers em grupos de registros que compõem uma base de dados.

Essencialmente o teste busca identificar grupos de registros, usualmente definidos por variáveis categóricas, para os quais o maior valor é significativamente maior que os demais valores do grupo.

Vamos ilustrar com um exemplo para tornar as coisas mais concretas. Suponha o seguinte conjunto de dados:

A variável Vendor_No vai definir os grupos de registros, ou seja, cada código de vendedor define um grupo enquanto a variável Invoice_Amount vai ser onde vamos buscar os outliers, ou seja, onde vamos calcular o RSF Factor.

O RSF Factor é calculado tomando-se o quociente entre o maior valor no grupo e o segundo maior valor, também no grupo. Simples assim.

Em termos matemáticos:

\[ RSF\_factor = \frac{maximo\_valor\_grupo}{segundo\_maior\_valor\_grupo} \]

Então para cada vendedor vamos identificar as faturas por ele emitidas, identificar os dois valores de interesse (primeiro e segundo maiores valores) e calcular o quociente.

O autor levanta algumas questões de ordem prática relacionadas à implementação deste teste. A primeira questão diz respeito ao fato de que, grupos contendo apenas um valor não pode gerar um RSF_Factor pela simples razão de não existir um segundo maior valor. Também comenta ser uma boa ideia excluir valores menores que 1,00 ou 10,00 e não incluir valores negativos.

O autor aponta também o desafio de identificar o segundo maior valor no grupo, o que requer estabelecer uma regra para definição do segundo maior valor nos casos em que se tem mais de um valor máximo no grupo.

O autor propõe um passo a passo para a implementação do teste e mostra como implementá-lo usando o Microsoft Access e o Maicrosoft Excel.

Implementação do Teste em R

Nosso objetivo neste documento é mostrar como o teste pode ser implementado usando o R e para isso vamos inicialmente escrever um script para a execução do teste que posteriormente será convertido em uma função.

Vamos utilizar um conjunto de dados simples (RSF.xlsx) para esse propósito.

Esse conjunto de dados pode ser baixado na seguinte página: http://www.ashishmathur.com/compute-relative-size-factor-per-vendor/

Vamos à importação dos dados:

library(readxl)
rsf <- read_excel("_RSF.xlsx", range="A1:C25")
head(rsf)
# A tibble: 6 x 3
  Vendor_No Invoice_No Invoice_Amount
  <chr>     <chr>               <dbl>
1 V4437     AP00048            21261 
2 V4409     AP0008002          21392.
3 V4550     AP000130           21542.
4 V4437     AP000292           21729.
5 V4526     AP0009             22758.
6 V4429     AP0007402          23413.

Importado o conjunto de dados e depois de algumas tentativas e erros e consultas à internet chegamos ao seguinte script para a execução do teste:

library(dplyr)

resultado <- rsf %>% 
  group_by(Vendor_No) %>% 
  summarise(maior_valor = max(Invoice_Amount),
            segundo_maior = nth(unique(Invoice_Amount), 2, order_by = desc(unique(Invoice_Amount))),
            n = n()) %>% 
  filter(n > 1) %>% 
  mutate(rsf = round(maior_valor / segundo_maior, 3)) %>% 
  arrange(desc(rsf))

resultado
# A tibble: 7 x 5
  Vendor_No maior_valor segundo_maior     n   rsf
  <chr>           <dbl>         <dbl> <int> <dbl>
1 V4550          25940.        21542.     2  1.20
2 V4554          28747         25378.     2  1.13
3 V4429          25098.        23413.     2  1.07
4 V4439          25378.        24068.     5  1.05
5 V4437          21729.        21261      2  1.02
6 V4455          25472.        25004      4  1.02
7 V4526          25940.        25753.     3  1.01

Uma coisa que não é feita no livro mas que nos parece interessante é montar um gráfico para visualizar o rsf.

library(ggplot2)

resultado %>% 
    ggplot(aes(x=reorder(Vendor_No, rsf), y=rsf)) +
    geom_point(color="blue") +
    xlab("Grupos") +
    ylab("RSF Factor") +
    theme_bw()

De acordo com o autor, a aplicação deste teste pode revelar erros de colocação de ponto decimal em dados de contas a pagar; situações nas quais, por exemplo, um valor de 3200.00 é inserido no sistema como 320000. Um erro parcial ocorre quando, por exemplo, um valor de 421.69 é inserido como 4216.90.

Outra observação feita pelo autor é que o RSF Factor é mais assertivo quanto a existência de erro quando o grupo possui muitos registros.

Elaboração da Função rsf_factor_test()

Com base na solução apresentada acima é razoavelmente simples elaborar uma função para a aplicação do teste em um conjunto de dados.

rsf_factor_test <- function(df, group_column, value_column, exclude_low=FALSE){

  if(exclude_low){
    df <- df %>% filter(.data[[value_column]] > 1)
  }
  
  df %>% 
    group_by(.data[[group_column]]) %>% 
    summarise(Max_Value = max(.data[[value_column]]),
              Second_Max = nth(unique(.data[[value_column]]), 2, order_by = desc(unique(.data[[value_column]]))),
              N = n()) %>% 
    filter(N > 1) %>% 
    mutate(RSF_Factor = round(Max_Value / Second_Max, 3)) %>% 
    arrange(desc(RSF_Factor))
  
}

Vamos aplicar a função ao nosso conjunto de dados:

rsf_factor_test(rsf, "Vendor_No", "Invoice_Amount")
# A tibble: 7 x 5
  Vendor_No Max_Value Second_Max     N RSF_Factor
  <chr>         <dbl>      <dbl> <int>      <dbl>
1 V4550        25940.     21542.     2       1.20
2 V4554        28747      25378.     2       1.13
3 V4429        25098.     23413.     2       1.07
4 V4439        25378.     24068.     5       1.05
5 V4437        21729.     21261      2       1.02
6 V4455        25472.     25004      4       1.02
7 V4526        25940.     25753.     3       1.01

Naturalmente que algumas melhorias e extensões podem ser incluídas na função. Por exemplo, a função pode calcular o quociente entre o valor máximo e a média do valores do grupo incluindo ou excluindo o valor máximo, como mencionado pelo autor. Por ora vamos deixar a função assim.

Referências e materiais adicionais

Para a elaboração deste documento a referência principal foi o Capítulo 11 do livro Forensic Analytics (1a Edição) do Mark Nigrini já mencionado anteriormente.

Para mais informações sobre esse teste o leitor pode consultar também o seguinte link: https://www.ideascripting.com/Relative-Size-Factor-Test

No vídeo https://www.youtube.com/watch?v=fyRT84LLbyw Mark Nigrini faz uma revisão do capítulo 7 da 2a Ed. do livro Forensic Analytics que aborda esse tópico e comenta sobre casos reais de fraude.

Também tem um outro vídeo ( https://www.youtube.com/watch?v=5f-5ZE3uccQ )
no qual o autor demonstra como implementar o teste com o Excel, também utilizando a 2a Edição do livro.

Deixamos para o leitor testar a função no conjunto de dados examinado pelo autor no vídeo (2_Somerville_Sample.xlsx), que pode ser baixado no link disponibilizado na descrição do vídeo.

Outro material interessante é o livro online Audit Analytics with R do Jonathan Lin que aborda esse teste no item “9.4.2 Relative size factor (RSF)”.

Citation

For attribution, please cite this work as

Silva (2021, Nov. 24). Audinalytics: Uma Implementação em R do RSF Test. Retrieved from audinalytics.netlify.app/posts/2021-11-22-uma-implmentao-em-r-do-rsf-test/

BibTeX citation

@misc{silva2021uma,
  author = {Silva, Marcos F.},
  title = {Audinalytics: Uma Implementação em R do RSF Test},
  url = {audinalytics.netlify.app/posts/2021-11-22-uma-implmentao-em-r-do-rsf-test/},
  year = {2021}
}