Minha solução para o problema proposto no Processo Seletivo da Birdie, Estágio Data Scientist, 2018
Usando as técnicas que lhe forem mais familiares e amigáveis (linguagem, frameworks, algoritmos), faça um classificador de títulos de ofertas de e-commerces para diferenciar entre smartphone / não-smartphone para o conjunto de títulos que pode ser baixado no nesse link
A partir do classificador, gere um arquivo de resposta onde para cada título é indicado a categoria (smartphone / não-smartphone) predita pelo classificador.
Publique o código para geração do classificador e a lista de categorias preditas em um repositório github/bitbucket/gitlab e nos envie o link.
- Aprendizado não supervisionado
- NLP (Natural Language Processing)
- Apenas duas classes: "smartphone" e "não smartphone"
- Todos os celulares são smartphones
- Tablets não são smartphones
- Python 3 (não compatível com versões anteriores)
- KMeans (clustering) com k = 2 (também é permitida a decisão pelo melhor k de maneira automatizada)
- Pré-processamento dos dados (também é permitida a execução sem o pré-processamento)
- Atributos criados com base no modelo Bag of Words
No diretório onde se encontra o arquivo data_estag_ds.tsv, executar:
python3 classifier.py
Output: post_classifier.tsv
Estou trabalhando com um dataset não rotulado, sendo assim, existem algumas opções:
- Criar regras de classificação com base em conhecimento próprio (ocorrência de palavras, por exemplo)
- Rotular manualmente as instâncias óbvias e usar Aprendizado semi-supervisionado
- Aprendizado não supervisionado
Em minha solução, podemos dizer que o Aprendizado de Máquina propriamente dito ocorre de maneira não supervisionada, com o clustering por KMeans.
No entanto, há um pré-processamento dos dados baseado em ocorrência de palavras. Isso evita que sejam criados muitos clusters com instâncias que obviamente não são smartphones. Por exemplo, instâncias que possuem a palavra "tablet" são automaticamente classificadas como "não smartphones". Isso pode gerar inconsistências, mas os resultados mostraram-se melhores do que quando não aplicado o pré-processamento.
Depois de feito esse pré-processamento, as instâncias que já foram classificadas são removidas do dataset que passará pelo KMeans. Agora é preciso criar atributos para o classificador. Optei por usar o CountVectorizer, no modelo Bag of Words.
Por fim, é preciso definir o "k" (número de clusters). Podemos fazer isso de duas maneiras:
- k = 2, assumindo que um cluster será de smartphones e outro de não smartphones
- Melhor k com base no melhor score. Para isso, o dataset tem que ser dividido em treino e teste. Serão gerados k diferentes clusters e apenas um será de smartphones, todos os outros serão de não smartphones.
As duas opções foram implementadas, mas a primeira obteve melhores resultados que a segunda e por isso fiz uso dela.
A saída de predição do KMeans se dá em classes "0" ou "1" etc com base no cluster em que as instâncias caíram. Para decidir qual classe é a de smartphones, peguei uma instância que eu sabia que tratava-se de um smartphone, devido justamente à ocorrência da palavra "smartphone". Se essa instância conhecida caiu no cluster 1, por exemplo, então esse é o cluster da classe "smartphone". Isso também pode gerar insconsistências. Se essa instãncia conhecida for rotulada erroneamente pelo classificador, então o resultado estará todo invertido. Isso só poderia ser evitado se estivéssemos implementando uma solução baseada em aprendizado semi-supervisionado.
Os resultados gerados pelo classificador são combinados com os resultados pré-processados e extraídos para um arquivo tsv.
Do meu entendimento, por tratar-se de um algoritmo de clustering, o nome "classificador" talvez seja uma maneira não ideal de referir-se à solução. Todavia, como o resultado é tratado como classes ("smartphone" e "não smartphone"), assumi que não haveria problema em tratar a solução como um "classificador".
A solução deve ser melhorada, visto que ainda há uma taxa de erros que poderia ser diminuída. Para tanto, uma ideia seria rotular manualmente 75% do conjunto de dados fornecido, treinar um classificador seguindo um Aprendizado Supervisionado (decision tree, jrip, knn, rna, etc) e testar nos outros 25% para avaliar a performance do classificador. Assim, com novas instâncias deconhecidas teríamos um classificador mais robusto.