Detecção de fraudes com aprendizagem supervisionada e semi-supervisionada

Bruno Borges
Ensina.AI
13 min readJul 1, 2020

--

No contexto de aprendizado de máquina, podemos identificar basicamente três tipos de métodos de aprendizagem:

  1. Aprendizado supervisionado, onde usamos dados rotulados para treinar o modelo, ou seja, os dados que utilizamos para treiná-los contém a resposta desejada, como os algoritmos de regressão e classificação;
  2. Aprendizado não-supervisionado, onde os dados de uma tabela de variáveis não são rotulados, como os algoritmos de clusterização e recomendação;
  3. Aprendizagem por reforço — onde a máquina observa um certo ambiente dinâmico e toma decisões nesse ambiente baseado em recompensas e punições, como o Q-learning.

Com relação ao primeiros métodos citado, a principal desvantagem do aprendizado supervisionado é que o conjunto de dados deve ser rotulado por um engenheiro ou cientista de dados, o que pode ser um processo bastante custoso. Para contornar essa desvantagem, foi introduzido o conceito de aprendizado semi-supervisionado, onde o algoritmo usa uma combinação de dados rotulados e não-rotulados para fazer o aprendizado de máquina.

Para classificação ou regressão, o aprendizado semi-supervisionado é útil quando lidamos com bases extremamente desbalanceadas (para detecção de anomalias, por exemplo). Nesse caso, teríamos como dados não rotulados aqueles que são da classe majoritária, e os dados rotulados aqueles que são da classe rara. Por exemplo, imagina que você gostaria de saber se um determinado animal é um cachorro ou não. Como você é aficionado por cachorros e possui um milhão de imagens deles, mas pouquíssimas de outros animais, você poderia utilizar um modelo generativo que se ajuste bem a todos atributos de imagens de cachorro. Qualquer outro animal o modelo iria identificar como anomalia.

Além da classificação e regressão, podemos citar outras aplicações interessantes para o aprendizado semi-supervisionado:

  1. Classificação Clusterizada — Os métodos convencionais de agrupamento não são supervisionados, mas em muitas situações, no entanto, informações sobre os clusters estão disponíveis. O mesmo problema acontece quando queremos classificar com aprendizado supervisionado instâncias usando uma base com poucos dados rotulados. Por exemplo, os rótulos de cluster de algumas observações podem ser conhecidos ou certas observações podem pertencer ao mesmo cluster. Em outros casos, pode-se querer identificar clusters associados a uma variável de resultado específica. Assim, uma ideia é usar o K-means para uma clusterização inicial e depois usar a distância de cada um dos rótulos ao centro do cluster como uma variável dependente para um modelo de aprendizagem supervisionada;
  2. Análise de fala: como rotular arquivos de áudio é uma tarefa muito intensa, o aprendizado semi-supervisionado é uma abordagem muito natural para resolver esse problema.
  3. Classificação do conteúdo da Internet: como rotular cada página da web é um processo inviável, algoritmos de aprendizado semi-supervisionados podem ser usados. Um exemplo é o algoritmo de pesquisa do Google, que usa uma variante do aprendizado semi-supervisionado para classificar a relevância de uma página da web para uma determinada consulta.

Em 2016, o Google lançou uma nova ferramenta chamada Google Expander. Funcionalmente, o Google Expander aproveita o aprendizado em larga escala baseado em gráficos para inferir o conhecimento sobre uma fonte de dados específica. Daí, o Expander cria uma representação multigráfica de uma fonte de dados na qual os nós correspondem a objetos ou conceitos e as arestas conectam nós que compartilham semelhanças. O gráfico deve conter dados conhecidos e desconhecidos. Usando aprendizado semi-supervisionado, o algoritmo rotula os conjuntos de dados desconhecidos, aproveitando as características de seus vizinhos no gráfico.

Objetivo do texto

Nesse texto, eu não irei apenas apresentar o conceito de aprendizado semi-supervisionado. Vou aplicá-lo usando a base de dados de fraude de crédito disponível no kaggle e comparar com técnicas utilizando aprendizado supervisionado. Com relação à base de dados, ela está disponível para download nesse link. Contém como input as seguintes variáveis:

  • Time: Número de segundos decorridos entre a transação atual e a primeira transação no conjunto de dados;
  • Amount: Valor da transação.
  • V1-V28: inputs codificados via PCA como forma de manter sigilo nos dados do cliente.

Como output, a base tem 0.17% dos dados (492 de 284.000) rotulados como fraude, o que a torna muito desbalanceada. Devido a isso, não podemos usar a acurácia para avaliar a performance do algoritmo, já que se marcássemos todos os dados como normais (não frades), teríamos uma acurácia de 99,83%, o que não vem ao caso para nossos propósitos. Métricas mais utilizadas nesse caso seria:

  • Precisão (Precision) — Mede a porcentagem de acertos entre as observações classificadas como positivas;
  • Revocação ou sensibilidade (Recall) — Mede a porcentagem de observações positivas que foram classificadas corretamente;
  • F-Beta — Essa medida atinge um equilíbrio entre sensibilidade e precisão usando a média harmônica dessas métricas, É uma generalização da métrica F1 e, se beta>1, a métrica dá mais peso à revocação, enquanto peso menor que 1 dar-se mais peso à precisão:
  • Coeficiente Kappa — É um método estatístico para avaliar o nível de concordância entre dois conjuntos de dados. É muito bom em lidar com classes raras:

onde Acc é a precisão e Acc_e a precisão observada em um classificador aleatório.

Todas esse métricas podem ser vistas em detalhes no texto que fiz sobre métricas para classificadores aqui. Nesse texto eu não vou mostrar os códigos, mas publiquei um notebook no kaggle explicando tudo em detalhes.

Um dilema que existe na detecção de fraudes seria o trade-off entre precisão e revocação. Veja a matriz de confusão abaixo:

Qual modelo seria melhor, o que deu a matriz de confusão da esquerda ou da direita? Se for o modelo da esquerda, você está preferindo precisão, ou seja, evitar ter muitos falsos positivos pra vender mais (erro tipo I), ao custo de deixar passar algumas fraudes. No modelo da direita, você quer evitar ao máximo deixar passar fraudes (erro tipo II), ao custo de muitos falsos positivos. A métrica que você vai usar depende basicamente de quanto custa deixar uma fraude passar e perder um cliente confiável. Se for algo muito caro você deve dar preferência à revocação, se não prefira a precisão (isso evita o custo de ligação para o cliente para conferir se é fraude ou não por exemplo). No meu caso, darei mais peso para a revocação na métrica fazendo beta=2 na métrica F-beta (F2).

Aprendizado supervisionado — Undersampling e oversampling

Primeiramente, vamos treinar um modelo com os algoritmos clássicos de classificação. Como a base é muito desbalanceada, temos que achar meios de contornar isso. Devemos inicialmente escolher bons representantes da classe majoritária. Faremos isso usando uma técnica de undersampling chamada One-Sided Selection. Primeiro, remove-se os links Tomeks. Duas instâncias a e b definem um link Tomek se a vizinhança mais próxima da instância a é b, a vizinhança mais próxima da instância b é a e as instâncias a e b pertencem a diferentes classes. A técnica TomekLink irá remover tais links, ou seja, os pontos em que as classes minoritária e maioritária são próximas. Depois, Oa regra CNN (Condensed Nearest Neighbor) é então usado para remover exemplos redundantes da classe majoritária que estão longe do limite de decisão.

Para oversampling, uma ideia é o SMOTe — Synthetic Minority Over-sampling Technique, que tem o incrível poder de criar dados sintéticos para aumentar a classe minoritária (oversampling). A ideia é simples: observe a figura abaixo; os pontos vermelhos representam a classe minoritária. Podemos criar dados sintéticos a essa base simplesmente adicionando pontos nas linhas que ligam os K pontos mais próximos.

Esse método de criação de dados sintéticos geralmente funciona muito bem. Para complementar, ainda aplicaremos outra etapa de undersampling, diminuindo o número de dados na classe majoritária, pois mesmo. Para a base de dados escolhidas, os algoritmos Random Forest e XGBoost perfomaram muito bem usando uma base com proporção de 10% para classe minoritária,

Um erro muito comum é usar uma base de teste com a mesma proporção de classe da base de treino. Como o modelo precisa ser treinado para lidar com uma base desbalanceada, a proporção da classe rara precisa refletir a base real. No casa da base que está sendo trabalhada, seria 0.17%.

Random Forest e XGBoost

Dentre os que testei, os algoritmos Random Forest e XGBoost performaram melhor. Usando um gridsearch, será usado os seguintes hiperparâmetros:

Random Forest

  • n_estimators = 1600; número de árvores de decisão na floresta;
  • min_samples_split = 2; controle o número mínimo de amostras necessárias para dividir cada nó. Valores muito grandes podem causar underfitting;
  • min_samples_leaf = 1; define o número mínimo de amostras necessárias para cada folha. Com valores muito grandes, as árvores podem não conseguir dividir o suficiente para capturar variação suficiente nos dados ;
  • max_features = sqrt; Max_ determina o número de variáveis a serem amostrados novamente. Valores grandes podem resultar em melhor desempenho do modelo, porque as árvores têm uma seleção maior de recursos para escolher a melhor divisão, mas também podem fazer com que as árvores sejam menos diversas e induzam o ajuste excessivo. O sqrt significa que escolhemos a raiz quadrada do número de features;
  • max_depth = 100; número máximo de níveis em cada árvore de decisão;
  • bootstrap = False; método de amostragem de data points (Falso: sem reposição)

XGBoost

  • min_child_weight = 5; Define a soma mínima de pesos de todas as observações necessárias em uma child. Previne overffiting;
  • max_depth = 12; Profundidade da árvore, análogo a Random Forest;
  • learning_rate = 0.1; taxa de aprendizado;
  • gamma = 0.2; Um nó é dividido apenas quando a divisão resultante fornece uma redução positiva na função de perda. Gamma especifica a redução de perda mínima necessária para fazer uma divisão.
  • colsample_bytree = 0.7; Indica a fração de colunas a serem amostradas aleatoriamente para cada árvore.
  • learning rate = 0.1; Define a taxa de aprendizado do algoritmo. Torna o modelo mais robusto diminuindo os pesos em cada etapa;

Para maximizar o resultado, deve-se usar um predição de classe probabilística e definir o melhor limiar para maximizar a métrica F2. Observe nesse gráfico onde está o limiar escolhido:

Com a matriz de confusão, entendemos melhor como o modelo classificou as classes normais e fraudes:

A matriz de confusão gerada pelo XGBoost é a mesma. A métrica f2 encontrada nesse caso foi de 84%, um resultado muito bom. Uma observação muito importante refere-se ao fato de que selecionamos uma amostra da base para treinar o modelo. É natural que esse valor seja diferente para outras amostragens, podendo dar valores maiores ou menores que este. Daí a importância de validar o modelo com várias amostras. Observe agora o resultado dos modelos para 10 amostras diferentes:

Analisando a média dos resultados das amostras, vamos escolher o Random Forest como vencedor, e portanto, benchmark para os algoritmos de aprendizagem semi-supervisionada. Claro que, se fôssemos rigorosos na estatística, deveríamos usar F -teste para aceitar a hipótese alternativa, com p-value<0.05, que a média da métrica F2 do modelo random forest é maior que a gerada usando XGBoost. Deixo isso como exercício.

Uma observação é que esse resultado é melhor que o melhor resultado do artigo da LAMFO sobre aprendizado semi-supervisionado encontrado aqui, cuja leitura é bastante recomendada.

Misturas Gaussianas

Aqui usaremos uma mistura de 3 curvas gaussianas que, usando uma técnica conhecida como EM (Expectation Maximization) vai encontrar um ótimo local da função de máxima verossimilhança dessa mistura de Gaussianas. De uma maneira resumida, esse algoritmo funciona assim:

  • E-Step: Nessa etapa ele calcula a probabilidade de cada ponto pertencer a cada Gaussiana;
  • M-Step: Após a primeira etapa, os parâmetros da mistura são maximizadas através de um conjunto de equações. O modelo alterna entre essas duas etapas até o algoritmo convergir a um ótimo local.

Vamos aplicar isso ao nosso modelo. Vamos usar 80% dos dados normais como base para ser ajustada pelo mistura gaussiana e a base de teste exatamente igual à usada para os algoritmos de aprendizagem supervisionada. Temos que definir um limiar para decidir ae que ponto na curva o modelo seria normal ou não. Podemos usar diversos limiares e pedir para o algoritmo retornar aquele que melhor minimiza a métrica F2. Eis os resultados:

Os resultados não foram melhor que os resultados com o aprendizado supervisionado de acordo com a métrica F2, apesar do resultado ser bastante próximo com esta métrica. (79% vs 83%). Esse modelo tem a vantagem de ser mais fácil de explicar, já que você aplica três curvas gaussianas e faz um corte, estabelecendo um limiar entre valores normais e anomalias, diferente do XGBoost, que é muito caixa-preta. Talvez o resultado possa ser melhor excluindo algumas variáveis e mantendo aquelas que mais verificam a diferença entre classes, como V17 e V18, por exemplo. Um ótimo exercício para o leitor.

Autoencoders

Talvez você já tenha ouvido falar desse algoritmo como um método para redução de dimensionalidade usando redes neurais. O que você provavelmente não sabia é que esse algoritmo também pode ser usado como método para aprendizado semi-supervisionado. A ideia é bastante simples: Lembrando do exemplo que dei para classificar cachorros e gatos, vamos usar autoencoders para codificar essas imagens. Você precisa treinar esse rede para codificar e decodificar. Suponha que treinamos essa rede somente para codificar e decodificar imagens de cachorro, Bom, se você quisesse codificar e decodificar imagens de gato o modelo provavelmente não iria se sair muito bem não é? Usando um limiar de erro, podemos classificar as imagens caso o erro seja pequeno (cachorro) e grande (gatos).

Autoencoders treinam modelos para ter como saída o valor dado na entrada. Claro que para evitarmos que ele simplesmente copie e cole a entrada precisamos colocar umas camadas ocultas na rede:

Diferente do algoritmo de misturas gaussianas, não é recomendado usado uma base de treino muito grande. Para o algoritmo performar bem, devemos escolher dados que melhor caracterizem a classe majoritária. Portanto, será escolhido para a base de treino apenas 4000 dados normais. Obviamente, tamanhos diferentes e a forma como você escolhe esse dados mudam o resultado final. Portanto, antes de fazer uma aplicação comercial deste algoritmo, deve-se fazer muitos testes para escolher a base de treino ótima.

Pediremos ao modelo para reconstruir pontos de dados normais e, se passarmos um ponto de dados de fraude, haverá um grande erro que usaremos para detectar a fraude. No nosso caso, a camada latente codificada terá 25 neurônios e, como nossos dados possuem 30 variáveis, isso significa que a rede neural precisará aprender uma representação latente que condensa 30 dimensões em 25 dimensões passando pela representação com 100 e 50 neurônios (30–100–50 -25–50–100 neurônios nas camadas ocultas). Os parâmetros foram configurados da seguinte forma:

  • activation = ‘tanh’ e ‘relu’; a função de ativação é responsável pela representação de não-linearidade dos modelos. Usaremos a função tangente hiperbólico e relu;
  • epochs = 400; define quantas épocas serão necessárias para treinar o modelo;
  • batch_size = 128; define o número de amostras que serão propagadas pela rede por vez. Como você treina a rede usando menos amostras que com o batch igual ao número de amostras, o procedimento geral de treinamento exige menos memória. Isso é especialmente importante se você não conseguir caber todo o conjunto de dados na memória da sua máquina. E também, normalmente as redes treinam mais rápido com mini-batches;
  • callback earlyStopping patiente = 30; Se após 30 épocas o modelo não melhorar na base de validação, termina o treinamento;
  • validation_split = 0.1 Aqui será usada uma base de validação que será composta por 10% da base de treino.
  • optimizer = ‘Adam’; Define o algoritmo de otimização responsável pela atualização do gradiente da rede. Como a otimização não é convexa, o algoritmo pode convergir para mínimos locais. Adam é quase sempre uma excelente opção.
  • loss = ‘mean_squared_error’; A cada época, o algoritmo irá tentar reduzir a função de perda, dada pela média dos erros quadráticos entre a saída e o resultado verdadeiro;
  • Dropout = 0.4. Camadas de dropout desligam uma determinada porcentagem de neurônios (40% aqui) para evitar overfitting.

Podemos acompanhar a atualização da função loss nas bases de treino e validação:

Pelo figura acima podemos ver que a rede converge de forma mais ou menos estável a um ponto ótimo local. Vamos gora verificar como o autoencoder classificou os dados de acordo com o erro de reconstrução:

Acima da linha estão todos os dados classificados como fraudes. Muitos pontos normais foram classificados como falso positivos, mas no geral, a perfomance do algoritmo não foi ruim, com F2 de 76%.

Vale lembrar que há muitas possibilidades de configuração dos hiperparâmetros da rede, além do fato de que, como a otimização do gradiente não é convexa, o algoritmo pode convergir para pontos locais diferentes. Os resultados que obtive variavam de um F2=70% até 82%. Devido a esses problemas de convergência eu prefiro Mistura gaussiana. como modelo de aprendizagem para esta base.

Conclusão

O modelo de Mistura Gaussiana teve um desempenho muito bom de acordo com a métrica F2. Embora não tenha superado os algoritmos de random forest e XGBoost, a diferença entre os dois métodos não foi tão significativa e, devido à fácil interpretação, o modelo de mistura gaussiana pode ser um alternativa interessante. Também é interessante observar como o autoencoder poder ser tratado como um algoritmo de classificação, uma tarefa diferente da qual o algoritmo foi concebido. Vale lembrar também que existem muitas outras técnicas que podem ser utilizadas para aprendizado semi-supervisionado, como forest isolation, histograma e máquina de suporte vetorial

--

--

Bruno Borges
Ensina.AI

Cientista de dados formado em engenheiria de produção e matemática aplicada.