{"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_minor":4,"nbformat":4,"cells":[{"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\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 read-only \"../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# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-06T16:49:13.103157Z","iopub.execute_input":"2022-01-06T16:49:13.103674Z","iopub.status.idle":"2022-01-06T16:49:13.114001Z","shell.execute_reply.started":"2022-01-06T16:49:13.103625Z","shell.execute_reply":"2022-01-06T16:49:13.113215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **1. Tổng quan**","metadata":{}},{"cell_type":"markdown","source":"**Một vấn đề** tồn tại đối với bất kỳ trang web lớn nào hiện nay là làm thế nào để xử lý các nội dung độc hại và dễ gây chia rẽ. Quora, một nền tảng cho phép mọi người có thể đặt câu hỏi và kết nối với những người khác để nhận được câu trả lời chất lượng. Tuy nhiên, vẫn có tồn tại những câu hỏi nhạy cảm, có ý đồ gây chia rẽ , thay vì muốn tìm câu trả lời hữu ích. Vì vậy, ta cần phải xây dựng một mô hình phân loại được giữa những câu hỏi chân thành, mục đích tốt (Sincere) với những câu hỏi mang tính tiêu cực, không đúng đắn ấy (Insincere).\n\n**Input**: Câu hỏi trên Quora (text)\n\n**Output**: Nhãn Sincere hoặc Insincere","metadata":{}},{"cell_type":"markdown","source":"# **2. Xử lý dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"**2.1. Phân tích dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"Dữ liệu vào là các câu hỏi trên Quora. Nhiệm vụ phải làm là phân loại các câu hỏi ấy.\nMột câu hỏi bao gồm các thuộc tính:\n* qid : id duy nhất nhận diện câu hỏi.\n* question_text: câu hỏi dạng text.\n* target: nhãn của câu hỏi, có giá trị là 1 nếu là \"insincere\", ngược lại là 0.","metadata":{}},{"cell_type":"markdown","source":"Khi phân loại, ta dùng thuộc tính question_text là đầu vào X, target là đầu ra nhãn Y.","metadata":{}},{"cell_type":"code","source":"train_data = pd.read_csv(\"/kaggle/input/quora-insincere-questions-classification/train.csv\")\ntest_data = pd.read_csv(\"/kaggle/input/quora-insincere-questions-classification/test.csv\")\n\n#Tập train\ntrain_data","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:13.115567Z","iopub.execute_input":"2022-01-06T16:49:13.116099Z","iopub.status.idle":"2022-01-06T16:49:16.884634Z","shell.execute_reply.started":"2022-01-06T16:49:13.116057Z","shell.execute_reply":"2022-01-06T16:49:16.883728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Lấy ra tập câu hỏi có nhãn 1(Insincere)\ninsincere_data = train_data[train_data.target == 1]\n#Lấy ra tập câu hỏi có nhãn 0(Sincere)\nsincere_data = train_data[train_data.target == 0]","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:16.886092Z","iopub.execute_input":"2022-01-06T16:49:16.886406Z","iopub.status.idle":"2022-01-06T16:49:17.014320Z","shell.execute_reply.started":"2022-01-06T16:49:16.886364Z","shell.execute_reply":"2022-01-06T16:49:17.013448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:17.015744Z","iopub.execute_input":"2022-01-06T16:49:17.016235Z","iopub.status.idle":"2022-01-06T16:49:17.340003Z","shell.execute_reply.started":"2022-01-06T16:49:17.016190Z","shell.execute_reply":"2022-01-06T16:49:17.339113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Phân tích tỉ lệ câu hỏi Sincere và Insincere trong tập train**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport pandas as pd\n\ntemp = train_data['target'].value_counts(normalize=True).reset_index()\n\ncolors = ['#4f92ff', '#4ffff0']\nexplode = (0.05, 0.05)\n \nplt.pie(temp['target'], explode=explode, labels=temp['index'], colors=colors,\n         autopct='%1.1f%%', shadow=True, startangle=0)\n \nfig = plt.gcf()\nfig.set_size_inches(12, 6)\nfig.suptitle('% Target', fontsize=16)\nplt.axis('equal')\nplt.show()\nprint(\"--------------------------\")\nprint( \"Dữ liệu Insincere chiếm\", insincere_data.shape[0] / train_data.shape[0] * 100)\nprint( \"Dữ liệu Sincere chiếm\", sincere_data.shape[0] / train_data.shape[0] * 100)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:17.342845Z","iopub.execute_input":"2022-01-06T16:49:17.343350Z","iopub.status.idle":"2022-01-06T16:49:17.487888Z","shell.execute_reply.started":"2022-01-06T16:49:17.343304Z","shell.execute_reply":"2022-01-06T16:49:17.487108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Phân tích các từ xuất hiện nhiều nhất bằng n-gram** : là tần suất xuất hiện của n kí tự ( hoặc từ ) liên tiếp nhau có trong dữ liệu của corpus.\n* unigram, mô hình với n=1, tức là ta sẽ tính tần suất xuất hiện của một kí tự (từ), như: “k”, “a”,…\n* bigrams với n=2, mô hình được sử dụng nhiều trong việc phân tích các hình thái cho ngôn ngữ, ví dụ với các chữ cái tiếng Anh, ‘th’,’he’,’in’,’an’,’er’ là các cặp kí tự hay xuất hiện nhất.\n* trigrams với n=3.","metadata":{}},{"cell_type":"code","source":"from wordcloud import STOPWORDS\nfrom collections import defaultdict\nimport seaborn as sns\n\ndef ngram_extractor(text, n_gram):\n    token = [token for token in text.lower().split(\" \") if token != \"\" if token not in STOPWORDS]\n    ngrams = zip(*[token[i:] for i in range(n_gram)])\n    return [\" \".join(ngram) for ngram in ngrams]\n\n# Lấy max_row các từ dạng n_gram xuất hiện nhiều nhất trong dữ liệu\ndef generate_ngrams(df, col, n_gram, max_row):\n    temp_dict = defaultdict(int)\n    for question in df[col]:\n        for word in ngram_extractor(question, n_gram):\n            temp_dict[word] += 1\n    temp_df = pd.DataFrame(sorted(temp_dict.items(), key=lambda x: x[1])[::-1]).head(max_row)\n    temp_df.columns = [\"word\", \"wordcount\"]\n    return temp_df\n\ndef comparison_plot(df_1,df_2,col_1,col_2):\n    fig, ax = plt.subplots(1, 2, figsize=(20,10))\n    \n    sns.barplot(x=col_2, y=col_1, data=df_1, ax=ax[0])\n    sns.barplot(x=col_2, y=col_1, data=df_2, ax=ax[1])\n\n    ax[0].set_xlabel('Word count', size=12)\n    ax[0].set_ylabel('Words', size=12)\n    ax[0].set_title('Top words in sincere questions', size=16)\n\n    ax[1].set_xlabel('Word count', size=12)\n    ax[1].set_ylabel('Words', size=12)\n    ax[1].set_title('Top words in insincere questions', size=16)\n\n    fig.subplots_adjust(wspace=0.25)\n    \n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:17.488966Z","iopub.execute_input":"2022-01-06T16:49:17.489173Z","iopub.status.idle":"2022-01-06T16:49:17.502426Z","shell.execute_reply.started":"2022-01-06T16:49:17.489148Z","shell.execute_reply":"2022-01-06T16:49:17.501452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Lấy ra 20 từ dạng unigram xuất hiện nhiều nhất trong 2 loại tập câu hỏi\nsincere_1gram = generate_ngrams(sincere_data, 'question_text', 1, 20)\ninsincere_1gram = generate_ngrams(insincere_data, 'question_text', 1, 20)\n\ncomparison_plot(sincere_1gram,insincere_1gram,'word','wordcount')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:17.503853Z","iopub.execute_input":"2022-01-06T16:49:17.504185Z","iopub.status.idle":"2022-01-06T16:49:29.905587Z","shell.execute_reply.started":"2022-01-06T16:49:17.504141Z","shell.execute_reply":"2022-01-06T16:49:29.904643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Lấy ra 20 từ dạng bigram xuất hiện nhiều nhất trong 2 loại tập câu hỏi\nsincere_2gram = generate_ngrams(sincere_data, 'question_text', 2, 20)\ninsincere_2gram = generate_ngrams(insincere_data, 'question_text', 2, 20)\n\ncomparison_plot(sincere_1gram,insincere_1gram,'word','wordcount')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:29.907311Z","iopub.execute_input":"2022-01-06T16:49:29.907557Z","iopub.status.idle":"2022-01-06T16:49:49.312971Z","shell.execute_reply.started":"2022-01-06T16:49:29.907528Z","shell.execute_reply":"2022-01-06T16:49:49.312136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Lấy ra 10 từ dạng trigram xuất hiện nhiều nhất trong 2 loại tập câu hỏi\nsincere_3gram = generate_ngrams(sincere_data, 'question_text', 3, 20)\ninsincere_3gram = generate_ngrams(insincere_data, 'question_text', 3, 20)\n\ncomparison_plot(sincere_1gram,insincere_1gram,'word','wordcount')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:49:49.314232Z","iopub.execute_input":"2022-01-06T16:49:49.314465Z","iopub.status.idle":"2022-01-06T16:50:08.299841Z","shell.execute_reply.started":"2022-01-06T16:49:49.314434Z","shell.execute_reply":"2022-01-06T16:50:08.298923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**2.2. Nhận xét dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"**Tập dữ liệu train gồm 1306122 câu hỏi**:\n* 93.8% trong số đó là câu hỏi là Sincere, còn lại là Insincere.\n* Những câu hỏi Insincere đa phần bao gồm các từ như trump, women, white, men, indian, muslims, black, americans, girls, indians, sex and india => nhắm tới nhóm người hay người cụ thể.\n* Top 3 câu hỏi Insincere bigram là \"Donald Trump\", \"White People\", \"Black People\" => các câu hỏi liên quan đến chủng tộc.\n* Các câu hỏi Insincere xoay quanh các tình huống giả định, tuổi tác, chủng tộc, v.v.\n* Các câu hỏi Sincere liên quan đến mẹo, lời khuyên, gợi ý, sự thật, v.v.","metadata":{}},{"cell_type":"markdown","source":"**2.3. Clean dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"**Clean dữ liệu cần:**\n* Unicode: chuyển về dạng unicode.\n* Lowercase: chuyển về chữ in thường.\n* Remove link, punctuation, number: bỏ dấu, chữ số, link\n* Tokenization: phân tách một câu thành các tokens (các từ, cụm từ,... có nghĩa).\n* Stemming hoặc Lemmazation: chuyển đổi, rút gọn các từ về từ gốc (ate, eaten thành eat).\n* Remove stopword: loại bỏ các stopword (a, an, or, of, the, ...).","metadata":{}},{"cell_type":"code","source":"#Sử dụng thư viện nltk(Natural Language Toolkit)\nimport re\nimport nltk\nimport string\nfrom unidecode import unidecode\nfrom nltk.tokenize import word_tokenize\nfrom nltk.corpus import stopwords\nfrom nltk.stem import PorterStemmer, WordNetLemmatizer\nfrom wordcloud import STOPWORDS\n\nmispell_dict = {\"aren't\" : \"are not\",\n\"can't\" : \"cannot\",\n\"couldn't\" : \"could not\",\n\"didn't\" : \"did not\",\n\"doesn't\" : \"does not\",\n\"don't\" : \"do not\",\n\"hadn't\" : \"had not\",\n\"hasn't\" : \"has not\",\n\"haven't\" : \"have not\",\n\"he'd\" : \"he would\",\n\"he'll\" : \"he will\",\n\"he's\" : \"he is\",\n\"i'd\" : \"I would\",\n\"i'd\" : \"I had\",\n\"i'll\" : \"I will\",\n\"i'm\" : \"I am\",\n\"isn't\" : \"is not\",\n\"it's\" : \"it is\",\n\"it'll\":\"it will\",\n\"i've\" : \"I have\",\n\"let's\" : \"let us\",\n\"mightn't\" : \"might not\",\n\"mustn't\" : \"must not\",\n\"shan't\" : \"shall not\",\n\"she'd\" : \"she would\",\n\"she'll\" : \"she will\",\n\"she's\" : \"she is\",\n\"shouldn't\" : \"should not\",\n\"that's\" : \"that is\",\n\"there's\" : \"there is\",\n\"they'd\" : \"they would\",\n\"they'll\" : \"they will\",\n\"they're\" : \"they are\",\n\"they've\" : \"they have\",\n\"we'd\" : \"we would\",\n\"we're\" : \"we are\",\n\"weren't\" : \"were not\",\n\"we've\" : \"we have\",\n\"what'll\" : \"what will\",\n\"what're\" : \"what are\",\n\"what's\" : \"what is\",\n\"what've\" : \"what have\",\n\"where's\" : \"where is\",\n\"who'd\" : \"who would\",\n\"who'll\" : \"who will\",\n\"who're\" : \"who are\",\n\"who's\" : \"who is\",\n\"who've\" : \"who have\",\n\"won't\" : \"will not\",\n\"wouldn't\" : \"would not\",\n\"you'd\" : \"you would\",\n\"you'll\" : \"you will\",\n\"you're\" : \"you are\",\n\"you've\" : \"you have\",\n\"'re\": \" are\",\n\"wasn't\": \"was not\",\n\"we'll\":\" will\",\n\"didn't\": \"did not\"}\n\nstemmer = PorterStemmer()\nlemmatizer = WordNetLemmatizer()\n\ndef clean(text):        \n    # chuyển về dạng unicode \n    text = unidecode(text).encode(\"ascii\")\n    text = str(text, \"ascii\")\n\n    # chuyển về chữ thường, bỏ các link, kí tự đặc biệt, chữ số.\n    text = text.lower()\n    text = re.sub('https?://\\S+|www\\.\\S+', '', text)\n    text = re.sub('<.*?>+', '', text)\n    text = re.sub('[%s]' % re.escape(string.punctuation), '', text)  \n    text = re.sub('\\n', '', text)\n    text = re.sub('[’“”…]', ' ', text)  \n    text = ''.join(i for i in text if not i.isdigit())\n\n    # Chuyển các từ viết tắt trong từ điển về dạng thường\n    tokens = word_tokenize(text)\n    tokens = [mispell_dict.get(token) if (mispell_dict.get(token) != None) else token for token in tokens]\n    text = \" \".join(tokens)\n\n    # Bỏ stop-words   \n    tokens = word_tokenize(text)\n    tokens_without_sw = [word for word in tokens if not word in STOPWORDS]\n\n    # Chuyển biến thể ngữ pháp của từ về từ gốc\n    text = [lemmatizer.lemmatize(word) for word in tokens_without_sw ] \n    text = \" \".join(text)\n\n    return text","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:50:08.301196Z","iopub.execute_input":"2022-01-06T16:50:08.301529Z","iopub.status.idle":"2022-01-06T16:50:08.320242Z","shell.execute_reply.started":"2022-01-06T16:50:08.301493Z","shell.execute_reply":"2022-01-06T16:50:08.319304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Thêm cột clean_questions về các câu hỏi đã clean vào tập train\ntrain_data['clean_questions'] = train_data['question_text'].apply(clean)\ntrain_data","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:50:08.321629Z","iopub.execute_input":"2022-01-06T16:50:08.321991Z","iopub.status.idle":"2022-01-06T16:59:53.551542Z","shell.execute_reply.started":"2022-01-06T16:50:08.321904Z","shell.execute_reply":"2022-01-06T16:59:53.550834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**2.4. Convert dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"Áp dụng CountVectorizre, convert dữ liệu text về dạng vector của số lần xuất hiện của các token. Bag-of-Words là kỹ thuật cốt lõi cho vấn đề này, các phương pháp bao gồm:\n* Tách dữ liệu thành các token\n* Xác định trọng số cho mỗi token ứng với số lần xuất hiện của nó.","metadata":{}},{"cell_type":"code","source":"from sklearn.feature_extraction.text import CountVectorizer\nfrom sklearn.model_selection import train_test_split\n\nX = train_data['clean_questions']\nY = train_data['target']\n\ncount_vectorizer = CountVectorizer(analyzer=\"word\", ngram_range=(1,3))\nX_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2, random_state = 1)\n\ncount_train = count_vectorizer.fit(X)\n\nX_vec_train = count_train.transform(X_train)\nX_vec_test = count_train.transform(X_test)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T16:59:53.552612Z","iopub.execute_input":"2022-01-06T16:59:53.553396Z","iopub.status.idle":"2022-01-06T17:02:05.940830Z","shell.execute_reply.started":"2022-01-06T16:59:53.553347Z","shell.execute_reply":"2022-01-06T17:02:05.939880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **3. Huấn luyện mô hình**","metadata":{}},{"cell_type":"markdown","source":"**Sử dụng mô hình Hồi quy Logistic (Logistic Regression)**: https://excessive-source-1c9.notion.site/18-09-2021-H-i-quy-Logistics-6c3eb44266e549169a0d01cc2d36cfa2\n* Với input tập câu hỏi sau khi clean và convert **X_train_vec $\\in$ $R^d$**, output là nhãn **Y_train $\\in \\{0, 1\\}$**.\n* Mô hình: $Y|X=x \\sim Ber(y|\\sigma(f(x))$ với $f(x) = w^Tx+w_0$\n* Cho $f(x)$ đi qua hàm sigmoid: $\\sigma(z) = \\frac 1 {1+e^{-z}}$\n* Huấn luyện bộ tham số của mô hình $\\theta = (w, w_0)$: Tính Likelihood => Tính hàm lỗi Negative Loglikelihood (NLL) => Xuống đồi bằng đạo hàm cập nhật bộ tham số.","metadata":{}},{"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score, recall_score ,f1_score\nfrom sklearn.metrics import classification_report\n\nmod = LogisticRegression(n_jobs=10, solver='saga',class_weight = 'balanced', C=0.1, verbose=1)\nmod.fit(X_vec_train, Y_train)\nY_pred = mod.predict(X_vec_test)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:02:05.942124Z","iopub.execute_input":"2022-01-06T17:02:05.942357Z","iopub.status.idle":"2022-01-06T17:04:53.685673Z","shell.execute_reply.started":"2022-01-06T17:02:05.942322Z","shell.execute_reply":"2022-01-06T17:04:53.684748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Sự dụng F1-score làm metric**\n* Trung bình điều hòa giữa precision (độ chính xác) và recall (độ bao phủ). $\\frac {2}{F_1} = \\frac {1}{Precision} + \\frac {1}{Recall}$\n* Precision: đánh giá bao nhiêu % kết luận của model là chính xác-True. $Precision = \\frac{TP}{TP+FP}$\n* Recall: đánh giá bao nhiêu % positive samples mà model nhận được. $Recall = \\frac{TP}{TP+FN}$","metadata":{}},{"cell_type":"markdown","source":"![Untitled.png](attachment:27cd0b38-b52e-441c-97a4-9bee98509303.png)\n","metadata":{},"attachments":{"27cd0b38-b52e-441c-97a4-9bee98509303.png":{"image/png":"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"}}},{"cell_type":"code","source":"print('Recall: ', recall_score(Y_pred, Y_test))\nprint('F1 score :', f1_score(Y_pred, Y_test), '\\n')\nprint(classification_report(Y_test, Y_pred))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:04:53.688281Z","iopub.execute_input":"2022-01-06T17:04:53.688538Z","iopub.status.idle":"2022-01-06T17:04:54.205092Z","shell.execute_reply.started":"2022-01-06T17:04:53.688507Z","shell.execute_reply":"2022-01-06T17:04:54.204117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. Submit","metadata":{}},{"cell_type":"code","source":"test_data['clean_questions'] = test_data['question_text'].apply(clean)\nX_test_vec = count_vectorizer.transform(test_data['clean_questions'])\npredictions = mod.predict(X_test_vec)\nsubmission = pd.DataFrame({'qid': test_data['qid'].values})\nsubmission['prediction'] = predictions\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:04:54.206645Z","iopub.execute_input":"2022-01-06T17:04:54.207246Z","iopub.status.idle":"2022-01-06T17:07:55.396978Z","shell.execute_reply.started":"2022-01-06T17:04:54.207197Z","shell.execute_reply":"2022-01-06T17:07:55.395982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:07:55.398594Z","iopub.execute_input":"2022-01-06T17:07:55.398824Z","iopub.status.idle":"2022-01-06T17:07:55.411357Z","shell.execute_reply.started":"2022-01-06T17:07:55.398798Z","shell.execute_reply":"2022-01-06T17:07:55.410523Z"},"trusted":true},"execution_count":null,"outputs":[]}]}