Por Rafael Novello em 02/02/2017 no site iMasters
Hoje quero mostrar um pequeno programa que criei para testar e praticar as técnicas de Machine Learning na categorização de textos. É apenas um protótipo que usa matérias jornalísticas, mas você pode baixá-lo para testar e estudar!
Importante: Meu objetivo não é abordar profundamente as diferentes técnicas, abordagens e algoritmos disponíveis, pois meu conhecimento ainda não me permite. Ao invés disso, quero te mostrar como é possível aplicar tais conhecimentos e, quem sabe, te estimular a também estudar o assunto!
Como você pode ver no aquivo em meu Github, o programa ficou com 152 linhas de código, o que é pouco mas vou me concentrar nas partes relacionadas ao processamento dos dados, treinamento e predição que são o foco do artigo de hoje.
O programa pode ser dividido nas seguintes etapas:
- Baixar e extrair o conteúdo das matérias a partir de um CSV com links e categorias;
- Limpar o conteúdo e deixar apenas o que é relevante para o treinamento do modelo;
- Criar o Bag of Words e treinar o modelo que fará a categorização;
- Categorizar novos links com o modelo treinado.
Com estas etapas em mente, vamos ao que interessa!
1. Baixar e extrair o conteúdo (Goose, o achado!)
Se você já criou algum tipo de web scraping, sabe como pode ser chato trabalhoso. Para os meus propósitos, era necessário extrair das páginas HTML apenas o conteúdo da matéria sem poluir o resultado com tags ou textos periféricos. Depois de muitas tentativas usando requests, lxml e regex, encontrei o projeto goose-extractor no pypi.
Em uma olhada rápida na documentação, percebemos que esse projeto é perfeito para o nosso caso e em 3 linhas ele resolve o problema:
Basta passar o link da página e o Goose faz o resto! Ele também permite acessar outros atributos da página, como o título da matéria, descriptors, etc. Vale a pena conferir!
Por se tratar de uma tarefa I/O Bound e serem mais de 700 links para baixar, estou usando a classe ThreadPoolExecutor do backport futures. O uso é muito simples e você pode saber mais na documentação do projeto!
2. Limpar o conteúdo (NLTK)
Com o texto das matérias em mãos, precisamos remover caracteres e palavras que podem atrapalhar o algoritmo de categorização, deixando apenas as palavras que possam contribuir com o “entendimento” do texto. Na primeira etapa, removo praticamente tudo que não for texto:
Depois disso, precisamos remover as chamadas stop words que, em resumo, são palavras que se repetem muito em qualquer texto e podem prejudicar a análise feita pelo algoritmo. Isso é feito com a ajuda do projeto NLTK.
O NLTK pode ser instalado via pip, mas depois da sua instalação é preciso baixar o pacote stopwords pelo gerenciador do próprio NLTK. Vou deixar lincadas as instruções das 2 etapas.
Depois de tudo instalado, é fácil remover as stop words dos nossos textos:
Por fim, criamos um DataFrame pandas para reunir os links, as categorias e os textos processados:
3. Bag of words
Em resumo rápido, bag of words é um modelo de representação textual que ignora a ordem e a gramática das palavras, mas preserva sua multiplicidade. Um exemplo pode nos ajudar:
O texto: “Rafael gosta muito de assistir filmes. A Ana gosta de filmes também” é transformado em uma lista de palavras:
Depois disso, o modelo gera uma lista com a frequência que cada palavra aparece no texto : [1, 2, 1, 2, 1, 2, 1, 1, 1].
Este processo, de traduzir palavras em números, é necessário, pois os algoritmos que vamos usar para classificar os textos só aceitam/”entendem” números. Para nossa sorte, o scikit-learn, uma das principais bibliotecas do tipo em Python, já tem uma classe para ajudar neste processo.
Abaixo, vou mostrar a função de treinamento por completo. Acredito que seja mais fácil explicar assim:
Das linhas 11 a 16, criamos a instância que vai montar o modelo bag of words dos textos que baixamos, mas por enquanto nada foi feito.
Na linha 17, é criada a instância que efetivamente vai analisar nossos dados e fazer predições. Como o nome sugere, será usada uma técnica chamada Regressão Logística para fazer a classificação dos textos. Eu testei algumas técnicas diferentes de classificação, mas esta apresentou os melhores resultados, chegando a 84% de acerto! Você pode conferir os teste que fiz neste link aqui!
Na linha 18, reunimos os 2 processos anteriores em um pipeline. Isto foi necessário para facilitar a preservação e armazenamento do modelo treinado. Vamos falar disso daqui a pouco!
Da linha 19 a 21 usamos uma função do scikit-learn para dividir nossa massa de dados em 80% para treino e 20% para testar a precisão do modelo.
Da linha 22 a 25, nós treinamos nosso modelo, avaliamos a precisão do mesmo e mostramos essa informação no terminal.
Finalizando, na linha 26 o modelo é treinado novamente, mas agora com 100% dos dados, e na linha 27 usamos outra ferramenta do scikit-learn para salvar o modelo treinado em disco, pois não precisamos refazer todo este processo toda vez que o programa for usado.
4. Pronto para uso!
Finalmente! O programa está pronto para categorizar novos textos! Vamos ver a função predict!
A função recebe como parâmetros uma URL (que vamos categorizar) e o caminho para o arquivo salvo em disco com nosso modelo treinado.
A linha 2 carrega o pipeline que salvamos no disco como o CountVectorizer e o LogisticRegression.
A linha 3 usa uma função para baixar e processar o texto da URL fornecida. Basicamente, os passos 1 e 2 desse artigo.
A linha 4 usa nosso pipeline para criar o bag of words do texto e fazer a predição de qual a categoria que melhor representa este texto.
As linhas de 6 a 9 mostram todas as categorias que nosso modelo conhece e as respectivas probabilidades em relação ao texto que está sendo categorizado.
Vamos ver como funciona!
Agora que já falamos sobre as principais partes do programa, vamos vê-lo em ação! Para testar no seu computador, além de baixar o arquivo do programa e a lista de links, você precisará instalar as dependências. Tudo via pip install:
- futures
- goose-extractor
- pandas
- nltk
- scikit-learn
O programa usa 3 parâmetros; FILE é o caminho para o arquivo CSV com os links das matérias que você pode baixar aqui. O formato do arquivo é muito simples e você pode montar o seu com outros links e categorias.
TRAIN é o nome do arquivo com o modelo treinado. Se o arquivo já existir, o programa usa o modelo existente; caso contrário, ele vai baixar os dados e processar.
Primeiro, vamos baixar os dados, processá-los e treinar nosso modelo. Esta é a saída do programa mostrando a quantidade de palavras em cada matéria:
Depois de algum tempo baixando e processando os dados, o programa nos mostra que ele salvou o arquivo bag_words.csv com os dados processados e a precisão do modelo após o treinamento. Chegamos a 79%!
Agora vamos testar se ele acerta a categoria desta matéria do G1 sobre tecnologia:
Concluindo (finalmente!)
Eu adoraria ficar aqui e te mostrar vários exemplos de como o programa acerta a categoria de várias matérias, mas você deve estar bem cansado – eu estou! rs
Bom, espero ter atingido meu objetivo e, pelo menos, motivado você a também estudar o assunto. Deixei vários links ao longo do texto e nas referências para te ajudar a entender melhor do que estamos falando.
Fique à vontade e comente o que achou aqui em baixo e se você souber como posso melhorar a precisão dos modelos usados, será de grande ajuda!
Referências
- http://www.andreykurenkov.com/writing/organizing-my-emails-with-a-neural-net/
- http://machinelearningmastery.com/multi-class-classification-tutorial-keras-deep-learning-library/
- http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html
- http://scikit-learn.org/stable/auto_examples/text/document_classification_20newsgroups.html
- http://nbviewer.jupyter.org/github/jmportilla/Udemy—Machine-Learning/blob/master/Multi-Class%20Classification.ipynb
Nenhum comentário:
Postar um comentário