<jupyter_start><jupyter_text>Parte 1 Imports- **numpy**: - **pandas**: - **nltk**: Para POS tagging, tokenização de sentenças e demais itens inerentes a NLP- **emoji**: Para converter emojis no texto para suas respectivas descriçrões- _emot_: Considerar o uso para extrair emojis e emoticons do texto- **re**: Para encontrar padrões por meio de expressões regulares<jupyter_code>import numpy as np
import pandas as pd
import nltk
from nltk.corpus import mac_morpho
import emoji
import re<jupyter_output><empty_output><jupyter_text>Leitura dos dadosLendo os dados do arquivo **banzeiro.json** em duas listas de objetos, que serão representados por `dicts`. Uma lista guardará os dados com os emojis substituídos pelas suas respectivas descrições e a outra, o conteúdo original.<jupyter_code>posts = pd.read_json("banzeiro.json")
posts.head()<jupyter_output><empty_output><jupyter_text>Verificando a estrutura dos dados, é possível perceber que existem colunas que não contém texto excrito por usuários, que uma publicação não possui legenda (`caption`) e que nem todas as instâncias possuem um vetor de comentários a ser processado (`comments`).<jupyter_code>posts.count()<jupyter_output><empty_output><jupyter_text>Parte 2 Limpeza de dadosAlgumas operações de limpeza dos dados deverão ser realizadas, considerando os seguintes pontos:- Algumas colunas não são relevantes no processamento de texto- Comentários que apenas mencionam outros usuários não expressam uma opinião- Publicações sem legenda não deixam claro a que se endereça a opinião- Publicações sem comentários não possuem opiniões a serem mineradas  Removendo colunas sem importância<jupyter_code>posts = posts.drop(["key", "datetime", "img_urls"], axis=1)
posts<jupyter_output><empty_output><jupyter_text>Removendo linhas onde caption ou comments são nulos<jupyter_code>posts = posts.dropna()
posts<jupyter_output><empty_output><jupyter_text>Removendo comentários que somente mencionam outros usuáriosFazendo o uso de Expressão Regular, qualquer comentário que contenha apenas nomes de outros usuários, com objetivo único de mencioná-los na publicação, será removido. Linhas que eventualmente fiquem sem comentários serão descartadas.<jupyter_code>for index, row in posts.iterrows():
    for comment in row["comments"]:
        if re.search("^(@[a-z0-9_.]*\s*)+$", comment["comment"]):
            posts.at[index, "comments"].remove(comment)
posts = posts.dropna()
posts<jupyter_output><empty_output><jupyter_text>Parte 3 Convertendo o dataframe para dictCom a parte de limpeza dos dados finalizada e antes do processamento realizado pelo NLTK, os dados serão representados em forma de **dict**.<jupyter_code>posts = posts.to_dict('records')<jupyter_output><empty_output><jupyter_text>Tokenizando sentenças e StringsFazendo o uso do **nltk**, serão tokenizadas as sentenças e palavras do dataset. As sentenças serão quebradas com o tokenizador **Punkt** treinado para o Português, e as palavras, quebrando nos espaços em branco.<jupyter_code>nltk.download("punkt")
sent_tokenizer=nltk.data.load('tokenizers/punkt/portuguese.pickle')<jupyter_output>[nltk_data] Downloading package punkt to /home/miguel/nltk_data...
[nltk_data]   Package punkt is already up-to-date!<jupyter_text>POS TaggingA marcação de _Part-of-Speech_ será feita com _taggers_ do NLTK treinados com o _corpus_ **Mac Morpho** de notícias do jornal Folha de S. Paulo de 1994. Para manter o código mais limpo, a tokenização e as marcações ocorrerão em conjunto.<jupyter_code>tsents = mac_morpho.tagged_sents()<jupyter_output><empty_output><jupyter_text>- *noun_tagger* é o tagger default, se nenhum outro resolve, ele assume que é um substantivo- *unigram_tagger* é um tagger para unigramas, baseado na maior frequência de tags encontrada nos corpus de treino- *bigram_tagger* é um tagger para bigramas que avalia a palavra levando em consideração a palavra anterior, afim de resolver ambiguidades<jupyter_code>noun_tagger = nltk.DefaultTagger('N')
unigram_tagger = nltk.UnigramTagger(tsents, backoff=noun_tagger)
bigram_tagger = nltk.BigramTagger(tsents, backoff=unigram_tagger)
for p in posts:
    sentences = sent_tokenizer.tokenize(p["caption"])
    print("Caption: " )
    p["caption"] = [bigram_tagger.tag(nltk.word_tokenize(sentence)) for sentence in sentences]
    print(p["caption"], "\n\n")
    for c in p["comments"]:
        print("Comment: " )
        sentences = sent_tokenizer.tokenize(c["comment"])
        c["comment"] = [bigram_tagger.tag(nltk.word_tokenize(sentence)) for sentence in sentences]
        print(c["comment"], "\n\n")<jupyter_output>Caption: 
[[('Já', 'ADV'), ('provou', 'V'), ('os', 'ART'), ('nossos', 'PROADJ'), ('Chás', 'N'), ('Gelados', 'N'), ('?', '?')], [('As', 'ART'), ('três', 'NUM'), ('combinações', 'N'), ('que', 'PRO-KS-REL'), ('vem', 'V'), ('chamando', 'V'), ('a', 'ART'), ('atenção', 'N'), ('dos', 'N'), ('nossos', 'PROADJ'), ('clientes', 'N'), ('que', 'PRO-KS-REL'), ('optam', 'N'), ('por', 'PREP'), ('uma', 'ART'), ('opção', 'N'), ('refrescante', 'N'), ('e', 'KC'), ('não', 'ADV'), ('alcoólica', 'ADJ'), (':', ':'), ('Hibisco', 'N'), ('com', 'PREP'), ('Abacaxi', 'N'), ('de', 'PREP'), ('Manaus', 'NPROP'), (',', ','), ('Limão', 'NPROP'), ('com', 'PREP'), ('Alecrim', 'N'), ('e', 'KC'), ('Maracujá', 'N'), ('com', 'PREP'), ('Cumaru', 'N'), ('.', '.')]] 


Comment: 
[[('Deliciosos', 'N')]] 


Caption: 
[[('Uma', 'ART'), ('das', 'NPROP'), ('entradas', 'N'), ('exclusivas', 'ADJ'), ('do', 'KS'), ('Banzeiro', 'N'), ('Manaus', 'NPROP'), ('.', 'NPROP')], [('Experimente', 'V|+'), ('o', 'PROPESS'), ('nosso', 'PROADJ'), ('T[...]
{'fraction_non_alphanumeric': 0.15607142857142858, 'fraction_numerical': 0.0017857142857142857, 'mean_word_length': 6.217783505154639, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '108565', 'license': 'MIT', 'n_tokens_mistral': 2063, 'n_tokens_neox': 2025, 'n_words': 577, 'path': 'Notebooks/teste-banzeiro/banzeiro-nltk.ipynb', 'repo_name': 'edgallojr/opinion-mining', 'size': '5600'}