<jupyter_start><jupyter_text>Libs Usadas<jupyter_code>import nltk
import string
import numpy as np
import pandas as pd
from gensim.models import KeyedVectors
from sklearn.dummy import DummyClassifier
from sklearn.metrics import classification_report
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import CountVectorizer

nltk.download('punkt')<jupyter_output>[nltk_data] Downloading package punkt to /root/nltk_data...
[nltk_data]   Unzipping tokenizers/punkt.zip.<jupyter_text>Leitura dos dados<jupyter_code>artigo_treino = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/curso word2vec/treino.csv')
artigo_teste = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/curso word2vec/teste.csv')
display(artigo_treino.head())
display(artigo_treino.shape)
display(artigo_teste.head())
display(artigo_teste.shape)<jupyter_output><empty_output><jupyter_text>Estudo de como funciona o Word2Vec<jupyter_code>modelo = KeyedVectors.load_word2vec_format('/content/cbow_s300.txt')
modelo.most_similar('carro')
modelo.most_similar(positive=["brasil", "argentina", "uruguai"])
'''
Possível maneira de descobrir o plural de palavras.

nuvens -> nuvem
estrelas -> estrelas

Como descobrir o plural da palavra "estrelas" com base nas outras informações?

nuvens + estrela - nuvem = estrelas

As operações vetoriais deveriam resultar assim.
'''

modelo.most_similar(positive=["nuvens", "estrela"], negative=["nuvem"])
'''
Nem tudo funciona perfeitamente.

Nesse caso abaixo podemos ver o claro vies humano.
Onde é associado a figura da mulher a enfermeira em vez de médica.
'''

modelo.most_similar(positive=["médico", "mulher"], negative=["homem"])
'''
Para um caso em que não temos tanto um vies humano, a relação funciona
corretamente, pois nesse caso é mais comum associar a mulher o cargo
de professora.

Assim, é muito importante fazer um estudo dos dados que foram analisados.
'''

modelo.most_similar(positive=["professor", "mulher"], negative=["homem"])<jupyter_output><empty_output><jupyter_text>Tokenização Vetorização de textos<jupyter_code>artigo_treino.title.loc[8]
'''
Função que tokeniza um texto separando pela pontuação.

Recebe uma frase como entrada.
'''

def tokenizador(texto):
  lista_alfanumerica = list()

  texto_min = texto.lower()
  
  for token_valido in nltk.word_tokenize(texto_min):
    if token_valido in string.punctuation: continue
    lista_alfanumerica.append(token_valido)

  return lista_alfanumerica
'''
Função que cria e ajusta a frase de entrada para um vetor.

Recebe uma frase que já foi tokenizada como entrada.
'''

def combinacao_vetores_soma(palavras_numeros):
  vetor_resultante = np.zeros(300)

  for pn in palavras_numeros:
    try:
      vetor_resultante += modelo.get_vector(pn)
    except KeyError:
      if pn.isnumeric():
        pn = '0'*len(pn)
        vetor_resultante += modelo.get_vector(pn)
      else:
        vetor_resultante += modelo.get_vector('unknown')

  return vetor_resultante
'''
Ainda existem erros nesse algoritmo.

Como o fato de palavras escritas erradas gerarem erro no Word2Vec.

Também temos o problema dos números, onde é preciso transformar
todos para zero.

Isso foi descrito no artigo científico do projeto do Word2Vec que
estamos usando.

As correções foram feitas na função acima com o try : except.
'''

palavras_numeros = tokenizador("texto alura")
vetor_texto = combinacao_vetores_soma(palavras_numeros)
print(len(vetor_texto))
print(vetor_texto)
'''
Função para transformar o conjunto de treino e teste em uma
matriz de vetores.

Recebe o conjunto de textos do DataFrame como entrada.
'''

def matriz_vetores(textos):
  x = len(textos)
  y = 300
  matriz = np.zeros((x, y))

  for i in range(x):
    palavras_numeros = tokenizador(textos.iloc[i])
    matriz[i] = combinacao_vetores_soma(palavras_numeros)
  
  return matriz
matriz_vetores_treino = matriz_vetores(artigo_treino.title)
matriz_vetores_teste = matriz_vetores(artigo_teste.title)<jupyter_output><empty_output><jupyter_text>Treinamento e Comparações  Treinamento com CBOW<jupyter_code>print(matriz_vetores_treino.shape)
print(matriz_vetores_teste.shape)<jupyter_output>(90000, 300)
(20513, 300)<jupyter_text>Regressão Logística<jupyter_code>lr = LogisticRegression(max_iter=200)
lr.fit(matriz_vetores_treino, artigo_treino.category)
label_prevista = lr.predict(matriz_vetores_teste)
lr.score(matriz_vetores_teste, artigo_teste.category)
cr = classification_report(artigo_teste.category, label_prevista)
print(cr)<jupyter_output>precision    recall  f1-score   support

     colunas       0.86      0.72      0.78      6103
   cotidiano       0.61      0.79      0.69      1698
     esporte       0.93      0.88      0.90      4663
   ilustrada       0.13      0.88      0.23       131
     mercado       0.84      0.79      0.81      5867
       mundo       0.74      0.86      0.79      2051

    accuracy                           0.80     20513
   macro avg       0.68      0.82      0.70     20513
weighted avg       0.83      0.80      0.81     20513<jupyter_text>Dummy Classifier<jupyter_code>dc = DummyClassifier()
dc.fit(matriz_vetores_treino, artigo_treino.category)
label_prevista_dc = dc.predict(matriz_vetores_teste)
dc.score(matriz_vetores_teste, artigo_teste.category)
cr_dc = classification_report(artigo_teste.category, label_prevista_dc)
print(cr_dc)<jupyter_output>precision    recall  f1-score   support

     colunas       0.29      0.16      0.21      6103
   cotidiano       0.09      0.17      0.11      1698
     esporte       0.23      0.16      0.19      4663
   ilustrada       0.01      0.24      0.02       131
     mercado       0.29      0.17      0.21      5867
       mundo       0.11      0.19      0.14      2051

    accuracy                           0.17     20513
   macro avg       0.17      0.18      0.15     20513
weighted avg       0.24      0.17      0.19     20513<jupyter_text>Treinamento com Skip-gram<jupyter_code>modelo_skipgram = KeyedVectors.load_word2vec_format("skip_s300.txt")
def combinacao_vetores_soma_skipgram(palavras_numeros):
  vetor_resultante = np.zeros(300)

  for pn in palavras_numeros:
    try:
      vetor_resultante += modelo_skipgram.get_vector(pn)
    except KeyError:
      if pn.isnumeric():
        pn = '0'*len(pn)
        vetor_resultante += modelo_skipgram.get_vector(pn)
      else:
        vetor_resultante += modelo_skipgram.get_vector('unknown')

  return vetor_resultante

def matriz_vetores_skipgram(textos):
  x = len(textos)
  y = 300
  matriz = np.zeros((x, y))

  for i in range(x):
    palavras_numeros = tokenizador(textos.iloc[i])
    matriz[i] = combinacao_vetores_soma_skipgram(palavras_numeros)
  
  return matriz
matriz_vetores_treino_skipgram = matriz_vetores_skipgram(artigo_treino.title)
matriz_vetores_teste_skipgram = matriz_vetores_skipgram(artigo_teste.title)
lr_skipgram = LogisticRegression(max_iter=300)
lr_skipgram.fit(matriz_vetores_treino_skipgram, artigo_treino.category)
label_prevista_skipgram = lr.predict(matriz_vetores_teste_skipgram)
lr_skipgram.score(matriz_vetores_teste_skipgram, artigo_teste.category)
cr_skipgram = classification_report(artigo_teste.category, label_prevista_skipgram)
print(cr_skipgram)<jupyter_output>precision    recall  f1-score   support

     colunas       0.86      0.72      0.78      6103
   cotidiano       0.63      0.81      0.70      1698
     esporte       0.93      0.89      0.91      4663
   ilustrada       0.15      0.92      0.26       131
     mercado       0.84      0.82      0.83      5867
       mundo       0.76      0.86      0.81      2051

    accuracy                           0.81     20513
   macro avg       0.69      0.83      0.71     20513
weighted avg       0.84      0.81      0.82     20513
{'fraction_non_alphanumeric': 0.0815799664386214, 'fraction_numerical': 0.05060023234800568, 'mean_word_length': 3.365070422535211, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 30, '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': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '62745', 'license': 'MIT', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2849, 'n_words': 598, 'path': '2 - Word Embedding/Word2Vec.ipynb', 'repo_name': 'DaviSegundo/MachineLearning_Study', 'size': '7747'}