dsnn/Assessment_S3
0
1{2 "cells": [3 {4 "cell_type": "markdown",5 "metadata": {6 "id": "PK-UE7d9aiQp"7 },8 "source": [9 "# **Telco Customer Churn** ( CRISP-DM Chapter 1)"10 ]11 },12 {13 "cell_type": "code",14 "execution_count": 2,15 "metadata": {16 "ExecuteTime": {17 "end_time": "2024-09-25T07:58:59.872738Z",18 "start_time": "2024-09-25T07:58:39.420662Z"19 }20 },21 "outputs": [],22 "source": [23 "import pandas as pd \n",24 "import numpy as np \n",25 "import matplotlib.pyplot as plt\n",26 "from sklearn.preprocessing import OneHotEncoder, MinMaxScaler, LabelEncoder\n",27 "from sklearn.linear_model import LogisticRegression\n",28 "from sklearn.model_selection import train_test_split\n",29 "from sklearn.metrics import ( accuracy_score,confusion_matrix,ConfusionMatrixDisplay)"30 ]31 },32 {33 "cell_type": "code",34 "execution_count": 3,35 "metadata": {36 "ExecuteTime": {37 "end_time": "2024-09-25T07:59:00.050813Z",38 "start_time": "2024-09-25T07:58:59.872738Z"39 },40 "id": "45DNTiSAqqbG"41 },42 "outputs": [],43 "source": [44 "df = pd.read_csv(\"D:\\p3\\Deifallah_Training\\WA_Fn-UseC_-Telco-Customer-Churn.csv\") # Path to the CSV file"45 ]46 },47 {48 "cell_type": "code",49 "execution_count": 4,50 "metadata": {51 "ExecuteTime": {52 "end_time": "2024-09-25T07:59:00.065496Z",53 "start_time": "2024-09-25T07:59:00.050813Z"54 },55 "id": "U30UqclEq8AV"56 },57 "outputs": [],58 "source": [59 "import joblib\n",60 "\n",61 "# Columns for different preprocessing steps\n",62 "label_encode_cols = [\"Partner\", \"Dependents\", \"PhoneService\", \"PaperlessBilling\",'gender']\n",63 "one_hot_encode_cols = [\"MultipleLines\", \"InternetService\", \"OnlineSecurity\", \"OnlineBackup\",\n",64 " \"DeviceProtection\", \"TechSupport\", \"StreamingTV\", \"StreamingMovies\",\n",65 " \"Contract\", \"PaymentMethod\"]\n",66 "min_max_scale_cols = [\"tenure\", \"MonthlyCharges\", \"TotalCharges\"]"67 ]68 },69 {70 "cell_type": "code",71 "execution_count": 5,72 "metadata": {73 "ExecuteTime": {74 "end_time": "2024-09-25T07:59:00.216007Z",75 "start_time": "2024-09-25T07:59:00.066662Z"76 },77 "id": "7SPWJ6GKrOqY"78 },79 "outputs": [],80 "source": [81 "# Separate Features and Target\n",82 "# Drop 'customerID' and 'Churn' from the features, keeping 'Churn' as the target\n",83 "X = df.drop(columns=['customerID', 'Churn'])\n",84 "y = df['Churn']"85 ]86 },87 {88 "cell_type": "code",89 "execution_count": 6,90 "metadata": {91 "ExecuteTime": {92 "end_time": "2024-09-25T07:59:00.234131Z",93 "start_time": "2024-09-25T07:59:00.220934Z"94 },95 "colab": {96 "base_uri": "https://localhost:8080/"97 },98 "id": "LIvqF6zHrQ30",99 "outputId": "34013dde-2933-4bbb-850f-7ef9567c6746"100 },101 "outputs": [102 {103 "name": "stdout",104 "output_type": "stream",105 "text": [106 "Unique values in 'Churn' before encoding: ['No' 'Yes']\n"107 ]108 }109 ],110 "source": [111 "# Debug: Print unique values of target variable before encoding\n",112 "print(\"Unique values in 'Churn' before encoding:\", y.unique())"113 ]114 },115 {116 "cell_type": "code",117 "execution_count": 7,118 "metadata": {119 "ExecuteTime": {120 "end_time": "2024-09-25T07:59:00.246754Z",121 "start_time": "2024-09-25T07:59:00.238342Z"122 },123 "id": "7jeMpnz2rT28"124 },125 "outputs": [],126 "source": [127 "# Encode the Target Variable\n",128 "# Initialize the LabelEncoder\n",129 "le_target = LabelEncoder()\n",130 "\n",131 "# Fit and transform the target variable 'Churn' to numerical values\n",132 "y = le_target.fit_transform(y)"133 ]134 },135 {136 "cell_type": "code",137 "execution_count": 8,138 "metadata": {139 "ExecuteTime": {140 "end_time": "2024-09-25T07:59:00.261495Z",141 "start_time": "2024-09-25T07:59:00.248767Z"142 },143 "colab": {144 "base_uri": "https://localhost:8080/"145 },146 "id": "dh8FCbq_rV-1",147 "outputId": "7a3f7c63-237e-4554-80f6-357930290038"148 },149 "outputs": [150 {151 "name": "stdout",152 "output_type": "stream",153 "text": [154 "Unique values in 'Churn' after encoding: [0 0 1 ... 0 1 0]\n"155 ]156 }157 ],158 "source": [159 "# Debug: Print unique values of target variable after encoding\n",160 "print(\"Unique values in 'Churn' after encoding:\", y)"161 ]162 },163 {164 "cell_type": "markdown",165 "metadata": {166 "id": "DX1kDE5MlO_V"167 },168 "source": [169 "**Label Encoder for the Target Variable**"170 ]171 },172 {173 "cell_type": "code",174 "execution_count": 9,175 "metadata": {176 "ExecuteTime": {177 "end_time": "2024-09-25T07:59:00.275888Z",178 "start_time": "2024-09-25T07:59:00.266417Z"179 },180 "colab": {181 "base_uri": "https://localhost:8080/"182 },183 "id": "cak1q_TXlO6t",184 "outputId": "ca7a48fa-110c-47a3-9c66-9e6f5fe7a195"185 },186 "outputs": [187 {188 "name": "stdout",189 "output_type": "stream",190 "text": [191 "Label encoder for target saved.\n"192 ]193 }194 ],195 "source": [196 "# Save the LabelEncoder for target variable\n",197 "joblib.dump(le_target, 'label_encoder_target.pkl')\n",198 "print(\"Label encoder for target saved.\")"199 ]200 },201 {202 "cell_type": "markdown",203 "metadata": {204 "id": "Csdc_300smlH"205 },206 "source": [207 "**Handle Missing Values and Convert Data Types**"208 ]209 },210 {211 "cell_type": "code",212 "execution_count": 13,213 "metadata": {214 "ExecuteTime": {215 "end_time": "2024-09-25T07:59:45.397386Z",216 "start_time": "2024-09-25T07:59:45.370778Z"217 },218 "id": "USHIBBhOskhe"219 },220 "outputs": [],221 "source": [222 "# Replace non-numeric values with NaN and fill with the mean of the column\n",223 "X[min_max_scale_cols] = X[min_max_scale_cols].replace(' ', np.nan).astype(float)\n",224 "X[min_max_scale_cols] = X[min_max_scale_cols].fillna(X[min_max_scale_cols].mean())"225 ]226 },227 {228 "cell_type": "markdown",229 "metadata": {230 "id": "xz7XqOrclBxa"231 },232 "source": [233 "**Saving MinMax Scaler**"234 ]235 },236 {237 "cell_type": "code",238 "execution_count": 28,239 "metadata": {240 "ExecuteTime": {241 "end_time": "2024-09-25T06:48:44.847214Z",242 "start_time": "2024-09-25T06:48:44.839874Z"243 },244 "id": "0tKDcyW2sdPn"245 },246 "outputs": [],247 "source": [248 "# **Min-Max Scale Specified Columns**\n",249 "min_max_scaler = MinMaxScaler()\n",250 "scaled_numerical = min_max_scaler.fit_transform(X[min_max_scale_cols])"251 ]252 },253 {254 "cell_type": "code",255 "execution_count": 29,256 "metadata": {257 "ExecuteTime": {258 "end_time": "2024-09-25T06:48:45.346721Z",259 "start_time": "2024-09-25T06:48:45.341629Z"260 },261 "colab": {262 "base_uri": "https://localhost:8080/"263 },264 "id": "baIg8TAmxB-d",265 "outputId": "d73591d4-ee50-4e06-870d-b5ab696b1c58"266 },267 "outputs": [268 {269 "name": "stdout",270 "output_type": "stream",271 "text": [272 "Min-max scaler saved.\n"273 ]274 }275 ],276 "source": [277 "# Save the min-max scaler to a file\n",278 "joblib.dump(min_max_scaler, 'min_max_scaler.pkl')\n",279 "print(\"Min-max scaler saved.\")"280 ]281 },282 {283 "cell_type": "markdown",284 "metadata": {285 "id": "ByHKE8kGk8A_"286 },287 "source": [288 "**Saving Label Encoders**"289 ]290 },291 {292 "cell_type": "code",293 "execution_count": 30,294 "metadata": {295 "ExecuteTime": {296 "end_time": "2024-09-25T06:48:46.155089Z",297 "start_time": "2024-09-25T06:48:46.143342Z"298 },299 "id": "q3XjCdb3qyZx"300 },301 "outputs": [],302 "source": [303 "# **Label Encode Specified Columns**\n",304 "label_encoders = {}\n",305 "for col in label_encode_cols:\n",306 " le = LabelEncoder()\n",307 " X[col] = le.fit_transform(X[col])\n",308 " label_encoders[col] = le"309 ]310 },311 {312 "cell_type": "code",313 "execution_count": 31,314 "metadata": {315 "ExecuteTime": {316 "end_time": "2024-09-25T06:48:46.617413Z",317 "start_time": "2024-09-25T06:48:46.612413Z"318 },319 "colab": {320 "base_uri": "https://localhost:8080/"321 },322 "id": "jbKiQRKksszV",323 "outputId": "2c18fcf6-79cb-4d5b-948e-5b3a6e44767b"324 },325 "outputs": [326 {327 "name": "stdout",328 "output_type": "stream",329 "text": [330 "Label encoders saved.\n"331 ]332 }333 ],334 "source": [335 "joblib.dump(label_encoders, 'label_encoders.pkl')\n",336 "print(\"Label encoders saved.\")"337 ]338 },339 {340 "cell_type": "markdown",341 "metadata": {342 "id": "kITWxNUok_tI"343 },344 "source": [345 "**Saving One-Hot Encoder**"346 ]347 },348 {349 "cell_type": "code",350 "execution_count": 32,351 "metadata": {352 "ExecuteTime": {353 "end_time": "2024-09-25T06:48:47.599921Z",354 "start_time": "2024-09-25T06:48:47.581012Z"355 },356 "colab": {357 "base_uri": "https://localhost:8080/"358 },359 "id": "Xu6uVwIfsdDq",360 "outputId": "454f1086-d1c5-4922-832a-2e5ddce9d4d1"361 },362 "outputs": [363 {364 "name": "stderr",365 "output_type": "stream",366 "text": [367 "D:\\Programs\\Anaconda\\Lib\\site-packages\\sklearn\\preprocessing\\_encoders.py:868: FutureWarning: `sparse` was renamed to `sparse_output` in version 1.2 and will be removed in 1.4. `sparse_output` is ignored unless you leave `sparse` to its default value.\n",368 " warnings.warn(\n"369 ]370 }371 ],372 "source": [373 "# **One-Hot Encode Specified Columns**\n",374 "one_hot_encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')\n",375 "one_hot_encoded = one_hot_encoder.fit_transform(X[one_hot_encode_cols])"376 ]377 },378 {379 "cell_type": "code",380 "execution_count": 33,381 "metadata": {382 "ExecuteTime": {383 "end_time": "2024-09-25T06:48:48.209920Z",384 "start_time": "2024-09-25T06:48:48.203709Z"385 },386 "colab": {387 "base_uri": "https://localhost:8080/"388 },389 "id": "-KUZ1O_4suvp",390 "outputId": "0aa8bc0e-9094-4968-f8de-bd0bc5c343e1"391 },392 "outputs": [393 {394 "name": "stdout",395 "output_type": "stream",396 "text": [397 "One-hot encoder saved.\n"398 ]399 }400 ],401 "source": [402 "# Save the one-hot encoder\n",403 "joblib.dump(one_hot_encoder, 'one_hot_encoder.pkl')\n",404 "print(\"One-hot encoder saved.\")"405 ]406 },407 {408 "cell_type": "markdown",409 "metadata": {410 "id": "8F7OQIAAsznK"411 },412 "source": [413 "**Combine Processed Columns**"414 ]415 },416 {417 "cell_type": "code",418 "execution_count": 34,419 "metadata": {420 "ExecuteTime": {421 "end_time": "2024-09-25T06:48:49.192927Z",422 "start_time": "2024-09-25T06:48:49.187519Z"423 },424 "id": "v3muz1l8s0Tt"425 },426 "outputs": [],427 "source": [428 "# Combine label encoded columns, scaled numerical columns, and one-hot encoded columns\n",429 "X_processed = np.hstack((X[label_encode_cols].values, scaled_numerical, one_hot_encoded))"430 ]431 },432 {433 "cell_type": "code",434 "execution_count": 35,435 "metadata": {436 "ExecuteTime": {437 "end_time": "2024-09-25T06:48:49.792738Z",438 "start_time": "2024-09-25T06:48:49.787178Z"439 },440 "colab": {441 "base_uri": "https://localhost:8080/"442 },443 "id": "0HcuGoCwiSnn",444 "outputId": "ca8fc2dc-a4ce-4cd2-dded-e5c2f7ce37e1",445 "scrolled": true446 },447 "outputs": [448 {449 "data": {450 "text/plain": [451 "array([[1., 0., 0., ..., 0., 1., 0.],\n",452 " [0., 0., 1., ..., 0., 0., 1.],\n",453 " [0., 0., 1., ..., 0., 0., 1.],\n",454 " ...,\n",455 " [1., 1., 0., ..., 0., 1., 0.],\n",456 " [1., 0., 1., ..., 0., 0., 1.],\n",457 " [0., 0., 1., ..., 0., 0., 0.]])"458 ]459 },460 "execution_count": 35,461 "metadata": {},462 "output_type": "execute_result"463 }464 ],465 "source": [466 "X_processed"467 ]468 },469 {470 "cell_type": "code",471 "execution_count": 36,472 "metadata": {473 "ExecuteTime": {474 "end_time": "2024-09-25T06:48:50.373368Z",475 "start_time": "2024-09-25T06:48:50.327521Z"476 },477 "id": "ThoZjINIs4vL"478 },479 "outputs": [],480 "source": [481 "# **Split Data into Training and Testing Sets**\n",482 "X_train, X_test, y_train, y_test = train_test_split(X_processed, y, test_size=0.2, random_state=42)"483 ]484 },485 {486 "cell_type": "markdown",487 "metadata": {488 "id": "H5ndA24FlHoF"489 },490 "source": [491 "**Saving the Trained Logistic Regression Model**\n"492 ]493 },494 {495 "cell_type": "code",496 "execution_count": 37,497 "metadata": {498 "ExecuteTime": {499 "end_time": "2024-09-25T06:48:57.210633Z",500 "start_time": "2024-09-25T06:48:56.846578Z"501 },502 "colab": {503 "base_uri": "https://localhost:8080/",504 "height": 74505 },506 "id": "Djk2YRSvsdee",507 "outputId": "0f76c552-d400-4bf7-ee1e-4b6a2c462d3f"508 },509 "outputs": [510 {511 "data": {512 "text/html": [513 "<style>#sk-container-id-1 {color: black;background-color: white;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LogisticRegression(max_iter=1000, random_state=42)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">LogisticRegression</label><div class=\"sk-toggleable__content\"><pre>LogisticRegression(max_iter=1000, random_state=42)</pre></div></div></div></div></div>"514 ],515 "text/plain": [516 "LogisticRegression(max_iter=1000, random_state=42)"517 ]518 },519 "execution_count": 37,520 "metadata": {},521 "output_type": "execute_result"522 }523 ],524 "source": [525 "# **Train the Model**\n",526 "model = LogisticRegression(max_iter=1000, random_state=42)\n",527 "model.fit(X_train, y_train)"528 ]529 },530 {531 "cell_type": "code",532 "execution_count": 38,533 "metadata": {534 "ExecuteTime": {535 "end_time": "2024-09-25T06:48:58.973360Z",536 "start_time": "2024-09-25T06:48:58.969170Z"537 }538 },539 "outputs": [],540 "source": [541 "y_pred_log = model.predict(X_test)"542 ]543 },544 {545 "cell_type": "code",546 "execution_count": 41,547 "metadata": {548 "ExecuteTime": {549 "end_time": "2024-09-25T06:49:33.209783Z",550 "start_time": "2024-09-25T06:49:32.054444Z"551 }552 },553 "outputs": [554 {555 "data": {556 "text/plain": [557 "<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x1f3201ff890>"558 ]559 },560 "execution_count": 41,561 "metadata": {},562 "output_type": "execute_result"563 },564 {565 "data": {566 "image/png": "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",567 "text/plain": [568 "<Figure size 640x480 with 2 Axes>"569 ]570 },571 "metadata": {},572 "output_type": "display_data"573 }574 ],575 "source": [576 "cf_matrix=confusion_matrix(y_test,y_pred=y_pred_log)\n",577 "display=ConfusionMatrixDisplay(cf_matrix, display_labels=model.classes_)\n",578 "display.plot()"579 ]580 },581 {582 "cell_type": "code",583 "execution_count": 42,584 "metadata": {585 "ExecuteTime": {586 "end_time": "2024-09-25T06:49:35.336682Z",587 "start_time": "2024-09-25T06:49:35.331053Z"588 },589 "colab": {590 "base_uri": "https://localhost:8080/"591 },592 "id": "QPG73cxOtA7q",593 "outputId": "de2ff6db-e1ef-4894-f722-58c9c21f321b"594 },595 "outputs": [596 {597 "name": "stdout",598 "output_type": "stream",599 "text": [600 "model saved as logistic_regression_model.pkl.\n"601 ]602 }603 ],604 "source": [605 "# Save the trained model\n",606 "model_file = 'logistic_regression_model.pkl'\n",607 "joblib.dump(model, model_file)\n",608 "print(f\"model saved as {model_file}.\")"609 ]610 },611 {612 "cell_type": "markdown",613 "metadata": {614 "id": "4Q--4FFDvEB_"615 },616 "source": [617 "\n",618 "###**requirements.txt**\n",619 "\n",620 "\n",621 "\n"622 ]623 },624 {625 "cell_type": "markdown",626 "metadata": {627 "id": "xm7lxCJFwgAS"628 },629 "source": [630 "* pandas\n",631 "* numpy==1.21.5\n",632 "* scikit-learn==1.2.2\n",633 "* gradio\n",634 "* joblib"635 ]636 }637 ],638 "metadata": {639 "colab": {640 "collapsed_sections": [641 "X3f_6RRVitXl",642 "JLUWkWPdbToK",643 "zILILs5Ad8EL",644 "FGvQiyeDeH7e",645 "ojXJC5VSjLi5",646 "4Q--4FFDvEB_"647 ],648 "provenance": []649 },650 "hide_input": false,651 "kernelspec": {652 "display_name": "Python 3 (ipykernel)",653 "language": "python",654 "name": "python3"655 },656 "language_info": {657 "codemirror_mode": {658 "name": "ipython",659 "version": 3660 },661 "file_extension": ".py",662 "mimetype": "text/x-python",663 "name": "python",664 "nbconvert_exporter": "python",665 "pygments_lexer": "ipython3",666 "version": "3.11.7"667 }668 },669 "nbformat": 4,670 "nbformat_minor": 1671}672 