Clasificación de sentimiento usando BERT

Representación Bidireccional para Transformadores, y pregunta-respuesta,

su adaptabilidad a las tareas visión que, las, tareas,

Tarea de clasificación de oraciones individuales BERT

BERT ha propuesto en las dos versiones:

  • BERT (BASE): 12 capas de pila de codificadores con 12 cabezales de autoatención bidireccionales y 768 unidades ocultas.
  • BERT (GRANDE): 24 capas de codificador con 24 cabezales de autoatención bidireccionales y 1024 unidades ocultas.

Para la implementación de TensorFlow, Google ha proporcionado dos versiones de BERT BASE y BERT LARGE: sin carcasa y con carcasa. En una versión sin mayúsculas y minúsculas, las letras se escriben en minúsculas antes de la tokenización de WordPiece.

Implementación:

  • Primero, necesitamos clonar el repositorio de GitHub en BERT para facilitar la configuración.

Código: 

python3

! git clone https://github.com / google-research / bert.git
Cloning into 'bert'...
remote: Enumerating objects: 340, done.
remote: Total 340 (delta 0), reused 0 (delta 0), pack-reused 340
Receiving objects: 100% (340/340), 317.20 KiB | 584.00 KiB/s, done.
Resolving deltas: 100% (185/185), done.
  • Ahora, necesitamos descargar el modelo BERT BASE utilizando el siguiente enlace y descomprimirlo en el directorio de trabajo (o en la ubicación deseada).

Código: 

python3

# Download BERT BASE model from tF hub ! wget https://storage.googleapis.com / bert_models / 2018_10_18 / uncased_L-12_H-768_A-12.zip ! unzip uncased_L-12_H-768_A-12.zip
Archive:  uncased_L-12_H-768_A-12.zip
   creating: uncased_L-12_H-768_A-12/
  inflating: uncased_L-12_H-768_A-12/bert_model.ckpt.meta  
  inflating: uncased_L-12_H-768_A-12/bert_model.ckpt.data-00000-of-00001  
  inflating: uncased_L-12_H-768_A-12/vocab.txt  
  inflating: uncased_L-12_H-768_A-12/bert_model.ckpt.index  
  inflating: uncased_L-12_H-768_A-12/bert_config.json  
  • Usaremos la versión TensorFlow 1x. En Google colab hay una función mágica llamada tensorflow_version que puede cambiar diferentes versiones.

Código: 

python3

% tensorflow_version 1.x
TensorFlow 1.x selected.
  • Ahora, importaremos los módulos necesarios para ejecutar este proyecto, usaremos NumPy, scikit-learn y Keras de los módulos incorporados de TensorFlow. Estos ya están preinstalados en colab, asegúrese de instalarlos en su entorno.

Código: 

python3

import os
import re
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow import keras
import csv
from sklearn import metrics
  • Ahora cargaremos conjuntos de datos de sentimientos de IMDB y haremos un preprocesamiento antes del entrenamiento. Para cargar el conjunto de datos IMDB desde TensorFlow Hub, seguiremos este tutorial. 

Código: 

python3

# load data from positive and negative directories and a columns that takes there\
# positive and negative label
def load_directory_data(directory):
  data = {}
  data["sentence"] = []
  data["sentiment"] = []
  for file_path in os.listdir(directory):
    with tf.gfile.GFile(os.path.join(directory, file_path), "r") as f:
      data["sentence"].append(f.read())
      data["sentiment"].append(re.match("\d+_(\d+)\.txt", file_path).group(1))
  return pd.DataFrame.from_dict(data)
 
# Merge positive and negative examples, add a polarity column and shuffle.
def load_dataset(directory):
  pos_df = load_directory_data(os.path.join(directory, "pos"))
  neg_df = load_directory_data(os.path.join(directory, "neg"))
  pos_df["polarity"] = 1
  neg_df["polarity"] = 0
  return pd.concat([pos_df, neg_df]).sample(frac = 1).reset_index(drop = True)
 
# Download and process the dataset files.
def download_and_load_datasets(force_download = False):
  dataset = tf.keras.utils.get_file(
      fname ="aclImdb.tar.gz",
      origin ="http://ai.stanford.edu/~amaas / data / sentiment / aclImdb_v1.tar.gz",
      extract = True)
   
  train_df = load_dataset(os.path.join(os.path.dirname(dataset),
                                       "aclImdb", "train"))
  test_df = load_dataset(os.path.join(os.path.dirname(dataset),
                                      "aclImdb", "test"))
   
  return train_df, test_df
train, test = download_and_load_datasets()
train.shape, test.shape
Downloading data from http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
84131840/84125825 [==============================] - 8s 0us/step
((25000, 3), (25000, 3))
  • Este conjunto de datos contiene 50 000 revisiones, 25 000 para cada entrenamiento y prueba, tomaremos muestras de 5 000 revisiones de cada prueba y entrenamiento. Además, tanto el conjunto de datos de prueba como el de entrenamiento contienen 3 columnas cuya lista se proporciona a continuación

Código: 

python3

# sample 5k datapoints for both train and test
train = train.sample(5000)
test = test.sample(5000)
# List columns of train and test data
train.columns, test.columns
(Index(['sentence', 'sentiment', 'polarity'], dtype='object'),
 Index(['sentence', 'sentiment', 'polarity'], dtype='object'))
  • Ahora, necesitamos convertir el formato específico que requiere el modelo BERT para entrenar y predecir, para eso usaremos el marco de datos pandas. A continuación se muestran las columnas requeridas en el formato de prueba y capacitación BERT:
    • GUID: una identificación para la fila. Requerido para datos de entrenamiento y prueba
    • Etiqueta de clase .: Un valor de 0 o 1 dependiendo del sentimiento positivo y negativo.
    • alfa: esta es una columna ficticia para la clasificación de texto, pero BERT la espera durante el entrenamiento.
    • texto:  El texto de revisión del punto de datos que necesitaba ser clasificado. Obviamente se requiere tanto para el entrenamiento como para la prueba.

Código: 

python3

# code
# Convert training data into BERT format
train_bert = pd.DataFrame({
  'guid': range(len(train)),
 'label':train['polarity'],
 'alpha': ['a']*train.shape[0],
 'text': train['sentence'].replace(r'\n', '', regex = True)
})
 
train_bert.head()
print("-----")
# convert test data into bert format
bert_test = pd.DataFrame({
 'id':range(len(test)),
 'text': test['sentence'].replace(r'\n', ' ', regex = True)
})
bert_test.head()
guid    label    alpha    text
14930    0    1    a    William Hurt may not be an American matinee id...
1445    1    1    a    Rock solid giallo from a master filmmaker of t...
16943    2    1    a    This movie surprised me. Some things were "cli...
6391    3    1    a    This film may seem dated today, but remember t...
4526    4    0    a    The Twilight Zone has achieved a certain mytho...
-----
guid    text
20010    0    One of Alfred Hitchcock's three greatest films...
16132    1    Hitchcock once gave an interview where he said...
24947    2    I had nothing to do before going out one night...
5471    3    tell you what that was excellent. Dylan Moran ...
21075    4    I watched this show until my puberty but still...
  • Ahora, dividimos los datos en tres partes: entrenar, desarrollar y probar y guardarlos en un archivo tsv, guardarlos en una carpeta (aquí, «Conjunto de datos IMDB»). Esto se debe a que ejecutar el archivo clasificador requiere un conjunto de datos en formato tsv.

Código: 

python3

# split  data into  train and validation set
bert_train, bert_val = train_test_split(train_bert, test_size = 0.1)
# save train, validation and testfile to afolder
bert_train.to_csv('bert / IMDB_dataset / train.tsv', sep ='\t', index = False, header = False)
bert_val.to_csv('bert / IMDB_dataset / dev.tsv', sep ='\t', index = False, header = False)
bert_test.to_csv('bert / IMDB_dataset / test.tsv', sep ='\t', index = False, header = True)
  • En este paso, entrenamos el modelo usando el siguiente comando, para ejecutar comandos bash en colab, usamos ! firmar delante del comando. El archivo run_classifier entrena el modelo con la ayuda del comando dado. Debido a limitaciones de tiempo y recursos, lo ejecutaremos solo en 3 épocas.

Código: 

python3

# Most of the arguments  hereare self-explanatory but some  arguments needs  to be explained:
# task name:We have discussed this above .Here we need toperform binary  classification that why we use cola
# vocab file :  A vocab file (vocab.txt) to map WordPiece to word id.
# init checkpoint:  A tensorflow checkpoint required. Here we used downloaded bert.
# max_seq_length :caps the maximunumber of words  to each reviews
# bert_config_file: file contains hyperparameter settings ! python bert / run_classifier.py
--task_name = cola --do_train = true --do_eval = true
--data_dir =/content / bert / IMDB_dataset
--vocab_file =/content / uncased_L-12_H-768_A-12 / vocab.txt
--bert_config_file =/content / uncased_L-12_H-768_A-12 / bert_config.json
--init_checkpoint =/content / uncased_L-12_H-768_A-12 / bert_model.ckpt
--max_seq_length = 64
--train_batch_size = 8 --learning_rate = 2e-5
--num_train_epochs = 3.0
--output_dir =/content / bert_output/
--do_lower_case = True
--save_checkpoints_steps 10000
# Last few lines
INFO:tensorflow:***** Eval results *****
I0713 06:06:28.966619 139722620139392 run_classifier.py:923] ***** Eval results *****
INFO:tensorflow:  eval_accuracy = 0.796
I0713 06:06:28.966814 139722620139392 run_classifier.py:925]   eval_accuracy = 0.796
INFO:tensorflow:  eval_loss = 0.95403963
I0713 06:06:28.967138 139722620139392 run_classifier.py:925]   eval_loss = 0.95403963
INFO:tensorflow:  global_step = 1687
I0713 06:06:28.967317 139722620139392 run_classifier.py:925]   global_step = 1687
INFO:tensorflow:  loss = 0.95741796
I0713 06:06:28.967507 139722620139392 run_classifier.py:925]   loss = 0.95741796
  • Ahora usaremos datos de prueba para evaluar nuestro modelo con el siguiente script bash. Este script guarda las predicciones en un archivo tsv.

Código: 

python3

# code to predict bert on test.tsv
# here we use  saved training checkpoint as  initial model ! python bert / run_classifier.py
--task_name = cola
--do_predict = true
--data_dir =/content / bert / IMDB_dataset
--vocab_file =/content / uncased_L-12_H-768_A-12 / vocab.txt
--bert_config_file =/content / uncased_L-12_H-768_A-12 / bert_config.json
--init_checkpoint =/content / bert_output / model.ckpt-0
--max_seq_length = 128
--output_dir =/content / bert_output/
INFO:tensorflow:Restoring parameters from /content/bert_output/model.ckpt-1687
I0713 06:08:22.372014 140390020667264 saver.py:1284] Restoring parameters from /content/bert_output/model.ckpt-1687
INFO:tensorflow:Running local_init_op.
I0713 06:08:23.801442 140390020667264 session_manager.py:500] Running local_init_op.
INFO:tensorflow:Done running local_init_op.
I0713 06:08:23.859703 140390020667264 session_manager.py:502] Done running local_init_op.
2020-07-13 06:08:24.453814: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
INFO:tensorflow:prediction_loop marked as finished
I0713 06:10:02.280455 140390020667264 error_handling.py:101] prediction_loop marked as finished
INFO:tensorflow:prediction_loop marked as finished
I0713 06:10:02.280870 140390020667264 error_handling.py:101] prediction_loop marked as finished
  • El siguiente código toma la predicción máxima para cada fila de datos de prueba y la almacena en una lista.

Código: 

python3

# code
import  csv
label_results =[]
with open('/content / bert_output / test_results.tsv') as file:
    rows = csv.reader(file, delimiter ="\t")
    for row in rows:
      data_1 =[float(i) for i in row]
      label_results.append(data_1.index(max(data_1)))
  • El siguiente código calcula la precisión y la puntuación F1.

Código: 

python3

print("Accuracy", metrics.accuracy_score(test['polarity'], label_results))
print("F1-Score", metrics.f1_score(test['polarity'], label_results))
Accuracy 0.8548
F1-Score 0.8496894409937888
  • Hemos logrado una precisión del 85 % y una puntuación F1 en el conjunto de datos de revisiones de IMDB mientras entrenábamos BERT (BASE) solo durante 3 épocas, lo que es un resultado bastante bueno. El entrenamiento en más épocas sin duda mejorará la precisión.

Referencias:

Publicación traducida automáticamente

Artículo escrito por pawangfg y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *