Em sites de classificados online é comum ver pessoas postando anúncios quase idênticos, mudando apenas uma palavra, ou as fotos, para tentar fazer com que mais usuários vejam o anúncio e respondam.

Isso acaba sendo um problema para quem quer encontrar o melhor negócio, já que precisa tolerar vários anúncios irrelevantes até encontrar o que deseja. Uma das soluções é ter uma equipe de revisores para avaliar os anúncios, mas dá pra perceber que os custos se tornariam altos ao recebermos milhões de anúncios por dia.

Esta é uma tarefa na qual machine learning pode ajudar.

A Avito é uma empresa de classificados online bastante popular no Leste Europeu. Não é a primeira vez que eles oferecem competições no Kaggle, e desta vez querem um sistema que possa detectar anúncios duplicados automaticamente.

O time do qual fiz parte terminou no terceiro lugar, e este artigo trata de um modelo que seria o bastante para terminar em 15º lugar.

Índice

Quais eram os dados disponíveis

Os arquivos principais eram aqueles que descreviam os pares de anúncios. Continham o ID dos dois anúncios, um indicador sobre a duplicidade do par, e o método utilizado para gerar aquele indicador. Esta terceira variável só estava disponível nos dados de treino.

Três métodos foram usados para gerar os dados: em um deles uma pessoa avaliava um par de anúncios e determinava se era duplicado, em outro um sistema automaticamente determinava se os anúncios eram duplicados, e no terceiro, uma pessoa avaliava manualmente os anúncios, mas apenas de um usuário.

No geral, pouco mais de 40% dos pares eram anúncios duplicados.

Como dados auxiliares tínhamos: informações textuais como título, descrição, atributos do anúncio (marca do carro, em anúncios de automóveis, por exemplo). Informações visuais, que eram as imagens dos anúncios. E informações gerais, como a categoria do anúncio, a latitude e longitude de onde foi postado, um indicador da região geográfica, e a estação de metrô mais próxima.

Os pares totalizavam mais de 4 milhões de linhas.

Como modelar esta tarefa

Uma das habilidades mais importantes do cientista de dados é saber traduzir uma tarefa para o mundo do machine learning. Neste caso, como estamos tratando de detectar duplicações, mais importante do que o conteúdo dos anúncios, é a similaridade entre as características do par.

Similaridade entre imagens

Mais importante que o próprio texto dos anúncios eram as imagens. Dá pra raciocinarmos o seguinte: mudar uma ou outra palavra do texto para não dar a impressão de anúncio duplicado é fácil, mas poucas pessoas vão ter o trabalho de tirar fotos diferentes, então a tendência é que as fotos de anúncios duplicados sejam as mesmas, ou muito parecidas.

Tive a oportunidade de aprender uma nova maneira de calcular a similaridade entre imagens, que é simples e tem um resultado muito bom. Basicamente consiste em reduzir a imagem, computar uma função sobre os pixels da imagem redimensionada e determinar bits para representar o valor da função computada.

Mais informações sobre estes métodos podem ser encontradas neste link: http://www.hackerfactor.com/blog/?/archives/529-Kind-of-Like-That.html

Similaridade entre o texto dos anúncios

Apesar de importantes, estas variáveis não são tão boas quanto a similaridade das imagens, já que é fácil modificar apenas algumas palavras e ter anúncios diferentes.

Nós não tínhamos informações temporais, como o momento em que o anúncio foi feito, então haviam anúncios que tinham o mesmo texto e não eram duplicados, e imagino que seja o caso de anúncios que expiraram e foram colocados novamente.

Um passo importante foi fazer a limpeza dos dados: transformar o texto para caixa baixa, remover a pontuação e fazer stemming.

Algumas métricas de similaridade funcionaram bem, como a Jaccard e a Cosine.

Similaridade entre outros campos

Também criei variáveis para indicar se outros campos, como o da localização, possuíam o mesmo valor. Algumas destas acabaram ajudando, mas foram minoria.

Como tínhamos latitude e longitude, calculei a distância geográfica entre os anúncios, que acabou contribuindo com o modelo.

Além disso, diferenças entre o preço dos dois produtos foram importantes. Não apenas comparar se o preço era exatamente igual, mas qual a magnitude da diferença.

Outras variáveis

Variáveis como o preço de um produto e a região onde ele se encontra também foram importantes. Uma das razões pode ser que em cidades maiores, ou bairros com maior população, exista uma probabilidade maior de duplicação.

O modelo utilizado

Apesar da solução final do time contar com vários modelos, eu foquei em criar apenas um que fosse capaz de capturar os padrões através das variáveis sobre os dados originais.

Este modelo foi um Gradient Boosted Trees, com a implementação do XGBoost. Um detalhe é que usei uma quantidade baixa de árvores, mas com uma profundidade grande em cada árvore, o que ajudou a capturar os padrões. Acredito que uma quantidade maior de árvores, e mais superficiais, teria atingido uma performance melhor.

Este modelo, por si só, terminaria em 15º lugar.

Seja o primeiro a saber das novidades em Machine Learning. Me siga no LinkedIn.