Classify text messages between 'spam' and 'ham'
Project description
Introdução
Este diretório contém um projeto Python para solução do problema prático 02-SMSSpamDetection do teste de Inteligência Artificial da Nuveo. Neste problema, solicitou-se a criação de um projeto para servir um modelo de classificação de mensagens de texto em 'ham' e 'spam'. O modelo foi criado utilizando o pacote scikit-learn e disponibilizado como um pipeline contendo um passo de pré-processamento utilizando TF-IDF, seguido por um modelo de classificação binária utilizando Random Forest.
Para a implementação, foi criado um pacote Python de nome spamdetection, que implementa a classe SpamDetector, contendo métodos prob_spam() (que retorna a probabilidade de classificação 'spam' determinada pelo modelo) e is_spam() (que retorna a classificação). Maiores detalhes sobre o uso do pacote estão disponíveis na seção Utilização e na documentação.
Conforme solicitado no desafio, o pacote também é acompanhado de um módulo de testes unitários, contido na pasta /tests. Maiores detalhes abaixo, na seção Testes.
Também foi criado um aplicativo web que permite fazer previsões utilizando o modelo. O aplicativo pode ser utilizado visitando https://nuveo-teste-ia.herokuapp.com/. Entretanto, por estar hospedado gratuitamente, somente um visitante é permitido por vez.
Dependências
Além da biblioteca padrão de Python, os seguintes pacotes são necessários para o uso do pacote spamdetection:
- sklearn == 0.24.1
- pywebio == 1.2.3
O pacote foi criado em Python 3.8.5.
Ambos estão especificados em requirements.txt. Caso opte por clonar o repositório (não é necessário, veja em Instalação), podem ser instalados com pip install requirements.txt à partir da pasta raiz do repositório.
Instalação
Duas opções estão disponíveis para uso do pacote spamdetection:
1. Instalar com pip
Para cumprimento do desafio, criei o pacote spamdetection, que também foi disponibilizado no PyPI. O pacote pode ser instalado à partir da linha de comando com:
pip install spamdetection
Antes da instalação e uso, recomenda-se a criação de um ambiente virtual dedicado, utilizando sua ferramenta favorita para gestão de ambientes virtuais, e.g.:
conda create -n {nome_do_ambiente}esource activate {nome_do_ambiente},virtualenv {nome_do_ambiente}eactivateoupython -m venv {endereço_do_ambiente}
O uso de ambiente virtual é altamente recomendado mas não obrigatório. Caso a versão de scikit-learn não seja a 0.24.1, haverá um mar de warnings desencorajando o uso de um modelo criado em versão diferente do pacote. Testei com a 0.23.2 e não houve degradação de performance.
2. Clonar este repositório
Tanto o pacote spamdetection quanto este repositório foram criados para que não fosse necessário clonar o repositório localmente (clonar repositório é solução para contribuir, não para utilizar!).
Entretanto, caso queira ter o código localmente, utilizar:
git clone git@github.com:fabio-a-oliveira/nuveo-teste-ia.git
Antes de utilizar, navegar até a pasta raiz do repositório e instalar as dependências com:
pip install requirements.txt
Aqui, recomenda-se também a utilização de ambiente virtual dedicado.
Utilização
São disponibilizados alguns modos de operação:
1. Classe SpamDetector
Após instalar o pacote seguindo as instruções em Instalação, utilizar o método SpamDetector().
Exemplo de utilização de prob_spam():
>>> from spamdetection import SpamDetector
>>> detector = SpamDetector()
>>> detector.prob_spam("These are not the droids you are looking for")
0.02
Exemplo de utilização de is_spam():
>>> from spamdetection import SpamDetector
>>> detector.is_spam("These are not the droids you are looking for")
False
O método is_spam() também pode ser chamado com o argumento mode, que aceita 1 ou "aggressive" (threshold baixo para classificação como spam) ou 2 ou "permissive" (threshold alto para classificação como spam). Caso não seja especificado, o valor padrão é "permissive".
O exemplo abaixo ilustra a diferença:
>>> from spamdetection import SpamDetector
>>> detector = SpamDetector()
>>> detector.prob_spam("call 09058094583 urgent")
0.42
>>> detector.is_spam("call 09058094583 urgent", "aggressive")
True
>>> detector.is_spam("call 09058094583 urgent", "permissive")
False
Vale ressaltar que o argumento mode pode receber também os valores 1 ou 2, que correspondem aos dois modos de operação solicitados no desafio. Os thresholds para classificação foram escolhidos para atingir zero falsos negativos (modo agressivo) e zero falsos positivos (modo permissivo) no conjunto de testes.
Adicionalmente, ambos os métodos prob_spam() e is_spam() também aceitam listas de mensagens como argumentos. Neste caso, retornam uma lista com suas respectivas respostas para cada mensagem individual.
Mais detalhes sobre o uso do pacote disponíveis em fabio-a-oliveira.github.io/nuveo-teste-ia.
N.B.: caso tenha optado por clonar o repositório, o comando import spamdetection somente fica disponível à partir da pasta 02-SMSSpamDetection, a não ser que se adicione a pasta ao PATH do Python.
2. Linha de comando
À partir da linha de comando, o pacote spamdetection pode ser utilizado de duas maneiras diferentes, dependendo da quantidade de argumentos.
Com nenhum argumento, o comando abaixo abre o aplicativo web https://nuveo-teste-ia.herokuapp.com/ em uma nova página do browser:
python -m spamdetection
Com um ou dois argumentos, o pacote retorna um diagnóstico da mensagem fornecida, conforme exemplos abaixo:
python -m spamdetection "call 09058094583 urgent"
>>> Message is classified as 'ham' with probability 0.58
python -m spamdetection "call 09058094583 urgent" aggressive
>>> Message is classified as 'spam' with probability 0.42
python -m spamdetection "call 09058094583 urgent" 2
>>> Message is classified as 'ham' with probability 0.58
Assim como nos demais usos, caso não seja fornecido o segundo argumento indicando o modo de operação, o valor padrão é "permissive".
3. Aplicação web
Visite https://nuveo-teste-ia.herokuapp.com/ e experimente com algumas mensagens para receber de volta suas classificações e probabilidade de spam!
Documentação do API
Além da descrição do uso neste arquivo README.md, foi criada a documentação do API utilizando o pdoc. A documentação pode ser consultada em fabio-a-oliveira.github.io/nuveo-teste-ia.
Optei pelo uso do pdoc (ao invés de uma ferramenta mais utilizada como sphinx) porque ele é mais simples e tem a vantagem de criar páginas com o botão view source, que permite inspecionar o código diretamente na página.
Testes
Detalhamento da metodologia de testes
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spamdetection-0.0.8.tar.gz.
File metadata
- Download URL: spamdetection-0.0.8.tar.gz
- Upload date:
- Size: 732.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.6.1 requests/2.24.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.8.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3e9c4c0e34ba2ae8708be36949fbc808f497f7137b1c9f33d67ef01f560b4f7
|
|
| MD5 |
9270228d20279f9fa1a89e7418fe6e2e
|
|
| BLAKE2b-256 |
fb2b996b2b1aa362f047f6589a2a983681b86d174f193cd4b961d36a329e9213
|
File details
Details for the file spamdetection-0.0.8-py3-none-any.whl.
File metadata
- Download URL: spamdetection-0.0.8-py3-none-any.whl
- Upload date:
- Size: 744.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.6.1 requests/2.24.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.8.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12315673fcd782ec0506fa5dcfbcba1960fc0640b2b240c72f2d87b2f71338c3
|
|
| MD5 |
89415c8104e235ba74f87fd080bad831
|
|
| BLAKE2b-256 |
f9e3d1182177e01289df4318424a8d9ebb3b46442addf01c3f8b8bb3a3925257
|