{"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":"import os\nimport time\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom tqdm import tqdm\nimport math\nfrom sklearn.model_selection import train_test_split\nfrom sklearn import metrics\nfrom sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer\n\nfrom keras.preprocessing.text import Tokenizer\nfrom keras.preprocessing.sequence import pad_sequences\nfrom keras.layers import Dense, Input, LSTM, Embedding, Dropout, Activation, CuDNNGRU, Conv1D\nfrom keras.layers import Bidirectional, GlobalMaxPool1D\nfrom keras.models import Model\nfrom keras import initializers, regularizers, constraints, optimizers, layers\nfrom keras import backend as K","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"40b60804c7a60e1c2fd79d88a85dcd8829001374"},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/train.csv\")\ntest_df = pd.read_csv(\"../input/test.csv\")\nprint(\"Train shape : \",train_df.shape)\nprint(\"Test shape : \",test_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f96160223743c848913120141eed6e4c983ffc97"},"cell_type":"code","source":"print (\"train data class 0 count is %d, and class 1 count is %d\" %(list(train_df[\"target\"]).count(0), list(train_df[\"target\"]).count(1)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ba0852c05afa824348ae62980a415d6e2ebb7e16"},"cell_type":"code","source":"frac_0 = np.float(list(train_df[\"target\"]).count(0))/(list(train_df[\"target\"]).count(0) + list(train_df[\"target\"]).count(1))\nfrac_1 = np.float(list(train_df[\"target\"]).count(1))/(list(train_df[\"target\"]).count(0) + list(train_df[\"target\"]).count(1))\nprint (\"train data class 0 count fraction is %f, and class 1 count fraction is %f\" %(frac_0, frac_1))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"566b3e20c1e11ea5f0129af066fce73e8c352d90"},"cell_type":"code","source":"train_indices = np.where(train_df[\"target\"] == 1)[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c3440732277523430d75b91447ba6ea84fb55f09"},"cell_type":"code","source":"print (\"\\n\".join(list(train_df.iloc[train_indices].question_text)[:10]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1cafbf42df22d38bd9d0479fd3642a54e60d4a9e"},"cell_type":"code","source":"positive_indices = list(np.where(train_df[\"target\"] == 1)[0])\nnegative_indices = list(np.where(train_df[\"target\"] == 0)[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0848439a17448e935ba22eed7b381fa7f8b74c5c"},"cell_type":"code","source":"validation_fraction = 0.2\nval_pos_index = list(np.random.choice(positive_indices, int(len(positive_indices) * validation_fraction), replace = False))\ntrain_pos_index = list(set(positive_indices) - set(val_pos_index))\nval_neg_index = list(np.random.choice(negative_indices, int(len(negative_indices) * validation_fraction), replace = False))\ntrain_neg_index = list(set(negative_indices) - set(val_neg_index))\ntotal_negative = train_neg_index + val_neg_index\ntotal_positive = train_pos_index + val_pos_index\n\nif len(total_negative) != len(negative_indices):\n    raise Exception(\"class 0 length mismatch, please check..\")\nif len(total_positive) != len(positive_indices):\n    raise Exception(\"class 1 length mismatch, please check..\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fd09c5809694d5d43f710f6f437d81f096895582"},"cell_type":"code","source":"train_pos_index_resample = train_pos_index\nwhile len(train_pos_index_resample) < int(0.8 * len(train_neg_index)):\n    sample_indices = list(np.random.choice(train_pos_index, 10000, replace = False))\n    train_pos_index_resample += sample_indices","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f4ef996f4f4a554641c0ce43d1f9e7f3227b655a"},"cell_type":"code","source":"train_indices = train_pos_index + train_neg_index\nnp.random.shuffle(train_indices)\ntrain = train_df.iloc[train_indices]\n\nval_indices = val_pos_index + val_neg_index\nnp.random.shuffle(val_indices)\nval = train_df.iloc[val_indices]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dbfa7bca90f3a7b546adac10473e8ef891a8a2a7"},"cell_type":"code","source":"embed_size = 300 # how big is each word vector\nmax_features = 100000 # how many unique words to use (i.e num rows in embedding vector)\nmaxlen = 100 # max number of words in a question to use\n\n## fill up the missing values\ntrain_X = train[\"question_text\"].fillna(\"_na_\").values\nval_X = val[\"question_text\"].fillna(\"_na_\").values\ntest_X = test_df[\"question_text\"].fillna(\"_na_\").values\n\n## Tokenize the sentences\ntokenizer = Tokenizer(num_words=max_features)\ntokenizer.fit_on_texts(list(train_X))\ntrain_X = tokenizer.texts_to_sequences(train_X)\nval_X = tokenizer.texts_to_sequences(val_X)\ntest_X = tokenizer.texts_to_sequences(test_X)\n\n## Pad the sentences \ntrain_X = pad_sequences(train_X, maxlen=maxlen)\nval_X = pad_sequences(val_X, maxlen=maxlen)\ntest_X = pad_sequences(test_X, maxlen=maxlen)\n\n## Get the target values\ntrain_y = train['target'].values\nval_y = val['target'].values\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e202268f941e55dcd5c3e039ded54fbce9634b49"},"cell_type":"code","source":"def f1(y_true, y_pred):\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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9dcc073db6385fe6035f809983fac8a48fc061cf"},"cell_type":"code","source":"inp = Input(shape=(maxlen,))\nx = Embedding(max_features, embed_size)(inp)\nx = Bidirectional(CuDNNGRU(64, return_sequences=True))(x)\nx = GlobalMaxPool1D()(x)\nx = Dense(16, activation=\"relu\")(x)\nx = Dropout(0.1)(x)\nx = Dense(1, activation=\"sigmoid\")(x)\nmodel = Model(inputs=inp, outputs=x)\nmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=[f1])\n\nprint(model.summary())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"40da9f470cbcbdf5f64a18bc3c4536c019021141"},"cell_type":"code","source":"model.fit(train_X, train_y, batch_size=512, epochs=3, validation_data=(val_X, val_y))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"db2da2aa920c5ac4b03c13d732c8a20deff2d9b9"},"cell_type":"code","source":"pred_val_y = model.predict([val_X], batch_size=1024, verbose=1)\nthres_list = []; result = []\nfor thresh in np.arange(0.1, 0.501, 0.01):\n    thresh = np.round(thresh, 2)\n    print(\"F1 score at threshold {0} is {1}\".format(thresh, metrics.f1_score(val_y, (pred_val_y>thresh).astype(int))))\n    thres_list.append(thresh); result.append(metrics.f1_score(val_y, (pred_val_y>thresh).astype(int)))\n\nindices = np.argsort(result)[::-1]\nprint (\"best threhold is : {0}\".format(thres_list[indices[0]]))                                             \n                            ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"110f0f0121dcf359ec26e373fa62fbd18b29feba"},"cell_type":"code","source":"pred_noemb_test_y = model.predict([test_X], batch_size=1024, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f6017233e20cd893a0f5eafec6938c30d48c75f3"},"cell_type":"code","source":"pred_test_y = (pred_noemb_test_y>0.33).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":"906c9b6e8e5931f56270b714d145c9ca5168cde1"},"cell_type":"code","source":"","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}