{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport operator\nfrom sklearn import metrics\nfrom sklearn.linear_model import LinearRegression\nfrom sklearn.model_selection import train_test_split\nfrom keras import backend as K, initializers, regularizers, constraints, optimizers, layers\nfrom keras.layers import Dense, Input, LSTM, Embedding, Dropout, Activation, CuDNNGRU, Conv1D, concatenate\nfrom keras.layers import Bidirectional, GlobalMaxPool1D, GlobalMaxPooling1D, GlobalAveragePooling1D\nfrom keras.layers import Input, Embedding, Dense, Conv2D, MaxPool2D, concatenate, Lambda\nfrom keras.layers import Reshape, Flatten, Concatenate, Dropout, SpatialDropout1D\nfrom keras.preprocessing.sequence import pad_sequences\nfrom keras.preprocessing.text import Tokenizer\nfrom keras.optimizers import Adam\nfrom keras.models import Model\nfrom keras.engine.topology import Layer     \n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Preprocesamiento"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# Carga de los datasets de la competencia a nuestro kernel \ntrain = pd.read_csv(\"../input/quora-insincere-questions-classification/train.csv\")\ntest = pd.read_csv(\"../input/quora-insincere-questions-classification/test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Este es el tamaño del vector embedding \nword_vector = 300 \n# Cantidad de palabras a tomar para matriz de embeddings  \nmax_features = 100000 \n # Tamaño maximo de cada pregunta \nsize_question = 40","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Definición de funciones"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Recorre el parametro \"texto\" ingresado a la función para identificar cada palabra y su respectivo numero de ocurrencias a lo largo de texto\n# En otras palabras, se nos dara un diccionario de las palabras\n\ndef crear_vocabulario(texto):  \n    oraciones = texto.apply(lambda x: x.split()).values \n    vocabulario = {}\n    \n    for oracion in oraciones:\n        for palabra in oracion: \n            try:\n                vocabulario[palabra] += 1\n            except KeyError:\n                vocabulario[palabra] = 1\n    return vocabulario\n\n\ndf = pd.concat([train ,test], sort=False)\n\nvocabulario = crear_vocabulario(df['question_text'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Esta funcion toma el parametro \"archivo\" para la creacion de un embedding_index\n# Embedding index: diccionario donde las claves son los embeddings y  los valores son vectores que contienen  sus respectiva representacion como embedding\n\ndef cargar_embeddings(archivo):\n    \n    def obten_coeficientes(palabra,*arr): \n        return palabra, np.asarray(arr, dtype='float32')\n    \n    embeddings_index = dict(obten_coeficientes(*o.split(\" \")) for o in open(archivo, encoding='latin'))\n    \n    return embeddings_index\n\n# Cargamos los embeddings de una de las fuentes dadas por la competencia. Se ha seleccionado trabajar bajo un embedding GloVe\nsrc_glove = '../input/quora-insincere-questions-classification/embeddings/glove.840B.300d/glove.840B.300d.txt'\n\nembedding_glove = cargar_embeddings(src_glove)\n\nlen(embedding_glove)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creamos una matriz llamada \"embedding_matrix\" que contenga dentro de ella todos los embeddings\n\ndef cargar_matriz_glove(word_index, embeddings_index):\n\n    embeddings = np.stack(embeddings_index.values())\n    emb_mean, emb_std = embeddings.mean(), embeddings.std()\n    word_vector = embeddings.shape[1]\n    \n    nb_words = min(max_features, len(word_index))\n    embedding_matrix = np.random.normal(emb_mean, emb_std, (nb_words, word_vector))\n\n    for palabra, i in word_index.items():\n        if i >= word_vector:\n            continue\n        embedding_vector = embeddings_index.get(palabra)\n        if embedding_vector is not None:\n            embedding_matrix[i] = embedding_vector\n\n    return embedding_matrix","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# El porcentaje que se imprimirá hace referencia a la extensión que nuestros embeddings cubren el vocabulario \n# Asimismo, se imprimiran las palabras del vocabulario con un mayor numero de ocurrencias a lo largo  del  texto\n\ndef check_coverage(vocabulario, embeddings_index):\n    palabra_conocida = {}\n    palabra_desconocida = {}\n    nb_palabra_conocida = 0\n    nb_palabra_desconocida = 0\n    for palabra in vocabulario.keys():\n        try:\n            palabra_conocida[palabra] = embeddings_index[palabra]\n            nb_palabra_conocida += vocabulario[palabra]\n        except:\n            palabra_desconocida[palabra] = vocabulario[palabra]\n            nb_palabra_desconocida += vocabulario[palabra]\n            pass\n    \n    \n    print('Se encontraron embeddings para el {:.3%} del vocabulario'.format(len(palabra_conocida)/len(vocabulario)))\n    print('Se encontraron embeddings para el {:.3%} de todo el cuerpo de texto'.format(nb_palabra_conocida/(nb_palabra_conocida + nb_palabra_desconocida)))\n    palabra_desconocida = sorted(palabra_desconocida.items(), key=operator.itemgetter(1))[::-1]\n\n    return palabra_desconocida","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"palabra_desconocida = check_coverage(vocabulario, embedding_glove)\n\n#Para mejorar el modelo se observaran que palabras no estan en el diccionario\npalabra_desconocida[:20]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# En el print realizado anteriormente, se ve que se toman en cuenta muchos factores que diferencian las  palabras entre si. Como la presencia de mayusculas en la palabra\n# Función para cambiar las palabras mayuscular a minusculas en el texto\n\ndef cambiar_mayusculas(embedding, vocabulario):\n    count = 0\n    for palabra in vocabulario:\n        if palabra in embedding and palabra.lower() not in embedding:  \n            embedding[palabra.lower()] = embedding[palabra]\n            count += 1\n    print(f\"Se agregaron {count} palabras al embedding\")\n    \n#se cambia todo a minusculas\ntrain['question_text'] = train['question_text'].apply(lambda x: x.lower())\ntest['question_text'] = test['question_text'].apply(lambda x: x.lower())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Antes de quitar mayúsculas\npalabra_desconocida = check_coverage(vocabulario, embedding_glove)\n# Después de quitar mayúsculas\ncambiar_mayusculas(embedding_glove, vocabulario) \npalabra_desconocida = check_coverage(vocabulario, embedding_glove)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Definimos las contracciones que se pueden encontrar en  el texto y sucesivamente el correspondiente reemplazo \nlista_contracciones = {\"ain't\": \"is not\", \"aren't\": \"are not\",\"can't\": \"cannot\", \"'cause\": \"because\", \"could've\": \"could have\",\n                       \"couldn't\": \"could not\", \"didn't\": \"did not\",  \"doesn't\": \"does not\", \"don't\": \"do not\", \"hadn't\": \"had not\",\n                       \"hasn't\": \"has not\", \"haven't\": \"have not\", \"he'd\": \"he would\",\"he'll\": \"he will\", \"he's\": \"he is\", \"how'd\": \"how did\",\n                       \"how'd'y\": \"how do you\", \"how'll\": \"how will\", \"how's\": \"how is\",  \"I'd\": \"I would\", \"I'd've\": \"I would have\",\n                       \"I'll\": \"I will\", \"I'll've\": \"I will have\",\"I'm\": \"I am\", \"I've\": \"I have\", \"i'd\": \"i would\", \"i'd've\": \"i would have\",\n                       \"i'll\": \"i will\",  \"i'll've\": \"i will have\",\"i'm\": \"i am\", \"i've\": \"i have\", \"isn't\": \"is not\", \"it'd\": \"it would\", \n                       \"it'd've\": \"it would have\", \"it'll\": \"it will\", \"it'll've\": \"it will have\",\"it's\": \"it is\", \"let's\": \"let us\", \n                       \"ma'am\": \"madam\", \"mayn't\": \"may not\", \"might've\": \"might have\",\"mightn't\": \"might not\",\"mightn't've\": \"might not have\", \n                       \"must've\": \"must have\", \"mustn't\": \"must not\", \"mustn't've\": \"must not have\", \"needn't\": \"need not\", \n                       \"needn't've\": \"need not have\",\"o'clock\": \"of the clock\", \"oughtn't\": \"ought not\", \"oughtn't've\": \"ought not have\", \n                       \"shan't\": \"shall not\", \"sha'n't\": \"shall not\", \"shan't've\": \"shall not have\", \"she'd\": \"she would\", \"she'd've\": \"she would have\", \n                       \"she'll\": \"she will\", \"she'll've\": \"she will have\", \"she's\": \"she is\", \"should've\": \"should have\", \"shouldn't\": \"should not\",\n                       \"shouldn't've\": \"should not have\", \"so've\": \"so have\",\"so's\": \"so as\", \"this's\": \"this is\",\"that'd\": \"that would\", \n                       \"that'd've\": \"that would have\", \"that's\": \"that is\", \"there'd\": \"there would\", \"there'd've\": \"there would have\", \n                       \"there's\": \"there is\", \"here's\": \"here is\",\"they'd\": \"they would\", \"they'd've\": \"they would have\", \"they'll\": \"they will\",\n                       \"they'll've\": \"they will have\", \"they're\": \"they are\", \"they've\": \"they have\", \"to've\": \"to have\", \"wasn't\": \"was not\", \n                       \"we'd\": \"we would\", \"we'd've\": \"we would have\", \"we'll\": \"we will\", \"we'll've\": \"we will have\", \"we're\": \"we are\",\n                       \"we've\": \"we have\", \"weren't\": \"were not\", \"what'll\": \"what will\", \"what'll've\": \"what will have\", \"what're\": \"what are\", \n                       \"what's\": \"what is\", \"what've\": \"what have\", \"when's\": \"when is\", \"when've\": \"when have\", \"where'd\": \"where did\", \n                       \"where's\": \"where is\", \"where've\": \"where have\", \"who'll\": \"who will\", \"who'll've\": \"who will have\", \"who's\": \"who is\", \n                       \"who've\": \"who have\", \"why's\": \"why is\", \"why've\": \"why have\", \"will've\": \"will have\", \"won't\": \"will not\", \n                       \"won't've\": \"will not have\", \"would've\": \"would have\", \"wouldn't\": \"would not\", \"wouldn't've\": \"would not have\", \n                       \"y'all\": \"you all\", \"y'all'd\": \"you all would\",\"y'all'd've\": \"you all would have\",\"y'all're\": \"you all are\",\n                       \"y'all've\": \"you all have\",\"you'd\": \"you would\", \"you'd've\": \"you would have\", \"you'll\": \"you will\", \"you'll've\": \"you will have\",\n                       \"you're\": \"you are\", \"you've\": \"you have\", 'colour': 'color', 'centre': 'center', 'favourite': 'favorite', \n                       'travelling': 'traveling', 'counselling': 'counseling', 'theatre': 'theater', 'cancelled': 'canceled', 'labour': 'labor', \n                       'organisation': 'organization', 'wwii': 'world war 2', 'citicise': 'criticize', 'youtu ': 'youtube ', 'Qoura': 'Quora', \n                       'sallary': 'salary', 'Whta': 'What', 'narcisist': 'narcissist', 'howdo': 'how do', 'whatare': 'what are', 'howcan': 'how can',\n                       'howmuch': 'how much', 'howmany': 'how many', 'whydo': 'why do', 'doI': 'do I', 'theBest': 'the best', 'howdoes': 'how does', \n                       'mastrubation': 'masturbation', 'mastrubate': 'masturbate', \"mastrubating\": 'masturbating', 'pennis': 'penis',\n                       'Etherium': 'Ethereum', 'narcissit': 'narcissist', 'bigdata': 'big data', '2k17': '2017', '2k18': '2018', 'qouta': 'quota', \n                       'exboyfriend': 'ex boyfriend', 'airhostess': 'air hostess', \"whst\": 'what', 'watsapp': 'whatsapp', 'demonitisation': 'demonetization',\n                       'demonitization': 'demonetization', 'demonetisation': 'demonetization'}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Agregamos mas palabras al vocabulario si deshacemos las contracciones, simplificando el contenido del texto \ndef quitar_contracciones(texto, lista):\n    caracteres_especiales = [\"’\", \"‘\", \"´\", \"`\"]\n    for s in caracteres_especiales:\n        texto = texto.replace(s, \"'\")\n    texto = ' '.join([lista[t] if t in lista else t for t in texto.split(\" \")])\n    return texto\n\n#Eliminando las contracciones\ntrain['question_text'] = train['question_text'].apply(lambda x: quitar_contracciones(x, lista_contracciones))\ntest['question_text'] = test['question_text'].apply(lambda x: quitar_contracciones(x, lista_contracciones))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Definimos más caracteres especiales que no se incluyeron anterioremente ya que no estan incluidos o vinculados a las contracciones\npuntuaciones = \"/-'?!.,#$%\\'()*+-/:;<=>@[\\\\]^_`{|}~\" + '\"\"“”’' + '∞θ÷α•à−β∅³π‘₹´°£€\\×™√²—–&'\npuntuaciones += '©^®` <→°€™› ♥←×§″′Â█½à…“★”–●â►−¢²¬░¶↑±¿▾═¦║―¥▓—‹─▒：¼⊕▼▪†■’▀¨▄♫☆é¯♦¤▲è¸¾Ã⋅‘∞∙）↓、│（»，♪╩╚³・╦╣╔╗▬❤ïØ¹≤‡√'\n\n#Funcion para obtener todos los caracteres desconocidos entre el embedding y la lista de caracteres\ndef caracteres_desconocidos(embedding, puntuacion):\n    desconocido = ''\n    for p in puntuacion:\n        if p not in embedding:\n            desconocido += p\n            desconocido += ' '\n    return desconocido","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Definiendo el diccionario para mapear los caracteres especiales\nlista_puntuaciones = {\"‘\": \"'\", \"´\": \"'\", \"°\": \"\", \"€\": \"e\", \"—\": \"-\", \"–\": \"-\", \"’\": \"'\", \"_\": \"-\", \"`\": \"'\", '“': '\"', '”': '\"', '“': '\"', \"£\": \"e\", '∞': 'infinity', 'θ': 'theta', '÷': '/', 'α': 'alpha', '•': '.', 'à': 'a', '−': '-', 'β': 'beta', '∅': '', '³': '3', 'π': 'pi', '…': ' '}\n\n#Funcion para eliminar caracteres desconocidos y reemplazarlos por el correspondiente\ndef eliminar_caracteres(texto, puntuacion, lista):\n    for p in lista:\n        texto = texto.replace(p, lista[p])\n    \n    for p in puntuacion:\n        texto = texto.replace(p, f' {p} ')\n    \n    return texto\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Eliminando caracteres especiales\ntrain['question_text'] = train['question_text'].apply(lambda x: eliminar_caracteres(x, puntuaciones, lista_puntuaciones))\ntest['question_text'] = test['question_text'].apply(lambda x: eliminar_caracteres(x, puntuaciones, lista_puntuaciones))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Reconstruyendo el diccionario\ndf = pd.concat([train ,test], sort=False)\nvocabulario = crear_vocabulario(df['question_text'])\n\n# Imprimiendo las primeras 10 palabras desconocidas del glove y los porcentajes de embeddings/texto\npalabara_desconocida = check_coverage(vocabulario, embedding_glove)\npalabra_desconocida[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Reservando un 10% para el conjunto de validacion usando la libreria sklearn\ntrain, val = train_test_split(train, test_size=0.2, random_state=42)\n\n#Rellenamos los espacios vacíos en nuestros datasets\nx_train = train['question_text'].fillna('_na_').values\nx_val = val['question_text'].fillna('_na_').values\nx_test = test['question_text'].fillna('_na_').values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Haciendo usao de la librería Keras, tokenizaremos oraciones de acuerdo a max_features en los datasets de entrenamiento, validacion y evaluacion \ntokenizer = Tokenizer(num_words = max_features)\ntokenizer.fit_on_texts(list(x_train))\n\nx_train = tokenizer.texts_to_sequences(x_train)\nx_val = tokenizer.texts_to_sequences(x_val)\nx_test = tokenizer.texts_to_sequences(x_test)\nprint(x_train[0])\n\n#Nos aseguraremos de que cada oracion tenga un tamaño de pregunta\nx_train = pad_sequences(x_train, maxlen = size_question)\nx_val = pad_sequences(x_val, maxlen = size_question)\nx_test = pad_sequences(x_test, maxlen = size_question)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Definimos los target values del modelo\ny_train = train['target'].values\ny_val = val['target'].values\n\n# Mezclando el conjunto de datos\nnp.random.seed(42)\n\ntrn_idx = np.random.permutation(len(x_train))\nval_idx = np.random.permutation(len(x_val))\n\nx_train = x_train[trn_idx]\ny_train = y_train[trn_idx]\nx_val = x_val[val_idx]\ny_val = y_val[val_idx]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Cargando la matriz glove de embeddings\nembedding_matrix_glove = cargar_matriz_glove(tokenizer.word_index, embedding_glove)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Attention(Layer):\n    def __init__(self, step_dim,\n                 W_regularizer=None, b_regularizer=None,\n                 W_constraint=None, b_constraint=None,\n                 bias=True, **kwargs):\n        self.supports_masking = True\n        self.init = initializers.get('glorot_uniform')\n\n        self.W_regularizer = regularizers.get(W_regularizer)\n        self.b_regularizer = regularizers.get(b_regularizer)\n\n        self.W_constraint = constraints.get(W_constraint)\n        self.b_constraint = constraints.get(b_constraint)\n\n        self.bias = bias\n        self.step_dim = step_dim\n        self.features_dim = 0\n        super(Attention, self).__init__(**kwargs)\n\n    def build(self, input_shape):\n        assert len(input_shape) == 3\n        shapeW = (input_shape[-1],)\n        shapeB = (input_shape[1],)\n        self.W = self.add_weight(shape= shapeW,\n                                 initializer=self.init,\n                                 name='{}_W'.format(self.name),\n                                 regularizer=self.W_regularizer,\n                                 constraint=self.W_constraint)\n        self.features_dim = input_shape[-1]\n\n        if self.bias:\n            self.b = self.add_weight(shape=shapeB,\n                                     initializer='zero',\n                                     name='{}_b'.format(self.name),\n                                     regularizer=self.b_regularizer,\n                                     constraint=self.b_constraint)\n        else:\n            self.b = None\n\n        self.built = True\n\n    def compute_mask(self, input, input_mask=None):\n        return None\n\n    def call(self, x, mask=None):\n        features_dim = self.features_dim\n        step_dim = self.step_dim\n\n        eij = K.reshape(K.dot(K.reshape(x, (-1, features_dim)),\n                        K.reshape(self.W, (features_dim, 1))), (-1, step_dim))\n\n        if self.bias:\n            eij += self.b\n\n        eij = K.tanh(eij)\n        a = K.exp(eij)\n\n        if mask is not None:\n            a *= K.cast(mask, K.floatx())\n\n        a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())\n\n        a = K.expand_dims(a)\n        weighted_input = x * a\n        return K.sum(weighted_input, axis=1)\n\n    def compute_output_shape(self, input_shape):\n        return input_shape[0], self.features_dim","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#se crea una funcion para aplicar la metrica de f1\ndef f1(y_true, y_pred):\n\n    def recall(y_true, y_pred):\n        \n        true_positives = K.sum(K.round(K.clip(y_true*y_pred, 0, 1)))\n        possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n        recall = true_positives/(possible_positives + K.epsilon())\n        return recall\n\n    def precision(y_true, y_pred):\n        \n        true_positives = K.sum(K.round(K.clip(y_true*y_pred, 0, 1)))\n        predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n        precision = true_positives/(predicted_positives + K.epsilon())\n        return precision\n\n    precision = precision(y_true, y_pred)\n    recall = recall(y_true, y_pred)\n\n    return 2*((precision*recall)/(precision+recall+K.epsilon()))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#se crea el modelo de lstm con attention\ndef modelo_lstm_att(embedding_matrix):\n    \n    x_input = Input(shape=(size_question,))\n    x = Embedding(max_features, word_vector, weights=[embedding_matrix], trainable=False)(x_input)\n    x = Bidirectional(LSTM(64, return_sequences=True))(x)\n    x = Bidirectional(LSTM(32, return_sequences=True))(x)\n    \n    att = Attention(size_question)(x)\n    \n    y = Dense(32, activation='relu')(att)\n    y = Dropout(0.1)(y)\n    y_output = Dense(1, activation='sigmoid')(y)    \n\n    model = Model(inputs=x_input, outputs=y_output)\n    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[f1, \n                                                                        \"acc\"])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Entrenamiento del modelo!\ndef train_pred(model, epochs=2):\n    \n    for e in range(epochs):\n        model.fit(x_train, y_train, batch_size=512, epochs=3, validation_data=(x_val, y_val))\n        pred_val_y = model.predict([x_val], batch_size=1024, verbose=0)\n        best_thresh = 0.5\n        best_score = 0.0\n        for thresh in np.arange(0.1, 0.501, 0.01):\n            thresh = np.round(thresh, 2)\n            score = metrics.f1_score(y_val, (pred_val_y > thresh).astype(int))\n            if score > best_score:\n                best_thresh = thresh\n                best_score = score\n\n        print(\"Val F1 Score: {:.4f}\".format(best_score))\n\n    pred_test_y = model.predict([x_test], batch_size=1024, verbose=0)\n\n    return pred_val_y, pred_test_y, best_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"paragram = '../input/quora-insincere-questions-classification/embeddings/paragram_300_sl999/paragram_300_sl999.txt'\nembedding_matrix_paragram = cargar_matriz_glove(tokenizer.word_index, cargar_embeddings(paragram))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"embedding_matrix = np.mean([embedding_matrix_glove, embedding_matrix_paragram], axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#creacion y entrenamiento del modelo\nmodel_lstm = modelo_lstm_att(embedding_matrix)\nmodel_lstm.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"outputs = []\npred_val_y, pred_test_y, best_score = train_pred(model_lstm, epochs=3)\noutputs.append([pred_val_y, pred_test_y, best_score, 'model_lstm_att only Glove'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#find best threshold\noutputs.sort(key=lambda x: x[2]) \nweights = [i for i in range(1, len(outputs) + 1)]\nweights = [float(i) / sum(weights) for i in weights] \n\npred_val_y = np.mean([outputs[i][0] for i in range(len(outputs))], axis = 0)\n\nthresholds = []\nfor thresh in np.arange(0.1, 0.501, 0.01):\n    thresh = np.round(thresh, 2)\n    res = metrics.f1_score(y_val, (pred_val_y > thresh).astype(int))\n    thresholds.append([thresh, res])\n    print(\"F1 score at threshold {0} is {1}\".format(thresh, res))\n    \nthresholds.sort(key=lambda x: x[1], reverse=True)\nbest_thresh = thresholds[0][0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Best threshold:\", best_thresh, \"and F1 score\", thresholds[0][1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#prediciones y archivo para el submit\npred_test_y = np.mean([outputs[i][1] for i in range(len(outputs))], axis = 0)\npred_test_y = (pred_test_y > best_thresh).astype(int)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.read_csv('../input/quora-insincere-questions-classification/sample_submission.csv')\nout_df = pd.DataFrame({\"qid\":sub[\"qid\"].values})\nout_df['prediction'] = pred_test_y\nout_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"","_uuid":"","trusted":true},"cell_type":"code","source":"import pandas as pd\nsample_submission = pd.read_csv(\"../input/quora-insincere-questions-classification/sample_submission.csv\")\ntest = pd.read_csv(\"../input/quora-insincere-questions-classification/test.csv\")\ntrain = pd.read_csv(\"../input/quora-insincere-questions-classification/train.csv\")","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}