<jupyter_start><jupyter_text>Cargamos y analizamos el dataset<jupyter_code># Primer hyperparámetro
num_words=30000

(training_data, training_targets), (testing_data, testing_targets) = dataset.load_data(num_words=num_words+2)
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)
print(data)
print('\n')
print('# of Rows: {}', len(data))
print('# of Classes: {}', max(training_targets) + 1)
import pandas as pd
import numpy as np
print(np.shape(data[3]))
import pandas as pd
type(data)
#narray to dataframe
dfData = pd.DataFrame(data)
type(dfData)
dfData.describe()
import pandas as pd
type(targets)
#narray to dataframe
dfTarget = pd.DataFrame(targets)
type(dfTarget)
dfTarget.describe()
# Tengo dos categorías: Sentimiento positivo (1) o sentimiento negativo (0)
num_categories = len(np.unique(targets))
print("Categories:", np.unique(targets))
# Tengo num_words palabras únicas en el vocabulario
print("Number of unique words:", len(np.unique(np.hstack(data))))
# Longitudes promedio de los comentarios de las películas
length = [len(i) for i in data]
print("Average Review length:", np.mean(length))
print("Standard Deviation:", round(np.std(length)))
# Imprimo cometario i'esimo con su clasificación de sentimiento
i = 0
print("Label:", targets[i])
# Las comentarios ya están preprocesados
print(data[i])
# Bajamos diccionario de palabras a indices
index = dataset.get_word_index()
print([f'{k}:{v}' for k,v in index.items()][:100]) 

# Armo diccionario reverso: de indices a palabras
reverse_index = dict([(value, key) for (key, value) in index.items()]) 
print([f'{k}:{v}' for k,v in reverse_index.items()][:100])
decoded = " ".join( [reverse_index.get(i - 3, "#") for i in data[0]] )
print(data[0])
print()
print(decoded)
print(" ")
print("target", targets[0])
# Padding y formateo de data para entrenar
# Hyperparametro - Longitud máxima de comentario
maxlen=1000
# fill with zeros until maxlen
# narray > list it's transformed in narray > narray
#
data = pad_sequences(data,maxlen=maxlen)
type(data)
type(data)
# np.shape(data)
# print(data)
data.shape
# Verificamos que todos tengan longitud 1000
print(len(data[0]))
print(np.array([len(d) for d in data]).var())
data

# Armar una MLP con one-hot encoding para resolver el problema

from keras.layers import Dense, Dropout, Flatten
from keras.models import Sequential
data.size
np.shape(data)[0]
# one hot encoding
shape = (np.shape(data)[0], len(data[0]), data.max()+1)
shape
one_hot = np.zeros(shape)
np.shape(one_hot)
len(data[1])
# usar maxlen y num_words para calcular la entrada
# Utilizar una sola capa
model = Sequential()
salida_densa = 1
#input_shape = nro_columnas_features
input_shape = len(data[1])
model.add(Dense(50, activation = "relu", input_shape=(input_shape,)))
# model.add(Flatten())
model.add(Dense(salida_densa, activation='relu'))
model.summary()
#¿Por que no es viable esta red?
#Armar una MLP usando Embeddings
from keras.layers import Embedding, Flatten, Dropout, Conv1D, MaxPooling1D
from keras import optimizers
num_words
maxlen
# Cantidad de palabras totales contando las reservadas
nb_words=num_words+3
# Tamano del embedding. Es un hiperparámetro y puede modificarlo
embed_dim=32
salida_capa_densa = 1
dropout=0.3 # Hiperparámetro

model = Sequential()
model.add(Embedding(nb_words, embed_dim, input_length=maxlen, trainable=True))
model.add(Flatten())
model.add(Dropout(dropout))
model.add(Dense(salida_capa_densa, activation='sigmoid'))
model.summary()


# MODIFIQUE HYPERPARAMS A GUSTO
adam = optimizers.Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])



model.fit(data,targets,batch_size=32,epochs=5,validation_split=0.2)
#Armar una CNN
#Abajo hay un ejemplo de arquitecture
# _________________________________________________________________
# Layer (type)                 Output Shape              Param #   
# =================================================================
# embedding_12 (Embedding)     (None, 1000, 32)          960096    
# _________________________________________________________________
# conv1d_7 (Conv1D)            (None, 1000, 64)          14400     
# _________________________________________________________________
# max_pooling1d_4 (MaxPooling1 (None, 500, 64)           0         
# _________________________________________________________________
# conv1d_8 (Conv1D)            (None, 500, 128)          57472     
# _________________________________________________________________
# global_max_pooling1d_4 (Glob (None, 128)               0         
# _________________________________________________________________
# dropout_4 (Dropout)          (None, 128)               0         
# _________________________________________________________________
# dense_19 (Dense)             (None, 46)                5934      
# =================================================================
# Cantidad de palabras totales contando las reservadas
nb_words=num_words+3
# Tamano del embedding. Es un hiperparámetro y puede modificarlo
embed_dim=32
salida_capa_densa = 1
dropout=0.3 # Hiperparámetro

model = Sequential()
model.add(Embedding(nb_words, embed_dim, input_length=maxlen, trainable=True))
model.add(Conv1D(filters=16, kernel_size=4, activation='relu' , input_shape = (maxlen,embed_dim)))
model.add(MaxPooling1D())
model.add(Flatten())
model.add(Dropout(dropout))
model.add(Dense(salida_capa_densa, activation='sigmoid'))
model.summary()
# MODIFIQUE HYPERPARAMS A GUSTO
adam = optimizers.Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])
model.fit(data,targets,batch_size=32,epochs=10,validation_split=0.2)<jupyter_output>Train on 40000 samples, validate on 10000 samples
Epoch 1/10
40000/40000 [==============================] - 48s 1ms/step - loss: 0.3786 - acc: 0.8365 - val_loss: 0.2923 - val_acc: 0.8823
Epoch 2/10
40000/40000 [==============================] - 49s 1ms/step - loss: 0.2644 - acc: 0.8999 - val_loss: 0.2899 - val_acc: 0.8856
Epoch 3/10
40000/40000 [==============================] - 49s 1ms/step - loss: 0.2124 - acc: 0.9229 - val_loss: 0.3677 - val_acc: 0.8837
Epoch 4/10
40000/40000 [==============================] - 51s 1ms/step - loss: 0.2011 - acc: 0.9323 - val_loss: 0.4165 - val_acc: 0.8769
Epoch 5/10
40000/40000 [==============================] - 50s 1ms/step - loss: 0.1704 - acc: 0.9427 - val_loss: 0.4135 - val_acc: 0.8825
Epoch 6/10
40000/40000 [==============================] - 52s 1ms/step - loss: 0.1660 - acc: 0.9483 - val_loss: 0.5754 - val_acc: 0.8635
Epoch 7/10
40000/40000 [==============================] - 51s 1ms/step - loss: 0.1704 - acc: 0.9499 - val_loss: 0.5695 - val_acc[...]
{'fraction_non_alphanumeric': 0.16729982466393922, 'fraction_numerical': 0.06282875511396845, 'mean_word_length': 5.355617455896008, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '337626', 'license': 'MIT', 'n_tokens_mistral': 2606, 'n_tokens_neox': 2283, 'n_words': 560, 'path': '01-imdb-trainable-embeddings.ipynb', 'repo_name': 'j3nnn1/nlp_itba', 'size': '6844'}