{"cells":[{"metadata":{"id":"svDDvMhYgxwM","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"95a9914f-ce8e-46f6-e9fb-46d2671cb78f","trusted":true,"_uuid":"1642a59f5e4d475a1757b74cf74fc4f48f5cecc3"},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom keras.preprocessing.text import Tokenizer,  text_to_word_sequence\nfrom keras.engine.topology import Layer\nfrom keras import initializers as initializers, regularizers, constraints\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.utils.np_utils import to_categorical\nfrom keras.preprocessing.sequence import pad_sequences\nfrom keras.layers import Embedding, Input, Dense, LSTM, GRU, Bidirectional, TimeDistributed, Dropout, CuDNNLSTM\nfrom keras import backend as K\nfrom keras import optimizers\nfrom keras.models import Model\nimport nltk\nimport re\nimport matplotlib.pyplot as plt\nimport sys\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn import metrics\nfrom nltk import tokenize,word_tokenize\nimport gc\nfrom tqdm import tqdm\ntqdm.pandas()\ngc.collect()\nimport seaborn as sns","execution_count":null,"outputs":[]},{"metadata":{"id":"u01IFY1Hgxwf","colab_type":"text","_uuid":"4440f99cbe40c318bd13ee6ecbbe1a3cb162fa40"},"cell_type":"markdown","source":"### Attention Layer"},{"metadata":{"id":"XbOJEMv7gxwi","colab_type":"code","colab":{},"trusted":true,"_uuid":"668e772f91421e5a8e87c3f97429c04d1d372f0d"},"cell_type":"code","source":"def dot_product(x, kernel):\n    \"\"\"\n    Wrapper for dot product operation, in order to be compatibl|e with both\n    Theano and Tensorflow\n    Args:\n        x (): input\n        kernel (): weights\n    Returns:\n    \"\"\"\n    if K.backend() == 'tensorflow':\n        return K.squeeze(K.dot(x, K.expand_dims(kernel)), axis=-1)\n    else:\n        return K.dot(x, kernel)\n\nclass AttentionWithContext(Layer):\n    \"\"\"\n    Attention operation, with a context/query vector, for temporal data.\n    Supports Masking.\n    Follows the work of Yang et al. [https://www.cs.cmu.edu/~diyiy/docs/naacl16.pdf]\n    \"Hierarchical Attention Networks for Document Classification\"\n    by using a context vector to assist the attention\n    # Input shape\n        3D tensor with shape: `(samples, steps, features)`.\n    # Output shape\n        2D tensor with shape: `(samples, features)`.\n    How to use:\n    Just put it on top of an RNN Layer (GRU/LSTM/SimpleRNN) with return_sequences=True.\n    The dimensions are inferred based on the output shape of the RNN.\n    Note: The layer has been tested with Keras 2.0.6\n    Example:\n        model.add(LSTM(64, return_sequences=True))\n        model.add(AttentionWithContext())\n        # next add a Dense layer (for classification/regression) or whatever...\n    \"\"\"\n\n    def __init__(self,\n                 W_regularizer=None, u_regularizer=None, b_regularizer=None,\n                 W_constraint=None, u_constraint=None, b_constraint=None,\n                 bias=True, **kwargs):\n\n        self.supports_masking = True\n        self.init = initializers.get('glorot_uniform')\n\n        self.W_regularizer = regularizers.get(W_regularizer)\n        self.u_regularizer = regularizers.get(u_regularizer)\n        self.b_regularizer = regularizers.get(b_regularizer)\n\n        self.W_constraint = constraints.get(W_constraint)\n        self.u_constraint = constraints.get(u_constraint)\n        self.b_constraint = constraints.get(b_constraint)\n\n        self.bias = bias\n        super(AttentionWithContext, self).__init__(**kwargs)\n\n    def build(self, input_shape):\n        assert len(input_shape) == 3\n\n        self.W = self.add_weight((input_shape[-1], input_shape[-1],),\n                                 initializer=self.init,\n                                 name='{}_W'.format(self.name),\n                                 regularizer=self.W_regularizer,\n                                 constraint=self.W_constraint)\n        if self.bias:\n            self.b = self.add_weight((input_shape[-1],),\n                                     initializer='zero',\n                                     name='{}_b'.format(self.name),\n                                     regularizer=self.b_regularizer,\n                                     constraint=self.b_constraint)\n\n        self.u = self.add_weight((input_shape[-1],),\n                                 initializer=self.init,\n                                 name='{}_u'.format(self.name),\n                                 regularizer=self.u_regularizer,\n                                 constraint=self.u_constraint)\n\n        super(AttentionWithContext, self).build(input_shape)\n\n    def compute_mask(self, input, input_mask=None):\n        # do not pass the mask to the next layers\n        return None\n\n    def call(self, x, mask=None):\n        uit = dot_product(x, self.W)\n\n        if self.bias:\n            uit += self.b\n\n        uit = K.tanh(uit)\n        ait = dot_product(uit, self.u)\n\n        a = K.exp(ait)\n\n        # apply mask after the exp. will be re-normalized next\n        if mask is not None:\n            # Cast the mask to floatX to avoid float64 upcasting in theano\n            a *= K.cast(mask, K.floatx())\n\n        # in some cases especially in the early stages of training the sum may be almost zero\n        # and this results in NaN's. A workaround is to add a very small positive number ε to the sum.\n        # a /= K.cast(K.sum(a, axis=1, keepdims=True), K.floatx())\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], input_shape[-1]","execution_count":null,"outputs":[]},{"metadata":{"id":"rWL4urlHgxwu","colab_type":"text","_uuid":"de867e70a1b042a2ac5a31a8fdcb0dbc2ddc13f9"},"cell_type":"markdown","source":"### Config"},{"metadata":{"id":"wvVCtTJbgxwx","colab_type":"code","colab":{},"trusted":true,"_uuid":"8e970050b9852e54e964961fe0110226348860c1"},"cell_type":"code","source":"max_features= 200000\nmax_senten_len = 40\nmax_senten_num = 3\nembed_size = 300\nVALIDATION_SPLIT = 0.1","execution_count":null,"outputs":[]},{"metadata":{"id":"iphJED4Qgxw8","colab_type":"text","_uuid":"da31e0150178690c03f71da4f77c1883a4639cb3"},"cell_type":"markdown","source":"### Data"},{"metadata":{"id":"SISE6xEnrKx_","colab_type":"code","colab":{},"trusted":true,"_uuid":"66b5c24a07ba29ee90cb163703dcf9433249000a"},"cell_type":"code","source":"from sklearn.utils import shuffle","execution_count":null,"outputs":[]},{"metadata":{"id":"83stXVBjgxw-","colab_type":"code","colab":{},"trusted":true,"_uuid":"1dfa79cd274172897f8f5a90594e7cbe1d30fc30"},"cell_type":"code","source":"df = pd.read_csv('../input/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c144abd805dcfa0f3120c31a739465f769c972d3"},"cell_type":"code","source":"test_df = pd.read_csv(\"../input/test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"60f0ecb944a3504916ad2f2b802858f35d5a4dee"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"yn2rJmMsfPOO","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"e8cc4a75-083a-4099-a16b-a4e9c414fb93","trusted":true,"_uuid":"bf9f1ccf81d0e91bc2722f119677314301a73af3"},"cell_type":"code","source":"len(df.target.unique())","execution_count":null,"outputs":[]},{"metadata":{"id":"mkBa2gzGq5MD","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":588},"outputId":"343f8c37-4ce1-4821-f42b-aee7c944d6b3","trusted":true,"_uuid":"4e2ea661300670641050fd8870ce3cea821f1a2d"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"cEhKU6wPq5HZ","colab_type":"code","colab":{},"trusted":true,"_uuid":"923adeea51ed5a9a2598f456f27a5aa596eb78bd"},"cell_type":"code","source":"df.columns = ['qid', 'text', 'category']\ntest_df.columns = ['qid', 'text']","execution_count":null,"outputs":[]},{"metadata":{"id":"7Q5PnT6M44If","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":626},"outputId":"994f280b-bc40-4f3a-b288-1b5a922c72cd","trusted":true,"_uuid":"a5fea8907a2d824ba0becf68142efe9ab6c56da6"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"QTbOuQw7gxxH","colab_type":"code","colab":{},"trusted":true,"_uuid":"120aa99478cccb4022937e6b6d3abd92c74f5bb3"},"cell_type":"code","source":"df = df[['text', 'category']]","execution_count":null,"outputs":[]},{"metadata":{"id":"JVUm8F55gxxP","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":142},"outputId":"b6dca62a-738e-448b-a935-f9dafef95ad7","trusted":true,"_uuid":"36ad12bc4f9634905d660c932d6eb93ec3d1df68"},"cell_type":"code","source":"df.info()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7bc0de8192893bd0e125562128e27f8c13699324"},"cell_type":"markdown","source":"## Preprocessing"},{"metadata":{"trusted":true,"_uuid":"8ad88c06ad9c6b8a67f4971a5d8f63d70c9d5697"},"cell_type":"code","source":"df['text'] = df['text'].apply(lambda x: x.lower())\ntest_df['text'] = test_df['text'].apply(lambda x: x.lower())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"29b7c9e16baba707786d2f33cf32aad268cc2c0b"},"cell_type":"code","source":"contraction_mapping = {\"ain't\": \"is not\", \"aren't\": \"are not\",\"can't\": \"cannot\", \"'cause\": \"because\", \"could've\": \"could have\", \"couldn't\": \"could not\", \"didn't\": \"did not\",  \"doesn't\": \"does not\", \"don't\": \"do not\", \"hadn't\": \"had not\", \"hasn't\": \"has not\", \"haven't\": \"have not\", \"he'd\": \"he would\",\"he'll\": \"he will\", \"he's\": \"he is\", \"how'd\": \"how did\", \"how'd'y\": \"how do you\", \"how'll\": \"how will\", \"how's\": \"how is\",  \"I'd\": \"I would\", \"I'd've\": \"I would have\", \"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\", \"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\", \"it'd've\": \"it would have\", \"it'll\": \"it will\", \"it'll've\": \"it will have\",\"it's\": \"it is\", \"let's\": \"let us\", \"ma'am\": \"madam\", \"mayn't\": \"may not\", \"might've\": \"might have\",\"mightn't\": \"might not\",\"mightn't've\": \"might not have\", \"must've\": \"must have\", \"mustn't\": \"must not\", \"mustn't've\": \"must not have\", \"needn't\": \"need not\", \"needn't've\": \"need not have\",\"o'clock\": \"of the clock\", \"oughtn't\": \"ought not\", \"oughtn't've\": \"ought not have\", \"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\", \"she'll\": \"she will\", \"she'll've\": \"she will have\", \"she's\": \"she is\", \"should've\": \"should have\", \"shouldn't\": \"should not\", \"shouldn't've\": \"should not have\", \"so've\": \"so have\",\"so's\": \"so as\", \"this's\": \"this is\",\"that'd\": \"that would\", \"that'd've\": \"that would have\", \"that's\": \"that is\", \"there'd\": \"there would\", \"there'd've\": \"there would have\", \"there's\": \"there is\", \"here's\": \"here is\",\"they'd\": \"they would\", \"they'd've\": \"they would have\", \"they'll\": \"they will\", \"they'll've\": \"they will have\", \"they're\": \"they are\", \"they've\": \"they have\", \"to've\": \"to have\", \"wasn't\": \"was not\", \"we'd\": \"we would\", \"we'd've\": \"we would have\", \"we'll\": \"we will\", \"we'll've\": \"we will have\", \"we're\": \"we are\", \"we've\": \"we have\", \"weren't\": \"were not\", \"what'll\": \"what will\", \"what'll've\": \"what will have\", \"what're\": \"what are\",  \"what's\": \"what is\", \"what've\": \"what have\", \"when's\": \"when is\", \"when've\": \"when have\", \"where'd\": \"where did\", \"where's\": \"where is\", \"where've\": \"where have\", \"who'll\": \"who will\", \"who'll've\": \"who will have\", \"who's\": \"who is\", \"who've\": \"who have\", \"why's\": \"why is\", \"why've\": \"why have\", \"will've\": \"will have\", \"won't\": \"will not\", \"won't've\": \"will not have\", \"would've\": \"would have\", \"wouldn't\": \"would not\", \"wouldn't've\": \"would not have\", \"y'all\": \"you all\", \"y'all'd\": \"you all would\",\"y'all'd've\": \"you all would have\",\"y'all're\": \"you all are\",\"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\", \"you're\": \"you are\", \"you've\": \"you have\", 'u.s':'america', 'e.g':'for example'}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"588facdf9e1cc7a5cabf4c4964c5572c0713484a"},"cell_type":"code","source":"def clean_contractions(text, mapping):\n    specials = [\"’\", \"‘\", \"´\", \"`\"]\n    for s in specials:\n        text = text.replace(s, \"'\")\n    text = ' '.join([mapping[t] if t in mapping else t for t in text.split(\" \")])\n    return text","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ab08938d0c9123331c6be94a5513763856a39cb6"},"cell_type":"code","source":"df['text'] = df['text'].apply(lambda x: clean_contractions(x, contraction_mapping))\ntest_df['text'] = test_df['text'].apply(lambda x: clean_contractions(x, contraction_mapping))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1494d4e502b0fde26012cdd77e1474e9dcee3723"},"cell_type":"code","source":"punct = \"/-'?!.,#$%\\'()*+-/:;<=>@[\\\\]^_`{|}~\" + '\"\"“”’' + '∞θ÷α•à−β∅³π‘₹´°£€\\×™√²—–&'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cc60c96d084d18d0360091e18631cfaa03138966"},"cell_type":"code","source":"punct_mapping = {\"‘\": \"'\", \"₹\": \"e\", \"´\": \"'\", \"°\": \"\", \"€\": \"e\", \"™\": \"tm\", \"√\": \" sqrt \", \"×\": \"x\", \"²\": \"2\", \"—\": \"-\", \"–\": \"-\", \"’\": \"'\", \"_\": \"-\", \"`\": \"'\", '“': '\"', '”': '\"', '“': '\"', \"£\": \"e\", '∞': 'infinity', 'θ': 'theta', '÷': '/', 'α': 'alpha', '•': '.', 'à': 'a', '−': '-', 'β': 'beta', '∅': '', '³': '3', 'π': 'pi', '!':' '}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4039d4fb243963d6834dfb4db67cb8fc5910bfce"},"cell_type":"code","source":"def clean_special_chars(text, punct, mapping):\n    for p in mapping:\n        text = text.replace(p, mapping[p])\n    \n    for p in punct:\n        text = text.replace(p, f' {p} ')\n    \n    specials = {'\\u200b': ' ', '…': ' ... ', '\\ufeff': '', 'करना': '', 'है': ''}  # Other special characters that I have to deal with in last\n    for s in specials:\n        text = text.replace(s, specials[s])\n    \n    return text","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"af1f7dbc784b5f7dc2f404c2aca4466e44b3a28d"},"cell_type":"code","source":"df['text'] = df['text'].apply(lambda x: clean_special_chars(x, punct, punct_mapping))\ntest_df['text'] = test_df['text'].apply(lambda x: clean_special_chars(x, punct, punct_mapping))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3751626328ec4182079a73610cbdae65b629d8bc"},"cell_type":"code","source":"mispell_dict = {'colour': 'color', 'centre': 'center', 'favourite': 'favorite', 'travelling': 'traveling', 'counselling': 'counseling', 'theatre': 'theater', 'cancelled': 'canceled', 'labour': 'labor', 'organisation': 'organization', 'wwii': 'world war 2', 'citicise': 'criticize', 'youtu ': 'youtube ', 'Qoura': 'Quora', 'sallary': 'salary', 'Whta': 'What', 'narcisist': 'narcissist', 'howdo': 'how do', 'whatare': 'what are', 'howcan': 'how can', 'howmuch': 'how much', 'howmany': 'how many', 'whydo': 'why do', 'doI': 'do I', 'theBest': 'the best', 'howdoes': 'how does', 'mastrubation': 'masturbation', 'mastrubate': 'masturbate', \"mastrubating\": 'masturbating', 'pennis': 'penis', 'Etherium': 'Ethereum', 'narcissit': 'narcissist', 'bigdata': 'big data', '2k17': '2017', '2k18': '2018', 'qouta': 'quota', 'exboyfriend': 'ex boyfriend', 'airhostess': 'air hostess', \"whst\": 'what', 'watsapp': 'whatsapp', 'demonitisation': 'demonetization', 'demonitization': 'demonetization', 'demonetisation': 'demonetization'}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dcd52e9658a9c38b569abc33b6915dfb2e0be61b"},"cell_type":"code","source":"def correct_spelling(x, dic):\n    for word in dic.keys():\n        x = x.replace(word, dic[word])\n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bbf6e8c271f3192ce6196e2261eb7731f2a045d2"},"cell_type":"code","source":"df['text'] = df['text'].apply(lambda x: correct_spelling(x, mispell_dict))\ntest_df['text'] = test_df['text'].apply(lambda x: correct_spelling(x, mispell_dict))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"648d67245cec720dee3ddc32189ea83ea5bf5d80"},"cell_type":"code","source":"labels = df['category']\ntext = df['text']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"83194acdaae61f8cba5efc4b006f10a20f7ef1b5"},"cell_type":"code","source":"indices = np.arange(text.shape[0])\nnp.random.shuffle(indices)\ntext = text[indices]\nlabels = labels.iloc[indices]\nnb_validation_samples = int(VALIDATION_SPLIT * df.shape[0])\n\ntrain_text = text[:-nb_validation_samples].reset_index().drop('index', axis=1)\ny_train = labels[:-nb_validation_samples].reset_index().drop('index', axis=1)\nval_text = text[-nb_validation_samples:].reset_index().drop('index', axis=1)\ny_val = labels[-nb_validation_samples:].reset_index().drop('index', axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"291adb991ec85f2507dc8b38d38e208cd0ee0954"},"cell_type":"code","source":"test = test_df['text']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"075915765f8f8ca4ba91691b8d220d1017b64fc5"},"cell_type":"code","source":"cates = df.groupby('category')\nprint(\"total categories:\", cates.ngroups)\nprint(cates.size())","execution_count":null,"outputs":[]},{"metadata":{"id":"YJOFyzjf5fe0","colab_type":"code","colab":{},"trusted":true,"_uuid":"86e266a58a5e847021fc6cebd4fc30991d02bdf9"},"cell_type":"code","source":"paras = []\nlabels = []\ntexts = []","execution_count":null,"outputs":[]},{"metadata":{"id":"FxeewB4Jgxx3","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":53},"outputId":"909116f6-d7a0-4383-91cb-f6de9d3171ed","trusted":true,"_uuid":"4b8f64afbf8acc01a08f6f4ec577053908c7cc7d"},"cell_type":"code","source":"sent_lens = []\nsent_nums = []\nfor idx in range(train_text.shape[0]):\n    text = train_text.text[idx]\n    texts.append(text)\n    sentences = tokenize.sent_tokenize(text)\n    sent_nums.append(len(sentences))\n    for sent in sentences:\n        sent_lens.append(len(text_to_word_sequence(sent)))\n    paras.append(sentences)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"88a937072dee076c6e7fd94446ddc47ebfdaae6d"},"cell_type":"code","source":"f, ax = plt.subplots(figsize=(12, 6))\nsns.distplot(sent_lens, ax=ax)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b54d956321b4f6598315566ca45ee661863700dc"},"cell_type":"code","source":"sns.distplot(sent_nums)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2fd6bb0a9179638ecee2bf52e4829a104575c7ef"},"cell_type":"code","source":"val_paras = []\nval_labels = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"aae6e7a65c9c9407293c6f91574ca51239f2a60e"},"cell_type":"code","source":"for idx in range(val_text.shape[0]):\n    text = val_text.text[idx]\n    sentences = tokenize.sent_tokenize(text)\n    val_paras.append(sentences)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e59c973e2d5a0f2df2b7a4e910bff272cd303418"},"cell_type":"code","source":"test_paras = []\ntest_labels = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cc8d187b1eb4c902b48f0e7b687b22c9c4d21ffa"},"cell_type":"code","source":"for idx in range(test.shape[0]):\n    text = test[idx]\n    sentences = tokenize.sent_tokenize(text)\n    test_paras.append(sentences)","execution_count":null,"outputs":[]},{"metadata":{"id":"zVjGIuJygxyP","colab_type":"code","colab":{},"trusted":true,"_uuid":"c3ea2a3aefd267b46c0947c04a7ad58bc9ca5e64"},"cell_type":"code","source":"tokenizer = Tokenizer(num_words=max_features, oov_token=True)\ntokenizer.fit_on_texts(texts)","execution_count":null,"outputs":[]},{"metadata":{"id":"99Jsdgjzgxyc","colab_type":"code","colab":{},"trusted":true,"_uuid":"2c6fca0199d8a02d21834d71b8acf8809cf3af39"},"cell_type":"code","source":"x_train = np.zeros((len(texts), max_senten_num, max_senten_len), dtype='int32')\nfor i, sentences in enumerate(paras):\n        tokenized_sent = tokenizer.texts_to_sequences(sentences)\n        padded_seq = pad_sequences(tokenized_sent, maxlen=max_senten_len, padding='post', truncating='post')\n        for j, seq in enumerate(padded_seq):\n            if(j < max_senten_num):\n                x_train[i,j,:] = seq\n            else:\n                break","execution_count":null,"outputs":[]},{"metadata":{"id":"OpKjmFmHgxyl","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"72313723-5fe8-49fa-9969-505c16be3cdc","trusted":true,"_uuid":"bd1e9d50df128646970caf5ce82de4af47ff6bdf"},"cell_type":"code","source":"x_train.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9db502983b824b6c0bf51684cd65182ffa87fc46"},"cell_type":"code","source":"x_val = np.zeros((val_text.shape[0], max_senten_num, max_senten_len), dtype='int32')\nfor i, sentences in enumerate(val_paras):\n        tokenized_sent = tokenizer.texts_to_sequences(sentences)\n        padded_seq = pad_sequences(tokenized_sent, maxlen=max_senten_len, padding='post', truncating='post')\n        for j, seq in enumerate(padded_seq):\n            if(j < max_senten_num):\n                x_val[i,j,:] = seq\n            else:\n                break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"87944d5b420b7606ad5463bbbd984c978e004bce"},"cell_type":"code","source":"test_data = np.zeros((test.shape[0], max_senten_num, max_senten_len), dtype='int32')\nfor i, sentences in enumerate(test_paras):\n        tokenized_sent = tokenizer.texts_to_sequences(sentences)\n        padded_seq = pad_sequences(tokenized_sent, maxlen=max_senten_len, padding='post', truncating='post')\n        for j, seq in enumerate(padded_seq):\n            if(j < max_senten_num):\n                test_data[i,j,:] = seq\n            else:\n                break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0a7406d8471c86347b5b08b15132067e95846673"},"cell_type":"code","source":"print(test_data.shape, x_val.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"YUgnmB2Igxyt","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"c5202c59-4f84-49fd-8bfa-5202f2b93262","trusted":true,"_uuid":"5d65bf7613c3e0e217b569fe1eb71fe7cc860cad"},"cell_type":"code","source":"word_index = tokenizer.word_index\nprint('Total %s unique tokens.' % len(word_index))","execution_count":null,"outputs":[]},{"metadata":{"id":"edq6g1Ybgxy3","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":53},"outputId":"6eb054ad-6950-4be5-e1ee-831c08847cfa","trusted":true,"_uuid":"3b57aabbe00d6cf62bd98d191c45706250416dab"},"cell_type":"code","source":"print('Shape of training tensor:', x_train.shape)\nprint('Shape of validation tensor:', x_val.shape)\nprint('Shape of test tensor:', test_data.shape)","execution_count":null,"outputs":[]},{"metadata":{"id":"l2UCwLNggxzM","colab_type":"text","_uuid":"a31545078acc77f424c95c33d59a96f502aba10b"},"cell_type":"markdown","source":"### Embeddings"},{"metadata":{"id":"PGRLk4Q1z1U-","colab_type":"code","colab":{},"trusted":true,"_uuid":"9bff7cfc93983318f015bc4758dfa94579b9cba1"},"cell_type":"code","source":"import os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"752e0a5d6ffcf6cba7815b963e23ed8546922e20"},"cell_type":"code","source":"gc.collect()\nword_index = tokenizer.word_index\nmax_features = len(word_index)+1\ndef load_glove(word_index):\n    EMBEDDING_FILE = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt'\n    def get_coefs(word,*arr): return word.lower(), np.asarray(arr, dtype='float32')\n    embeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(EMBEDDING_FILE) if o.split(\" \")[0] in word_index)\n\n    all_embs = np.stack(embeddings_index.values())\n    emb_mean,emb_std = all_embs.mean(), all_embs.std()\n    embed_size = all_embs.shape[1]\n    embedding_matrix = np.random.normal(emb_mean, emb_std, (max_features, embed_size))\n    for 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            \n    return embedding_matrix \n    \ndef load_fasttext(word_index):    \n    EMBEDDING_FILE = '../input/embeddings/wiki-news-300d-1M/wiki-news-300d-1M.vec'\n    def get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32')\n    embeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(EMBEDDING_FILE) if len(o)>100 and o.split(\" \")[0] in word_index )\n\n    all_embs = np.stack(embeddings_index.values())\n    emb_mean,emb_std = all_embs.mean(), all_embs.std()\n    embed_size = all_embs.shape[1]\n\n    embedding_matrix = np.random.normal(emb_mean, emb_std, (max_features, embed_size))\n    for 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\n    return embedding_matrix\n\ndef load_para(word_index):\n    EMBEDDING_FILE = '../input/embeddings/paragram_300_sl999/paragram_300_sl999.txt'\n    def get_coefs(word,*arr): return word.lower(), np.asarray(arr, dtype='float32')\n    embeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(EMBEDDING_FILE, encoding=\"utf8\", errors='ignore') if len(o)>100 and o.split(\" \")[0] in word_index)\n\n    all_embs = np.stack(embeddings_index.values())\n    emb_mean,emb_std = all_embs.mean(), all_embs.std()\n    embed_size = all_embs.shape[1]\n    \n    embedding_matrix = np.random.normal(emb_mean, emb_std, (max_features, embed_size))\n    for 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    return embedding_matrix","execution_count":null,"outputs":[]},{"metadata":{"id":"bp4upuqFu3Eb","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"2ac20441-d569-4bf5-e7af-aa23e31c866d","trusted":true,"_uuid":"88df613e2852c82455dfc92d953f5ff41b1569c0"},"cell_type":"code","source":"Embedding_funs = [load_glove,  load_fasttext, load_para]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f080b8b64ccc38db4b8abec350337198ce4f9fda"},"cell_type":"code","source":"import itertools","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7f617fb84ac8d0d0f4cc68a91d408ea0e04292ab"},"cell_type":"markdown","source":"## Model"},{"metadata":{"trusted":true,"_uuid":"18855e300f7850b94613e834bf434017e09eb8d7"},"cell_type":"code","source":"REG_PARAM = 1e-2\nl2_reg = regularizers.l2(REG_PARAM)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e4a246cf74c4b84a7501018f8ea51fb9d4c736f7"},"cell_type":"code","source":"def 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()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f52c4eb8832fbcd14175a3d143cfa56f202ae201"},"cell_type":"code","source":"# https://www.kaggle.com/ryanzhang/tfidf-naivebayes-logreg-baseline\n\ndef threshold_search(y_true, y_proba):\n    best_threshold = 0\n    best_score = 0\n    for threshold in [i * 0.01 for i in range(100)]:\n        score = metrics.f1_score(y_true=y_true, y_pred=y_proba > threshold)\n        if score > best_score:\n            best_threshold = threshold\n            best_score = score\n    search_result = {'threshold': best_threshold, 'f1': best_score}\n    return search_result","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8e47083f235794cafe378b323e09edb29a1d8143"},"cell_type":"code","source":"def get_model(embedding_matrix):\n    embedding_layer = Embedding(nb_words, embed_size, weights=[embedding_matrix])\n    word_input = Input(shape=(max_senten_len,), dtype='float32')\n    word_sequences = embedding_layer(word_input)\n    word_lstm = Bidirectional(CuDNNLSTM(max_senten_len, return_sequences=True, recurrent_regularizer=l2_reg))(word_sequences)\n    word_dense = TimeDistributed(Dense(64))(word_lstm)\n    word_att = AttentionWithContext()(word_dense)\n    wordEncoder = Model(word_input, word_att)\n\n    sent_input = Input(shape=(max_senten_num, max_senten_len), dtype='float32')\n    sent_encoder = TimeDistributed(wordEncoder)(sent_input)\n    sent_lstm = Bidirectional(CuDNNLSTM(max_senten_num, return_sequences=True, recurrent_regularizer=l2_reg))(sent_encoder)\n    sent_dense = TimeDistributed(Dense(32))(sent_lstm)\n    sent_att = AttentionWithContext()(sent_dense)\n    preds = Dense(1, activation='sigmoid', kernel_regularizer=l2_reg)(sent_att)\n    model = Model(sent_input, preds)\n    model.compile(loss='binary_crossentropy',optimizer='adam',metrics=[f1])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a61e9e9172b55bd43e3c1eb5f5e0df038dffedb4"},"cell_type":"code","source":"# https://www.kaggle.com/strideradu/word2vec-and-gensim-go-go-go\ndef train_pred(model, train_X, train_y, val_X, val_y, epochs=2, callback=None):\n    h = model.fit(train_X, train_y, batch_size=512, epochs=epochs, validation_data=(val_X, val_y), callbacks = callback, verbose=1)\n    model.load_weights(filepath)\n    pred_val_y = model.predict([val_X], batch_size=1024, verbose=0)\n    pred_test_y = model.predict([test_data], batch_size=1024, verbose=0)\n    print(metrics.f1_score(val_y, (pred_val_y > 0.33).astype(int)))\n    print('=' * 60)\n    return pred_val_y, pred_test_y","execution_count":null,"outputs":[]},{"metadata":{"id":"k4rWQsaV0Yx8","colab_type":"code","colab":{},"trusted":true,"_uuid":"e633b8544e7a209f099130c0573f6045dc9aeec5"},"cell_type":"code","source":"filepath=\"weights_best.h5\"\nvalidation_results = np.zeros((len(Embedding_funs), x_val.shape[0]))\ntest_results = np.zeros((len(Embedding_funs), test_data.shape[0]))\nfor indx, fun in enumerate(Embedding_funs):\n    checkpoint = ModelCheckpoint(filepath, monitor='val_f1', verbose=1, save_best_only=True, mode='max')\n    callbacks = [checkpoint]\n    embedding_matrix = fun(word_index)\n    nb_words = embedding_matrix.shape[0]\n    model = get_model(embedding_matrix)\n    pred_val_y , pred_test_y= train_pred(model, x_train, y_train, x_val, y_val, epochs = 3, callback = callbacks)\n    validation_results[indx] = pred_val_y.reshape(-1)   \n    test_results[indx] = pred_test_y.reshape(-1)\n    os.remove(filepath)\n    del model\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"id":"c2RcVWFTgxzc","colab_type":"code","colab":{},"trusted":true,"_uuid":"abdb6adfcfaace47815d0ae083ee45a0e2c31e6e"},"cell_type":"code","source":"def check_all_validations(validation_results, val_y, total=3):\n    all_combs_f1 = {}\n    all_combs_thres = {}\n    for i in range(total):\n        combinations = list(itertools.combinations(range(total), i+1))\n        for indexes in combinations:\n            val_res = np.mean(validation_results[list(indexes)], axis=0)\n            search_result = threshold_search(val_y, val_res)\n            all_combs_f1[indexes] = search_result['f1']\n            all_combs_thres[indexes] = search_result['threshold']\n    return all_combs_f1, all_combs_thres","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e770422e5d3d5cefa707f5b6eae32a678a228157"},"cell_type":"code","source":"all_combinations_f1, all_combinations_thresh = check_all_validations(validation_results, y_val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"584bf9efcb4b6237bc7533131461f5a94bbb9fd0"},"cell_type":"code","source":"for i in all_combinations_f1:\n    print(i, ':', all_combinations_f1[i], 'with threshold equals to', all_combinations_thresh[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9ab14fbdc69dc7299307b9cce1c08943b431eea9"},"cell_type":"code","source":"import operator\nall_comb_sorted = sorted(all_combinations_f1.items(), key=operator.itemgetter(1), reverse=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0fc92586069ba5e25d28eba0162fc8f5fddf8cf0"},"cell_type":"code","source":"pred_test_y = np.mean(test_results[list(all_comb_sorted[0][0])], axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e637e939a8967881dc3afd2a948e6d86669051a7"},"cell_type":"code","source":"best_thresh = all_combinations_thresh[all_comb_sorted[0][0]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f57e1d7a06862050aacacbbfb7f55fc00539a60a"},"cell_type":"code","source":"pred_test_y = (pred_test_y>best_thresh).astype(int)\nout_df = pd.DataFrame({\"qid\":test_df[\"qid\"].values})\nout_df['prediction'] = pred_test_y\nout_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3af0f03f198a6cd9264f02c03ff330912c13fbd6"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8110278ca3e17e74c0df74b384d09c0fa2917ffe"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"be411dc95a14fb8f36d1c795678c55351461af02"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"colab":{"name":"HAN.ipynb","version":"0.3.2","provenance":[],"collapsed_sections":[],"toc_visible":true},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"accelerator":"GPU","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}