{"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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\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 the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"from keras.preprocessing.text import Tokenizer\nfrom keras.preprocessing.sequence import pad_sequences\nfrom keras_tqdm import TQDMNotebookCallback\n\nimport os\n\nimport tensorflow as tf\nimport keras as K\nprint(tf.__version__)\nprint(K.__version__)\nprint(tf.keras.__version__)\n\nimport numpy as np\nnp.random.seed(42)\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import f1_score\nfrom keras.models import Model\nfrom keras.layers import Input, Embedding, Dense, Conv2D, MaxPool2D\nfrom keras.layers import Reshape, Flatten, Concatenate, Dropout, SpatialDropout1D\nfrom keras.preprocessing import text, sequence\nfrom keras.callbacks import Callback\nfrom keras import backend as K\nimport warnings\nwarnings.filterwarnings('ignore')\n\nprint(os.listdir(\"../input\"))\nEMBEDDING_FILE = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt'\ntrain = pd.read_csv('../input/train.csv')\ntest = pd.read_csv('../input/test.csv')\nsubmission = pd.read_csv('../input/sample_submission.csv')\n\nX_train = train[\"question_text\"].fillna(\"_na_\").values\ny_train = train[\"target\"].values\nX_test = test[\"question_text\"].fillna(\"_na_\").values\n\nmax_features = 40000\nmaxlen = 300\nembed_size = 300\n\ntokenizer = text.Tokenizer(num_words=max_features)\ntokenizer.fit_on_texts(list(X_train) + list(X_test))\n\nX_train = tokenizer.texts_to_sequences(X_train)\nX_test = tokenizer.texts_to_sequences(X_test)\nx_train = sequence.pad_sequences(X_train, maxlen=maxlen)\nx_test = sequence.pad_sequences(X_test, maxlen=maxlen)\n\n# embdedding setup\n# Source https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html\nfrom tqdm import tqdm\n\nembeddings_index = {}\nf = open(EMBEDDING_FILE, 'r', encoding='utf-8')\nfor line in tqdm(f):\n    values = line.split(\" \")\n    word = values[0]\n    coefs = np.asarray(values[1:], dtype='float32')\n    embeddings_index[word] = coefs\nf.close()\n\nprint('Found %s word vectors.' % len(embeddings_index))\n\ndef f1(y_true, y_pred):\n    '''\n    metric from here \n    https://stackoverflow.com/questions/43547402/how-to-calculate-f1-macro-in-keras\n    '''\n    def recall(y_true, y_pred):\n        \"\"\"Recall metric.\n\n        Only computes a batch-wise average of recall.\n\n        Computes the recall, a metric for multi-label classification of\n        how many relevant items are selected.\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        \"\"\"Precision metric.\n\n        Only computes a batch-wise average of precision.\n\n        Computes the precision, a metric for multi-label classification of\n        how many selected items are relevant.\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    precision = precision(y_true, y_pred)\n    recall = recall(y_true, y_pred)\n    return 2*((precision*recall)/(precision+recall+K.epsilon()))\n\n\nword_index = tokenizer.word_index\nnb_words = min(max_features, len(word_index))\nprint(len(word_index), max_features)\nembedding_matrix = np.zeros((nb_words, embed_size))\nfor word, i in word_index.items():\n    if i >= max_features: continue\n    embedding_vector = embeddings_index.get(word)\n    if embedding_vector is not None: embedding_matrix[i] = embedding_vector\n        \nclass F1Evaluation(Callback):\n    def __init__(self, validation_data=(), interval=1):\n        super(Callback, self).__init__()\n\n        self.interval = interval\n        self.X_val, self.y_val = validation_data\n\n    def on_epoch_end(self, epoch, logs={}):\n        if epoch % self.interval == 0:\n            y_pred = self.model.predict(self.X_val, verbose=0)\n            y_pred = (y_pred > 0.5).astype(int)\n            score = f1_score(self.y_val, y_pred)\n            print(\"\\n F1 Score - epoch: %d - score: %.6f \\n\" % (epoch+1, score))\n            \n            \nfrom keras.models import Model\nfrom keras.layers import Input, Dropout, Activation, Dense, SpatialDropout1D,  BatchNormalization, PReLU\nfrom keras.layers.convolutional import Conv1D\nfrom keras.layers.pooling import GlobalMaxPooling1D, GlobalAveragePooling1D,MaxPooling1D\nfrom keras.layers.embeddings import Embedding\nfrom keras.preprocessing import sequence\nfrom keras.initializers import glorot_uniform\nfrom keras.layers import add\nfrom keras.preprocessing import text, sequence\nfrom keras.callbacks import Callback\nfrom keras import optimizers\nfrom keras import initializers, regularizers, constraints, callbacks\nnp.random.seed(1)\n\n#model\n#wrote out all the blocks instead of looping for simplicity\nfilter_nr = 64\nfilter_size = 3\nmax_pool_size = 3\nmax_pool_strides = 2\ndense_nr = 256\nspatial_dropout = 0.2\ndense_dropout = 0.5\ntrain_embed = False\nconv_kern_reg = regularizers.l2(0.00001)\nconv_bias_reg = regularizers.l2(0.00001)\n\ndef get_model():    \n    inp = Input(shape=(maxlen, ))\n    emb_comment = Embedding(max_features, embed_size, weights=[embedding_matrix], trainable=False)(inp)\n    \n    emb_comment = SpatialDropout1D(spatial_dropout)(emb_comment)\n\n    block1 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(emb_comment)\n    block1 = BatchNormalization()(block1)\n    block1 = PReLU()(block1)\n    block1 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block1)\n    block1 = BatchNormalization()(block1)\n    block1 = PReLU()(block1)\n\n    #we pass embedded comment through conv1d with filter size 1 because it needs to have the same shape as block output\n    #if you choose filter_nr = embed_size (300 in this case) you don't have to do this part and can add emb_comment directly to block1_output\n    resize_emb = Conv1D(filter_nr, kernel_size=1, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(emb_comment)\n    resize_emb = PReLU()(resize_emb)\n    \n    block1_output = add([block1, resize_emb])\n    block1_output = MaxPooling1D(pool_size=max_pool_size, strides=max_pool_strides)(block1_output)\n    \n    block2 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block1_output)\n    block2 = BatchNormalization()(block2)\n    block2 = PReLU()(block2)\n    block2 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block2)\n    block2 = BatchNormalization()(block2)\n    block2 = PReLU()(block2)\n    \n    block2_output = add([block2, block1_output])\n    block2_output = MaxPooling1D(pool_size=max_pool_size, strides=max_pool_strides)(block2_output)\n\n    block3 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block2_output)\n    block3 = BatchNormalization()(block3)\n    block3 = PReLU()(block3)\n    block3 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block3)\n    block3 = BatchNormalization()(block3)\n    block3 = PReLU()(block3)\n    \n    block3_output = add([block3, block2_output])\n    block3_output = MaxPooling1D(pool_size=max_pool_size, strides=max_pool_strides)(block3_output)\n\n    block4 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block3_output)\n    block4 = BatchNormalization()(block4)\n    block4 = PReLU()(block4)\n    block4 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block4)\n    block4 = BatchNormalization()(block4)\n    block4 = PReLU()(block4)\n\n    block4_output = add([block4, block3_output])\n    block4_output = MaxPooling1D(pool_size=max_pool_size, strides=max_pool_strides)(block4_output)\n\n    block5 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block4_output)\n    block5 = BatchNormalization()(block5)\n    block5 = PReLU()(block5)\n    block5 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block5)\n    block5 = BatchNormalization()(block5)\n    block5 = PReLU()(block5)\n\n    block5_output = add([block5, block4_output])\n    block5_output = MaxPooling1D(pool_size=max_pool_size, strides=max_pool_strides)(block5_output)\n\n    block6 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block5_output)\n    block6 = BatchNormalization()(block6)\n    block6 = PReLU()(block6)\n    block6 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block6)\n    block6 = BatchNormalization()(block6)\n    block6 = PReLU()(block6)\n\n    block6_output = add([block6, block5_output])\n    block6_output = MaxPooling1D(pool_size=max_pool_size, strides=max_pool_strides)(block6_output)\n\n    block7 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block6_output)\n    block7 = BatchNormalization()(block7)\n    block7 = PReLU()(block7)\n    block7 = Conv1D(filter_nr, kernel_size=filter_size, padding='same', activation='linear', \n                kernel_regularizer=conv_kern_reg, bias_regularizer=conv_bias_reg)(block7)\n    block7 = BatchNormalization()(block7)\n    block7 = PReLU()(block7)\n\n    block7_output = add([block7, block6_output])\n    output = GlobalMaxPooling1D()(block7_output)\n    \n    output = Dense(dense_nr, activation='linear')(output)\n    output = BatchNormalization()(output)\n    output = PReLU()(output)\n    output = Dropout(dense_dropout)(output)\n    \n                \n        \n    outp = Dense(1, activation=\"sigmoid\")(output)\n    \n    model = Model(inputs=inp, outputs=outp)\n    model.compile(loss='binary_crossentropy',\n                  optimizer='adam',\n                  metrics=['accuracy', f1])\n\n    return model\n\nmodel = get_model()\n\nmodel.summary()\n\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.models import load_model\nmodelname = \"submission_DPCNN-200seqlen.h5\"\n\ncheckpoint = ModelCheckpoint(filepath= modelname, monitor='val_f1', save_best_only=True, mode='max')\nbatch_size = 256\nepochs = 12\n\nX_tra, X_val, y_tra, y_val = train_test_split(x_train, y_train, train_size=0.95,\n                                              random_state=233)\nF1_Score = F1Evaluation(validation_data=(X_val, y_val), interval=1)\n\n\nhist = model.fit(X_tra, y_tra, batch_size=batch_size, epochs=epochs,\n                 validation_data=(X_val, y_val),\n                 callbacks=[F1_Score, checkpoint], verbose=2)\n\n\nmaxvalue = max(hist.history['val_acc'])\nepoch = hist.history['val_acc'].index(maxvalue) +1\nprint(epoch, maxvalue)\n\nfrom keras.models import load_model\nmodelmax = load_model(modelname,custom_objects={\"f1\": f1})\n\n\nfrom sklearn.metrics import confusion_matrix\nyprediction = modelmax.predict(X_val)\n\ny_pred = (yprediction > 0.5).astype(int)\ny_true = (y_val > 0.5).astype(int)\n\nscore = f1_score(y_val, y_pred)\nprint(\"F1_score: \", score)\n\n#confusion matrix\nimport itertools\nimport matplotlib.pyplot as plt\ndef plot_confusion_matrix(cm, classes,\n                          normalize=False,\n                          title='Confusion matrix',\n                          cmap=plt.cm.Blues):\n    \"\"\"\n    This function prints and plots the confusion matrix.\n    Normalization can be applied by setting `normalize=True`.\n    \"\"\"\n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j],\n                 horizontalalignment=\"center\",\n                 color=\"white\" if cm[i, j] > thresh else \"black\")\n\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n    \nbest_thresh = 0.5\nbest_score = 0\nfor thresh in np.arange(0.1, 0.501, 0.01):\n    thresh = np.round(thresh, 2)\n    score = f1_score(y_val, (yprediction>thresh).astype(int))\n    if score > best_score:\n        best_thresh = thresh\n        best_score = score\nprint(\"Best f1 = {} at threshold = {}\".format(best_score, best_thresh))\n\ny_pred_thresh = (yprediction > best_thresh).astype(int)\ny_true_thresh = (y_val > best_thresh).astype(int)\n\nconfusion_mtx = confusion_matrix(y_true_thresh, y_pred_thresh)\n#plot confusion matrix\nplot_confusion_matrix(confusion_mtx, classes = range(2))\n\n#prediction on test sample\ny_pred_test = modelmax.predict([x_test], batch_size = 1024, verbose = 1)\ny_pred_test_thresh = (y_pred_test > best_thresh).astype(int)\n\nprint(y_pred_test_thresh.shape)\n\nout_df = pd.DataFrame({\"qid\":test[\"qid\"].values})\nout_df['prediction'] = y_pred_test_thresh\nout_df.head(10)\n\nout_df.to_csv(\"submission.csv\", index=False)\n\nprint(\"submission done\")\n\n\n\n","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}