from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments, DataCollatorWithPadding
from datasets import load_dataset, DatasetDict #alteração - load_metric moved to the evaluate package
from evaluate import load as load_metric #alteração - inclusão desta linha
from torch.utils.data import DataLoader, SequentialSampler
import torch
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay, classification_report
import pandas as pd # EXERCÍCIO 2 (OVERSAMPLING)
from datasets import Dataset
Obs: No Módulo 4, Unidade 7, o exemplo se oversampling utilizou a base de dados Titanic. Assim, o conjunto de dados (classe, idade e tarifa) era associado ao respectivo rótulo (sobreviveu ou morreu).
O SMOTE criou dados de modo que tenhamos o mesmo número de sobreviventes e mortos na base de dados.
SMOTE works by creating synthetic samples by interpolating between existing data points in the feature space. This interpolation requires numerical features, not raw text. The traceback shows the error originating from
the check_array function within scikit-learn, which is called by SMOTE to validate the input data. This function attempts to convert the input to a numerical array, but fails because of the string values in the 'text'
column of the X_train DataFrame.
print(dataset)
def show_info_dataset(dataset, title):
# Converter o dataset para um DataFrame do pandas
df = dataset.to_pandas()
# Contar as ocorrências na coluna 'label'
label_counts = df['label'].value_counts()
# Mapeamento dos labels para nomes
label_names = {0: 'Negativo', 1: 'Positivo', 2: 'Neutro'}
# Obter os nomes das labels
labels = [label_names[label] for label in label_counts.index]
# Definir as cores para cada label
colors = ['green', 'red', 'blue']
# Plotar o gráfico de barras
plt.figure(figsize=(10, 6))
bars = plt.bar(labels, label_counts, color=colors)
# Adicionar os totais em cima das barras
for bar in bars:
yval = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2, yval, int(yval), va='bottom') # va: vertical alignment
# Configurar o título e os rótulos dos eixos
plt.title(title)
plt.xlabel('Label')
plt.ylabel('Total')
plt.show()
show_info_dataset(train_dataset, 'Distribuição por Classe - Treino')
show_info_dataset(val_dataset, 'Distribuição por Classe - Validação')
show_info_dataset(test_dataset, 'Distribuição por Classe - Teste')
Reduz o tamanho dos datasets apenas para conseguir rodar no Google Colab por menos tempo, para rodar com o dataset completo só comentar as próximas 3 linhas
print("\n TRAIN DATASET\n")
display(train_dataset[:2]) # mostra as 2 primeiras amostras do train_dataset
print(len(train_dataset)) # 5000 amostras no total
display(train_dataset[4999]) # mostra, por completo, a última amostra
input_ids_size = len(train_dataset[0]['input_ids']) # Get the size of 'input_ids' for the first item
print(f"Size of 'input_ids' for the first item: {input_ids_size}")
Conclusão: cada uma das 5000 linhas das colunas 'input_ids' e 'attention_mask' é composta por 512 dados
#EXERCÍCIO 2 (TENTATIVA DE APLICAR OVERSAMPLING COM SMOTE - M4U7)
print("\n\n X TRAIN DATASET CONCATENADO\n")
display(x_train_concatenated[:2]) # mostra as 2 primeiras amostras do x_train_concatenated
print(len(x_train_concatenated)) # 5000 amostras no total
display(x_train_concatenated[4999]) # mostra, por completo, a última amostra
x_train_concatenated_size = len(x_train_concatenated[0]) # Get the size of x_train_concatenated for the first item
print(f"Size of x_train_concatenated: {x_train_concatenated_size}")
Conclusão: cada uma das 5000 linhas da train_concatenated é composta por 1024 dados
y_train = train_dataset['label']
print("\n\n Y TRAIN DATASET\n")
display(y_train[:2]) # mostra as 2 primeiras amostras do y_train
print(len(y_train)) # 5000
display(y_train[4999]) # mostra, por completo, a última amostra
cria o modelo smote através da classe SMOTE.
novamente o random_state é utilizado para que os dados sejam replicáveis
smote = SMOTE(random_state=42)
Cria novos dados com base no X_train e y_train utilizando o SMOTE.
Esses novos dados são guardados nas variáveis X_train_smote e y_train_smote
print("\n\n X TRAIN SMOTE\n")
display(X_train_smote[:2]) # mostra as 2 primeiras amostras do X_train_smote
print(len(X_train_smote)) # 9711 amostras no total, ou seja, o SMOTE gerou novas amostras
display(X_train_smote[4999]) # mostra, por completo, a última amostra
Create a new Dataset object from the SMOTE-augmented data
train_dataset = Dataset.from_dict({
'label': y_train_smote.tolist(), # Convert y_train_smote to a list
'input_ids': [row[:512].tolist() for row in X_train_smote], # Slice and convert to lists
'attention_mask': [row[512:].tolist() for row in X_train_smote] # Slice and convert to lists
})
print("\n\n TRAIN DATASET RECONSTITUÍDO\n")
display(train_dataset[:2]) # mostra as 2 primeiras amostras do train_dataset reconstituído
print(len(train_dataset)) # 5000 amostras no total
display(train_dataset[4999]) # mostra, por completo, a última amostra
input_ids_size = len(train_dataset[0]['input_ids']) # Get the size of 'input_ids' for the first item
print(f"Size of 'input_ids' for the first item: {input_ids_size}")
Conclusão: cada uma das 5000 linhas das colunas 'input_ids' e 'attention_mask' é composta por 512 dados
model = BertForSequenceClassification.from_pretrained(model_id, num_labels=num_labels)
def compute_metrics(eval_pred):
logits, labels = eval_pred
# Transforma os logits (saída do modelo) em previsões de classe, atribuindo a cada exemplo a classe com a
# maior probabilidade, ou seja, a que tem o maior valor de logit.
predictions = torch.argmax(torch.tensor(logits), dim=-1)
training_args = TrainingArguments(
output_dir=results_path, # Diretório de saída para os resultados
evaluation_strategy="epoch", # Estratégia de avaliação (avaliar a cada época)
learning_rate=3e-5, # Taxa de aprendizado
per_device_train_batch_size=batch_size, # Tamanho do batch de treino
per_device_eval_batch_size=batch_size, # Tamanho do batch de avaliação
num_train_epochs=3, # Número de épocas de treinamento
weight_decay=0.01, # Decaimento de peso
report_to="none", # alteração - inclusão desta linha
logging_dir="./logs", # alteração - inclusão desta linha
)
def predict_sentiment(text):
# Certificar que o modelo e os inputs estão no mesmo dispositivo (CPU ou GPU)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
# Tokeniza o texto, aplica padding e truncamento, converte para tensor PyTorch e move os dados para o dispositivo especificado.
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512).to(device)
model.eval()
with torch.no_grad():
# Executa o modelo com as entradas fornecidas, passando os tensores de input como argumentos para gerar as previsões ou saídas do modelo.
outputs = model(**inputs)
# Aplica a função softmax as saídas do modelo para converter os valores em probabilidades, normalizadas ao longo da última dimensão.
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
# Retorna a maior probabilidade
return probs.argmax().item()
example_text = "Eu adorei esse filme! Foi fantástico."
predicted_label = predict_sentiment(example_text)
sentiment = ['Negativo', 'Positivo', 'Neutro']
print(f"Sentimento previsto: {sentiment[predicted_label]}")
Seleciona a versão do modelo que será utilizada
model_id = "lfcc/bert-portuguese-ner"
from transformers import pipeline, AutoModelForTokenClassification, AutoTokenizer
Carregando o modelo e tokenizer
model = AutoModelForTokenClassification.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)
examples = [
"Paulo viajou para o Estados Unidos.",
"Marie Curie foi uma cientista polonesa que realizou pesquisas pioneiras sobre radioatividade.",
"Fernando Henrique Cardoso foi o primeiro presidente eleito após a ditadura no Brasil.",
"Petrobras foi fundada em 3 de outubro de 1953"
]
Realizando NER nos exemplos de texto
for example in examples:
ner_results = ner_pipeline(example)
print(f"Texto: {example}")
print("Entidades Nomeadas:")
for entity in ner_results:
print(f" - {entity['word']}: {entity['entity_group']} ({entity['score']*100:.2f}%)")
print()
examples = [
"I love learning about natural language processing.",
"The BERT model was developed by Google AI Research.",
"Machine translation is a challenging and interesting task."
]
Realizando a tradução dos exemplos de texto
for example in examples:
translation = translation_pipeline(example)
print(f"Texto original: {example}")
print(f"Tradução: {translation[0]['translation_text']}\n")