{"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":"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":"99c91c4effc2d21e407e1166eb3ec3ac32084aa1"},"cell_type":"code","source":"def clean_text(x):\n\n    x = str(x)\n    for punct in \"/-'\":\n        x = x.replace(punct, ' ')\n    for punct in '&':\n        x = x.replace(punct, f' {punct} ')\n    for punct in '?!.,\"#$%\\'()*+-/:;<=>@[\\\\]^_`{|}~' + '“”’':\n        x = x.replace(punct, '')\n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b7ffd5d3fdd2c4575a516f20e7a62ac207aa4024"},"cell_type":"code","source":"train_df[\"question_text\"] = train_df[\"question_text\"].apply(lambda x: clean_text(x))\ntest_df[\"question_text\"] = test_df[\"question_text\"].apply(lambda x: clean_text(x))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"01284db2537b879bd3165bdb8bf6c7ea493d318c"},"cell_type":"code","source":"mispell_dict = {'colour':'color',\n                'colours':'color',\n                'colors':'color',\n                'scores':'score',\n                'centre':'center',\n                'didnt':'did not',\n                'doesnt':'does not',\n                'isnt':'is not',\n                'shouldnt':'should not',\n                'favourite':'favorite',\n                'travelling':'traveling',\n                'counselling':'counseling',\n                'theatre':'theater',\n                'cancelled':'canceled',\n                'labour':'labor',\n                'organisation':'organization',\n                'wwii':'world war 2',\n                'citicise':'criticize',\n                'instagram': 'social medium',\n                'whatsapp': 'social medium',\n                'Snapchat': 'social medium',\n                'behaviour':'behavior',\n                'realise':'realize',\n                'favour':'favor',\n                'learnt':'learned',\n                'programme':'program',\n                'recognise':'recognize'\n                \n                }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"33e785c62a3edff315736a2c3b58331daf6c2247"},"cell_type":"code","source":"contraction_mapping = {\"ain't\": \"is not\", \"aren't\": \"are not\",\"can't\": \"cannot\",\n                       \"'cause\": \"because\", \"could've\": \"could have\", \"couldn't\": \"could not\", \n                       \"didn't\": \"did not\",  \"doesn't\": \"does not\", \"don't\": \"do not\",\n                       \"hadn't\": \"had not\", \"hasn't\": \"has not\", \"haven't\": \"have not\", \n                       \"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\", \n                       \"I'd\": \"I would\", \"I'd've\": \"I would have\", \"I'll\": \"I will\", \n                       \"I'll've\": \"I will have\",\"I'm\": \"I am\", \"I've\": \"I have\", \n                       \"i'd\": \"i would\", \"i'd've\": \"i would have\", \"i'll\": \"i will\", \n                       \"i'll've\": \"i will have\",\"i'm\": \"i am\", \"i've\": \"i have\", \n                       \"isn't\": \"is not\", \"it'd\": \"it would\", \"it'd've\": \"it would have\", \n                       \"it'll\": \"it will\", \"it'll've\": \"it will have\",\"it's\": \"it is\", \n                       \"let's\": \"let us\", \"ma'am\": \"madam\", \"mayn't\": \"may not\", \n                       \"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\",\n                       \"needn't\": \"need not\", \"needn't've\": \"need not have\",\"o'clock\": \"of the clock\",\n                       \"oughtn't\": \"ought not\", \"oughtn't've\": \"ought not have\", \"shan't\": \"shall not\", \n                       \"sha'n't\": \"shall not\", \"shan't've\": \"shall not have\", \"she'd\": \"she would\",\n                       \"she'd've\": \"she would have\", \"she'll\": \"she will\", \"she'll've\": \"she will have\",\n                       \"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\", \n                       \"this's\": \"this is\",\"that'd\": \"that would\", \"that'd've\": \"that would have\", \n                       \"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\", \n                       \"they'd've\": \"they would have\", \"they'll\": \"they will\", \n                       \"they'll've\": \"they will have\", \"they're\": \"they are\", \n                       \"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\", \n                       \"we'll've\": \"we will have\", \"we're\": \"we are\", \"we've\": \"we have\", \n                       \"weren't\": \"were not\", \"what'll\": \"what will\", \"what'll've\": \"what will have\",\n                       \"what're\": \"what are\",  \"what's\": \"what is\", \"what've\": \"what have\", \n                       \"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\", \n                       \"who'll've\": \"who will have\", \"who's\": \"who is\", \"who've\": \"who have\", \n                       \"why's\": \"why is\", \"why've\": \"why have\", \"will've\": \"will have\", \n                       \"won't\": \"will not\", \"won't've\": \"will not have\", \"would've\": \"would have\",\n                       \"wouldn't\": \"would not\", \"wouldn't've\": \"would not have\", \"y'all\": \"you all\", \n                       \"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\", \n                       \"you'll\": \"you will\", \"you'll've\": \"you will have\", \"you're\": \"you are\", \"you've\": \"you have\" }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e2ae1930edfb7cb7fd625ce2aebd0b57a259879"},"cell_type":"code","source":"def change_mispell(x):\n    text=x.split()\n    final_string = ' '.join(str(mispell_dict.get(word, word)) for word in text)\n    return final_string\n\ndef change_mispell2(x):\n    text=x.split()\n    final_string = ' '.join(str(contraction_mapping.get(word, word)) for word in text)\n    return final_string","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"769cba94fef6ee233b9d61155f8bde33e5a73d39"},"cell_type":"code","source":"train_df[\"question_text\"] = [change_mispell(x) for x in train_df[\"question_text\"]]\ntest_df[\"question_text\"] = [change_mispell(x) for x in test_df[\"question_text\"]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f84a6df5077b02a81ccfd5b3d69a4c86b0289598"},"cell_type":"code","source":"train_df['question_text'] = [change_mispell2(x) for x in train_df['question_text']]\ntest_df['question_text'] = [change_mispell2(x) for x in test_df['question_text']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4543b1359d0079ade562c7285108279a02049ee8"},"cell_type":"code","source":"## split to train and val\nfrom sklearn.model_selection import train_test_split\ntrain_df, val_df = train_test_split(train_df, test_size=0.1, random_state=2018)\n\n## some config values \nembed_size = 300 # how big is each word vector\nmax_features = 50000 # 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_df[\"question_text\"].fillna(\"_na_\").values\nval_X = val_df[\"question_text\"].fillna(\"_na_\").values\ntest_X = test_df[\"question_text\"].fillna(\"_na_\").values\n\n## Tokenize the sentences\nfrom keras.preprocessing.text import Tokenizer\nfrom keras.preprocessing.sequence import pad_sequences\n\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_df['target'].values\nval_y = val_df['target'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c529c2bf58020d4646e428067426812108b43488"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a0e08e78591ca51a9b4a21039131c4973013d19d"},"cell_type":"code","source":"print(train_X.shape)\nprint(val_X.shape)\nprint(train_y.shape)\nprint(val_y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"240e66467e2b9f904691c690596b62e492618c8d"},"cell_type":"code","source":"### preprocessing embedding\n# - use google\n\nembeddings_index_google = {}\nwith open('../input/embeddings/GoogleNews-vectors-negative300/GoogleNews-vectors-negative300.bin', \"rb\") as f:\n    header = f.readline()\n    vocab_size, layer1_size = map(int, header.split())\n    binary_len = np.dtype('float32').itemsize * layer1_size\n    for line in range(vocab_size):\n        word = []\n        while True:\n            ch = f.read(1).decode('latin-1')\n            if ch == ' ':\n                word = ''.join(word)\n                break\n            if ch != '\\n':\n                word.append(ch)\n        vector = np.frombuffer(f.read(binary_len), dtype='float32')\n        embeddings_index_google[word] = vector\n        if line % 100000 == 0:\n            print(word)\n\nword_index = tokenizer.word_index\nembedding_matrix = np.zeros((max_features, embed_size))\nfor word, i in word_index.items():\n    embedding_vector = embeddings_index_google.get(word)\n    if i < max_features:\n        if embedding_vector is not None:\n            # Words not found in embedding index will be all-zeros.\n            embedding_matrix[i] = embedding_vector","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dc7233360966a67b2682cf5e0555a0329250d6b4"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7075aaaf052d2e9c8ead053af8d722d123f6863c"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a57efd06907461abc460a2e21fbfda4e39623fa3"},"cell_type":"code","source":"## Define a model\nfrom keras.models import Sequential\nfrom keras.layers import Embedding, Conv1D, Flatten, Dense, Dropout\n\nmodel = Sequential()\nmodel.add(Embedding(input_dim=max_features, output_dim=embed_size, input_length=maxlen, weights=[embedding_matrix],name=\"embedding\"))\nmodel.add(Conv1D(64, 3, padding='same', name=\"conv1\"))\nmodel.add(Conv1D(32, 3, padding='same', name=\"conv2\"))\nmodel.add(Conv1D(16, 3, padding='same', name=\"conv3\"))\nmodel.add(Flatten(name=\"flatten\"))\nmodel.add(Dropout(0.5, name=\"dropout1\"))\nmodel.add(Dense(32, activation='relu', name=\"dense1\"))\nmodel.add(Dense(1, activation='sigmoid', name=\"output\"))\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"48e78032f21a954f975a2aeda9bfbe35bea0acc8"},"cell_type":"code","source":"model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\nmodel.fit(train_X, train_y, batch_size=512, epochs=1, validation_data=(val_X, val_y))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"32eb56e3f8c41fb24a4e8d3eafb3262feaa333d9"},"cell_type":"code","source":"pred_test_y_google = model.predict([test_X], batch_size=1024, verbose=1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2cdc603c0f10ab488f25d79931f6059abba5e977"},"cell_type":"code","source":"del word_index, embeddings_index, all_embs, embedding_matrix, model, inp, x\nimport gc; gc.collect()\ntime.sleep(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"27fc5b9f5cce30dfa670dfa1adc754d2d029cca3"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4c0dac666b28edeb502bf6669a854c8688febc43"},"cell_type":"code","source":"# use glove\n\nEMBEDDING_FILE = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt'\ndef get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32')\nembeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(EMBEDDING_FILE))\n\nall_embs = np.stack(embeddings_index.values())\nemb_mean,emb_std = all_embs.mean(), all_embs.std()\nembed_size = all_embs.shape[1]\n\nword_index = tokenizer.word_index\nnb_words = min(max_features, len(word_index))\nembedding_matrix = np.random.normal(emb_mean, emb_std, (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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"74459bf2c55d565a2b84afe0865ab502c687f46f"},"cell_type":"code","source":"## Define a model\nfrom keras.models import Sequential\nfrom keras.layers import Embedding, Conv1D, Flatten, Dense, Dropout\n\nmodel = Sequential()\nmodel.add(Embedding(input_dim=max_features, output_dim=embed_size, input_length=maxlen, weights=[embedding_matrix],name=\"embedding\"))\nmodel.add(Conv1D(64, 3, padding='same', name=\"conv1\"))\nmodel.add(Conv1D(32, 3, padding='same', name=\"conv2\"))\nmodel.add(Conv1D(16, 3, padding='same', name=\"conv3\"))\nmodel.add(Flatten(name=\"flatten\"))\nmodel.add(Dropout(0.5, name=\"dropout1\"))\nmodel.add(Dense(32, activation='relu', name=\"dense1\"))\nmodel.add(Dense(1, activation='sigmoid', name=\"output\"))\n\nmodel.summary()\n\nmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\nmodel.fit(train_X, train_y, batch_size=512, epochs=1, validation_data=(val_X, val_y))\n\npred_test_y_glove = model.predict([test_X], batch_size=1024, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0d0a7fc549e9d0b21efc69e7f5e95c493eb67379"},"cell_type":"code","source":"del word_index, embeddings_index, all_embs, embedding_matrix, model, inp, x\nimport gc; gc.collect()\ntime.sleep(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2490d9d7e768bf409b1a16ddd34f6a3d1a4f0383"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"270a0a7112bd0d27a7aa33c66b20198805525e31"},"cell_type":"code","source":"# wike\n\nEMBEDDING_FILE = '../input/embeddings/wiki-news-300d-1M/wiki-news-300d-1M.vec'\ndef get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32')\nembeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(EMBEDDING_FILE) if len(o)>100)\n\nall_embs = np.stack(embeddings_index.values())\nemb_mean,emb_std = all_embs.mean(), all_embs.std()\nembed_size = all_embs.shape[1]\n\nword_index = tokenizer.word_index\nnb_words = min(max_features, len(word_index))\nembedding_matrix = np.random.normal(emb_mean, emb_std, (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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a7954985c290856ba102966b041d5b684f1e241d"},"cell_type":"code","source":"## Define a model\nfrom keras.models import Sequential\nfrom keras.layers import Embedding, Conv1D, Flatten, Dense, Dropout\n\nmodel = Sequential()\nmodel.add(Embedding(input_dim=max_features, output_dim=embed_size, input_length=maxlen, weights=[embedding_matrix],name=\"embedding\"))\nmodel.add(Conv1D(64, 3, padding='same', name=\"conv1\"))\nmodel.add(Conv1D(32, 3, padding='same', name=\"conv2\"))\nmodel.add(Conv1D(16, 3, padding='same', name=\"conv3\"))\nmodel.add(Flatten(name=\"flatten\"))\nmodel.add(Dropout(0.5, name=\"dropout1\"))\nmodel.add(Dense(32, activation='relu', name=\"dense1\"))\nmodel.add(Dense(1, activation='sigmoid', name=\"output\"))\n\nmodel.summary()\n\nmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\nmodel.fit(train_X, train_y, batch_size=512, epochs=1, validation_data=(val_X, val_y))\n\npred_test_y_wiki = model.predict([test_X], batch_size=1024, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5bd49eda0ce4bf37004bbebf6dd70f6a25d54442"},"cell_type":"code","source":"del word_index, embeddings_index, all_embs, embedding_matrix, model, inp, x\nimport gc; gc.collect()\ntime.sleep(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a1287ba404c9ac1fc9c2b0b2fd1fc221098982b2"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"629bec27981a2ed3964806f111562004fdfc5191"},"cell_type":"code","source":"# use paragram\n\nEMBEDDING_FILE = '../input/embeddings/paragram_300_sl999/paragram_300_sl999.txt'\ndef get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32')\nembeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(EMBEDDING_FILE, encoding=\"utf8\", errors='ignore') if len(o)>100)\n\nall_embs = np.stack(embeddings_index.values())\nemb_mean,emb_std = all_embs.mean(), all_embs.std()\nembed_size = all_embs.shape[1]\n\nword_index = tokenizer.word_index\nnb_words = min(max_features, len(word_index))\nembedding_matrix = np.random.normal(emb_mean, emb_std, (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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"789e1292f12426613f5b4c9571eb209c4837c7a6"},"cell_type":"code","source":"## Define a model\nfrom keras.models import Sequential\nfrom keras.layers import Embedding, Conv1D, Flatten, Dense, Dropout\n\nmodel = Sequential()\nmodel.add(Embedding(input_dim=max_features, output_dim=embed_size, input_length=maxlen, weights=[embedding_matrix],name=\"embedding\"))\nmodel.add(Conv1D(64, 3, padding='same', name=\"conv1\"))\nmodel.add(Conv1D(32, 3, padding='same', name=\"conv2\"))\nmodel.add(Conv1D(16, 3, padding='same', name=\"conv3\"))\nmodel.add(Flatten(name=\"flatten\"))\nmodel.add(Dropout(0.5, name=\"dropout1\"))\nmodel.add(Dense(32, activation='relu', name=\"dense1\"))\nmodel.add(Dense(1, activation='sigmoid', name=\"output\"))\n\nmodel.summary()\n\nmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\nmodel.fit(train_X, train_y, batch_size=512, epochs=1, validation_data=(val_X, val_y))\n\npred_test_y_paragram = model.predict([test_X], batch_size=1024, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5e8a9c1a7d7838a5f12e0ca3bc57f0f5df6858d6"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d6b00e87ac5b72844796251a2f6ad3cee20cd656"},"cell_type":"code","source":"# stacking\npred_test_y = 0.25*pred_test_y_google + 0.25*pred_test_y_glove + 0.25*pred_test_y_wiki + 0.25*pred_test_y_paragram\npred_test_y = (pred_test_y>0.35).astype(int)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b608696c8577594bf460f584aa57890de74195b4"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"634ff4914ee8c760d553f0117504998dbd11b2f8"},"cell_type":"code","source":"out_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":"96df0f798a42280f9fc450136b8cc513ca336093"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6d3b1675debfe919b9a33f43fc40e0eaf4607bb0"},"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}