merve HF staff commited on
Commit
6f26afe
1 Parent(s): bfb4bc1

Upload improving-production-workflows-using-skops.ipynb

Browse files
improving-production-workflows-using-skops.ipynb ADDED
@@ -0,0 +1 @@
 
 
1
+ {"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"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-08-12T16:07:49.750037Z","iopub.execute_input":"2022-08-12T16:07:49.750515Z","iopub.status.idle":"2022-08-12T16:07:49.761989Z","shell.execute_reply.started":"2022-08-12T16:07:49.750473Z","shell.execute_reply":"2022-08-12T16:07:49.760803Z"},"trusted":true},"execution_count":34,"outputs":[{"name":"stdout","text":"/kaggle/input/tabular-playground-series-aug-2022/sample_submission.csv\n/kaggle/input/tabular-playground-series-aug-2022/train.csv\n/kaggle/input/tabular-playground-series-aug-2022/test.csv\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Using skops to host your models on Hugging Face Hub\nThis notebook shows you how you can use [skops](https://skops.readthedocs.io/) to improve your data science workflows with scikit-learn. We will have end-to-end example for Kaggle Tabular Playground Series of August 2022.","metadata":{}},{"cell_type":"markdown","source":"## Install skops","metadata":{}},{"cell_type":"code","source":"#!pip install skops","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:42:20.000537Z","iopub.execute_input":"2022-08-12T16:42:20.000960Z","iopub.status.idle":"2022-08-12T16:42:20.005212Z","shell.execute_reply.started":"2022-08-12T16:42:20.000926Z","shell.execute_reply":"2022-08-12T16:42:20.004298Z"},"trusted":true},"execution_count":58,"outputs":[]},{"cell_type":"markdown","source":"## Import libraries","metadata":{}},{"cell_type":"code","source":"import skops\nimport sklearn\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.273144Z","iopub.execute_input":"2022-08-12T16:08:01.273524Z","iopub.status.idle":"2022-08-12T16:08:01.279217Z","shell.execute_reply.started":"2022-08-12T16:08:01.273487Z","shell.execute_reply":"2022-08-12T16:08:01.277670Z"},"trusted":true},"execution_count":36,"outputs":[]},{"cell_type":"markdown","source":"## Let's take a look at the dataset\nTarget variable is a binary category. We have couple of numerical and categorical variables.","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"../input/tabular-playground-series-aug-2022/train.csv\")\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.280555Z","iopub.execute_input":"2022-08-12T16:08:01.280918Z","iopub.status.idle":"2022-08-12T16:08:01.433127Z","shell.execute_reply.started":"2022-08-12T16:08:01.280882Z","shell.execute_reply":"2022-08-12T16:08:01.431902Z"},"trusted":true},"execution_count":37,"outputs":[{"execution_count":37,"output_type":"execute_result","data":{"text/plain":" id product_code loading attribute_0 attribute_1 attribute_2 attribute_3 \\\n0 0 A 80.10 material_7 material_8 9 5 \n1 1 A 84.89 material_7 material_8 9 5 \n2 2 A 82.43 material_7 material_8 9 5 \n3 3 A 101.07 material_7 material_8 9 5 \n4 4 A 188.06 material_7 material_8 9 5 \n\n measurement_0 measurement_1 measurement_2 ... measurement_9 \\\n0 7 8 4 ... 10.672 \n1 14 3 3 ... 12.448 \n2 12 1 5 ... 12.715 \n3 13 2 6 ... 12.471 \n4 9 2 8 ... 10.337 \n\n measurement_10 measurement_11 measurement_12 measurement_13 \\\n0 15.859 17.594 15.193 15.029 \n1 17.947 17.915 11.755 14.732 \n2 15.607 NaN 13.798 16.711 \n3 16.346 18.377 10.020 15.250 \n4 17.082 19.932 12.428 16.182 \n\n measurement_14 measurement_15 measurement_16 measurement_17 failure \n0 NaN 13.034 14.684 764.100 0 \n1 15.425 14.395 15.631 682.057 0 \n2 18.631 14.094 17.946 663.376 0 \n3 15.562 16.154 17.172 826.282 0 \n4 12.760 13.153 16.412 579.885 0 \n\n[5 rows x 26 columns]","text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>id</th>\n <th>product_code</th>\n <th>loading</th>\n <th>attribute_0</th>\n <th>attribute_1</th>\n <th>attribute_2</th>\n <th>attribute_3</th>\n <th>measurement_0</th>\n <th>measurement_1</th>\n <th>measurement_2</th>\n <th>...</th>\n <th>measurement_9</th>\n <th>measurement_10</th>\n <th>measurement_11</th>\n <th>measurement_12</th>\n <th>measurement_13</th>\n <th>measurement_14</th>\n <th>measurement_15</th>\n <th>measurement_16</th>\n <th>measurement_17</th>\n <th>failure</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>A</td>\n <td>80.10</td>\n <td>material_7</td>\n <td>material_8</td>\n <td>9</td>\n <td>5</td>\n <td>7</td>\n <td>8</td>\n <td>4</td>\n <td>...</td>\n <td>10.672</td>\n <td>15.859</td>\n <td>17.594</td>\n <td>15.193</td>\n <td>15.029</td>\n <td>NaN</td>\n <td>13.034</td>\n <td>14.684</td>\n <td>764.100</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>A</td>\n <td>84.89</td>\n <td>material_7</td>\n <td>material_8</td>\n <td>9</td>\n <td>5</td>\n <td>14</td>\n <td>3</td>\n <td>3</td>\n <td>...</td>\n <td>12.448</td>\n <td>17.947</td>\n <td>17.915</td>\n <td>11.755</td>\n <td>14.732</td>\n <td>15.425</td>\n <td>14.395</td>\n <td>15.631</td>\n <td>682.057</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>A</td>\n <td>82.43</td>\n <td>material_7</td>\n <td>material_8</td>\n <td>9</td>\n <td>5</td>\n <td>12</td>\n <td>1</td>\n <td>5</td>\n <td>...</td>\n <td>12.715</td>\n <td>15.607</td>\n <td>NaN</td>\n <td>13.798</td>\n <td>16.711</td>\n <td>18.631</td>\n <td>14.094</td>\n <td>17.946</td>\n <td>663.376</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>A</td>\n <td>101.07</td>\n <td>material_7</td>\n <td>material_8</td>\n <td>9</td>\n <td>5</td>\n <td>13</td>\n <td>2</td>\n <td>6</td>\n <td>...</td>\n <td>12.471</td>\n <td>16.346</td>\n <td>18.377</td>\n <td>10.020</td>\n <td>15.250</td>\n <td>15.562</td>\n <td>16.154</td>\n <td>17.172</td>\n <td>826.282</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>A</td>\n <td>188.06</td>\n <td>material_7</td>\n <td>material_8</td>\n <td>9</td>\n <td>5</td>\n <td>9</td>\n <td>2</td>\n <td>8</td>\n <td>...</td>\n <td>10.337</td>\n <td>17.082</td>\n <td>19.932</td>\n <td>12.428</td>\n <td>16.182</td>\n <td>12.760</td>\n <td>13.153</td>\n <td>16.412</td>\n <td>579.885</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 26 columns</p>\n</div>"},"metadata":{}}]},{"cell_type":"code","source":"df[\"failure\"].unique()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.436722Z","iopub.execute_input":"2022-08-12T16:08:01.437150Z","iopub.status.idle":"2022-08-12T16:08:01.445258Z","shell.execute_reply.started":"2022-08-12T16:08:01.437117Z","shell.execute_reply":"2022-08-12T16:08:01.444066Z"},"trusted":true},"execution_count":38,"outputs":[{"execution_count":38,"output_type":"execute_result","data":{"text/plain":"array([0, 1])"},"metadata":{}}]},{"cell_type":"markdown","source":"# Encode categorical variables, impute missing values\nWe will impute mean for the numerical attribues and measurements. ","metadata":{}},{"cell_type":"code","source":"df.describe()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.447099Z","iopub.execute_input":"2022-08-12T16:08:01.447438Z","iopub.status.idle":"2022-08-12T16:08:01.558557Z","shell.execute_reply.started":"2022-08-12T16:08:01.447409Z","shell.execute_reply":"2022-08-12T16:08:01.557437Z"},"trusted":true},"execution_count":39,"outputs":[{"execution_count":39,"output_type":"execute_result","data":{"text/plain":" id loading attribute_2 attribute_3 measurement_0 \\\ncount 26570.000000 26320.000000 26570.000000 26570.000000 26570.000000 \nmean 13284.500000 127.826233 6.754046 7.240459 7.415883 \nstd 7670.242662 39.030020 1.471852 1.456493 4.116690 \nmin 0.000000 33.160000 5.000000 5.000000 0.000000 \n25% 6642.250000 99.987500 6.000000 6.000000 4.000000 \n50% 13284.500000 122.390000 6.000000 8.000000 7.000000 \n75% 19926.750000 149.152500 8.000000 8.000000 10.000000 \nmax 26569.000000 385.860000 9.000000 9.000000 29.000000 \n\n measurement_1 measurement_2 measurement_3 measurement_4 \\\ncount 26570.000000 26570.000000 26189.000000 26032.000000 \nmean 8.232518 6.256568 17.791528 11.731988 \nstd 4.199401 3.309109 1.001200 0.996085 \nmin 0.000000 0.000000 13.968000 8.008000 \n25% 5.000000 4.000000 17.117000 11.051000 \n50% 8.000000 6.000000 17.787000 11.733000 \n75% 11.000000 8.000000 18.469000 12.410000 \nmax 29.000000 24.000000 21.499000 16.484000 \n\n measurement_5 ... measurement_9 measurement_10 measurement_11 \\\ncount 25894.000000 ... 25343.000000 25270.000000 25102.000000 \nmean 17.127804 ... 11.430725 16.117711 19.172085 \nstd 0.996414 ... 0.999137 1.405978 1.520785 \nmin 12.073000 ... 7.537000 9.323000 12.461000 \n25% 16.443000 ... 10.757000 15.209000 18.170000 \n50% 17.132000 ... 11.430000 16.127000 19.211500 \n75% 17.805000 ... 12.102000 17.025000 20.207000 \nmax 21.425000 ... 15.412000 22.479000 25.640000 \n\n measurement_12 measurement_13 measurement_14 measurement_15 \\\ncount 24969.000000 24796.000000 24696.000000 24561.000000 \nmean 11.702464 15.652904 16.048444 14.995554 \nstd 1.488838 1.155247 1.491923 1.549226 \nmin 5.167000 10.890000 9.140000 9.104000 \n25% 10.703000 14.890000 15.057000 13.957000 \n50% 11.717000 15.628500 16.040000 14.969000 \n75% 12.709000 16.374000 17.082000 16.018000 \nmax 17.663000 22.713000 22.303000 21.626000 \n\n measurement_16 measurement_17 failure \ncount 24460.000000 24286.000000 26570.000000 \nmean 16.460727 701.269059 0.212608 \nstd 1.708935 123.304161 0.409160 \nmin 9.701000 196.787000 0.000000 \n25% 15.268000 618.961500 0.000000 \n50% 16.436000 701.024500 0.000000 \n75% 17.628000 784.090250 0.000000 \nmax 24.094000 1312.794000 1.000000 \n\n[8 rows x 23 columns]","text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>id</th>\n <th>loading</th>\n <th>attribute_2</th>\n <th>attribute_3</th>\n <th>measurement_0</th>\n <th>measurement_1</th>\n <th>measurement_2</th>\n <th>measurement_3</th>\n <th>measurement_4</th>\n <th>measurement_5</th>\n <th>...</th>\n <th>measurement_9</th>\n <th>measurement_10</th>\n <th>measurement_11</th>\n <th>measurement_12</th>\n <th>measurement_13</th>\n <th>measurement_14</th>\n <th>measurement_15</th>\n <th>measurement_16</th>\n <th>measurement_17</th>\n <th>failure</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>count</th>\n <td>26570.000000</td>\n <td>26320.000000</td>\n <td>26570.000000</td>\n <td>26570.000000</td>\n <td>26570.000000</td>\n <td>26570.000000</td>\n <td>26570.000000</td>\n <td>26189.000000</td>\n <td>26032.000000</td>\n <td>25894.000000</td>\n <td>...</td>\n <td>25343.000000</td>\n <td>25270.000000</td>\n <td>25102.000000</td>\n <td>24969.000000</td>\n <td>24796.000000</td>\n <td>24696.000000</td>\n <td>24561.000000</td>\n <td>24460.000000</td>\n <td>24286.000000</td>\n <td>26570.000000</td>\n </tr>\n <tr>\n <th>mean</th>\n <td>13284.500000</td>\n <td>127.826233</td>\n <td>6.754046</td>\n <td>7.240459</td>\n <td>7.415883</td>\n <td>8.232518</td>\n <td>6.256568</td>\n <td>17.791528</td>\n <td>11.731988</td>\n <td>17.127804</td>\n <td>...</td>\n <td>11.430725</td>\n <td>16.117711</td>\n <td>19.172085</td>\n <td>11.702464</td>\n <td>15.652904</td>\n <td>16.048444</td>\n <td>14.995554</td>\n <td>16.460727</td>\n <td>701.269059</td>\n <td>0.212608</td>\n </tr>\n <tr>\n <th>std</th>\n <td>7670.242662</td>\n <td>39.030020</td>\n <td>1.471852</td>\n <td>1.456493</td>\n <td>4.116690</td>\n <td>4.199401</td>\n <td>3.309109</td>\n <td>1.001200</td>\n <td>0.996085</td>\n <td>0.996414</td>\n <td>...</td>\n <td>0.999137</td>\n <td>1.405978</td>\n <td>1.520785</td>\n <td>1.488838</td>\n <td>1.155247</td>\n <td>1.491923</td>\n <td>1.549226</td>\n <td>1.708935</td>\n <td>123.304161</td>\n <td>0.409160</td>\n </tr>\n <tr>\n <th>min</th>\n <td>0.000000</td>\n <td>33.160000</td>\n <td>5.000000</td>\n <td>5.000000</td>\n <td>0.000000</td>\n <td>0.000000</td>\n <td>0.000000</td>\n <td>13.968000</td>\n <td>8.008000</td>\n <td>12.073000</td>\n <td>...</td>\n <td>7.537000</td>\n <td>9.323000</td>\n <td>12.461000</td>\n <td>5.167000</td>\n <td>10.890000</td>\n <td>9.140000</td>\n <td>9.104000</td>\n <td>9.701000</td>\n <td>196.787000</td>\n <td>0.000000</td>\n </tr>\n <tr>\n <th>25%</th>\n <td>6642.250000</td>\n <td>99.987500</td>\n <td>6.000000</td>\n <td>6.000000</td>\n <td>4.000000</td>\n <td>5.000000</td>\n <td>4.000000</td>\n <td>17.117000</td>\n <td>11.051000</td>\n <td>16.443000</td>\n <td>...</td>\n <td>10.757000</td>\n <td>15.209000</td>\n <td>18.170000</td>\n <td>10.703000</td>\n <td>14.890000</td>\n <td>15.057000</td>\n <td>13.957000</td>\n <td>15.268000</td>\n <td>618.961500</td>\n <td>0.000000</td>\n </tr>\n <tr>\n <th>50%</th>\n <td>13284.500000</td>\n <td>122.390000</td>\n <td>6.000000</td>\n <td>8.000000</td>\n <td>7.000000</td>\n <td>8.000000</td>\n <td>6.000000</td>\n <td>17.787000</td>\n <td>11.733000</td>\n <td>17.132000</td>\n <td>...</td>\n <td>11.430000</td>\n <td>16.127000</td>\n <td>19.211500</td>\n <td>11.717000</td>\n <td>15.628500</td>\n <td>16.040000</td>\n <td>14.969000</td>\n <td>16.436000</td>\n <td>701.024500</td>\n <td>0.000000</td>\n </tr>\n <tr>\n <th>75%</th>\n <td>19926.750000</td>\n <td>149.152500</td>\n <td>8.000000</td>\n <td>8.000000</td>\n <td>10.000000</td>\n <td>11.000000</td>\n <td>8.000000</td>\n <td>18.469000</td>\n <td>12.410000</td>\n <td>17.805000</td>\n <td>...</td>\n <td>12.102000</td>\n <td>17.025000</td>\n <td>20.207000</td>\n <td>12.709000</td>\n <td>16.374000</td>\n <td>17.082000</td>\n <td>16.018000</td>\n <td>17.628000</td>\n <td>784.090250</td>\n <td>0.000000</td>\n </tr>\n <tr>\n <th>max</th>\n <td>26569.000000</td>\n <td>385.860000</td>\n <td>9.000000</td>\n <td>9.000000</td>\n <td>29.000000</td>\n <td>29.000000</td>\n <td>24.000000</td>\n <td>21.499000</td>\n <td>16.484000</td>\n <td>21.425000</td>\n <td>...</td>\n <td>15.412000</td>\n <td>22.479000</td>\n <td>25.640000</td>\n <td>17.663000</td>\n <td>22.713000</td>\n <td>22.303000</td>\n <td>21.626000</td>\n <td>24.094000</td>\n <td>1312.794000</td>\n <td>1.000000</td>\n </tr>\n </tbody>\n</table>\n<p>8 rows × 23 columns</p>\n</div>"},"metadata":{}}]},{"cell_type":"markdown","source":"Take a look at the missing values and data types.","metadata":{}},{"cell_type":"code","source":"df.isna().any()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.560497Z","iopub.execute_input":"2022-08-12T16:08:01.560849Z","iopub.status.idle":"2022-08-12T16:08:01.573857Z","shell.execute_reply.started":"2022-08-12T16:08:01.560796Z","shell.execute_reply":"2022-08-12T16:08:01.572810Z"},"trusted":true},"execution_count":40,"outputs":[{"execution_count":40,"output_type":"execute_result","data":{"text/plain":"id False\nproduct_code False\nloading True\nattribute_0 False\nattribute_1 False\nattribute_2 False\nattribute_3 False\nmeasurement_0 False\nmeasurement_1 False\nmeasurement_2 False\nmeasurement_3 True\nmeasurement_4 True\nmeasurement_5 True\nmeasurement_6 True\nmeasurement_7 True\nmeasurement_8 True\nmeasurement_9 True\nmeasurement_10 True\nmeasurement_11 True\nmeasurement_12 True\nmeasurement_13 True\nmeasurement_14 True\nmeasurement_15 True\nmeasurement_16 True\nmeasurement_17 True\nfailure False\ndtype: bool"},"metadata":{}}]},{"cell_type":"code","source":"df.dtypes","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.575878Z","iopub.execute_input":"2022-08-12T16:08:01.576226Z","iopub.status.idle":"2022-08-12T16:08:01.585351Z","shell.execute_reply.started":"2022-08-12T16:08:01.576194Z","shell.execute_reply":"2022-08-12T16:08:01.584190Z"},"trusted":true},"execution_count":41,"outputs":[{"execution_count":41,"output_type":"execute_result","data":{"text/plain":"id int64\nproduct_code object\nloading float64\nattribute_0 object\nattribute_1 object\nattribute_2 int64\nattribute_3 int64\nmeasurement_0 int64\nmeasurement_1 int64\nmeasurement_2 int64\nmeasurement_3 float64\nmeasurement_4 float64\nmeasurement_5 float64\nmeasurement_6 float64\nmeasurement_7 float64\nmeasurement_8 float64\nmeasurement_9 float64\nmeasurement_10 float64\nmeasurement_11 float64\nmeasurement_12 float64\nmeasurement_13 float64\nmeasurement_14 float64\nmeasurement_15 float64\nmeasurement_16 float64\nmeasurement_17 float64\nfailure int64\ndtype: object"},"metadata":{}}]},{"cell_type":"markdown","source":"Let's see the cardinality of categorical variables.","metadata":{}},{"cell_type":"code","source":"print(df.product_code.nunique())\nprint(df.attribute_0.nunique())\nprint(df.attribute_0.nunique())\n","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.586538Z","iopub.execute_input":"2022-08-12T16:08:01.587124Z","iopub.status.idle":"2022-08-12T16:08:01.602366Z","shell.execute_reply.started":"2022-08-12T16:08:01.587085Z","shell.execute_reply":"2022-08-12T16:08:01.601468Z"},"trusted":true},"execution_count":42,"outputs":[{"name":"stdout","text":"5\n2\n2\n","output_type":"stream"}]},{"cell_type":"markdown","source":"# Preprocessing \nWe will use OneHotEncoder to encode our categorical variables, SimpleImputer to impute missing values and put them all in a ColumnTransformer. We will then use the transformer in our machine learning pipeline to have an end-to-end object for better reproducibility.","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import OneHotEncoder\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.compose import ColumnTransformer\n\ncolumn_transformer_pipeline = ColumnTransformer([\n (\"loading_missing_value_imputer\", SimpleImputer(strategy=\"mean\"), [\"loading\"]),\n (\"numerical_missing_value_imputer\", SimpleImputer(strategy=\"mean\"), list(df.columns[df.dtypes == 'float64'])),\n (\"attribute_0_encoder\", OneHotEncoder(categories = \"auto\"), [\"attribute_0\"]),\n (\"attribute_1_encoder\", OneHotEncoder(categories = \"auto\"), [\"attribute_1\"]),\n (\"product_code_encoder\", OneHotEncoder(categories = \"auto\"), [\"product_code\"])])","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.603692Z","iopub.execute_input":"2022-08-12T16:08:01.604304Z","iopub.status.idle":"2022-08-12T16:08:01.612756Z","shell.execute_reply.started":"2022-08-12T16:08:01.604268Z","shell.execute_reply":"2022-08-12T16:08:01.611678Z"},"trusted":true},"execution_count":43,"outputs":[]},{"cell_type":"code","source":"df = df.drop([\"id\"], axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.616244Z","iopub.execute_input":"2022-08-12T16:08:01.616897Z","iopub.status.idle":"2022-08-12T16:08:01.628662Z","shell.execute_reply.started":"2022-08-12T16:08:01.616855Z","shell.execute_reply":"2022-08-12T16:08:01.627386Z"},"trusted":true},"execution_count":44,"outputs":[]},{"cell_type":"code","source":"from sklearn.tree import DecisionTreeClassifier\nfrom sklearn.pipeline import Pipeline\npipeline = Pipeline([\n ('transformation', column_transformer_pipeline),\n ('model', DecisionTreeClassifier(max_depth=4))\n])","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.630096Z","iopub.execute_input":"2022-08-12T16:08:01.631034Z","iopub.status.idle":"2022-08-12T16:08:01.640519Z","shell.execute_reply.started":"2022-08-12T16:08:01.630995Z","shell.execute_reply":"2022-08-12T16:08:01.639257Z"},"trusted":true},"execution_count":45,"outputs":[]},{"cell_type":"code","source":"X = df.drop([\"failure\"], axis = 1)\ny = df.failure","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.642270Z","iopub.execute_input":"2022-08-12T16:08:01.643448Z","iopub.status.idle":"2022-08-12T16:08:01.656699Z","shell.execute_reply.started":"2022-08-12T16:08:01.643404Z","shell.execute_reply":"2022-08-12T16:08:01.655346Z"},"trusted":true},"execution_count":46,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.658597Z","iopub.execute_input":"2022-08-12T16:08:01.659907Z","iopub.status.idle":"2022-08-12T16:08:01.680523Z","shell.execute_reply.started":"2022-08-12T16:08:01.659853Z","shell.execute_reply":"2022-08-12T16:08:01.679150Z"},"trusted":true},"execution_count":47,"outputs":[]},{"cell_type":"code","source":"pipeline.fit(X_train, y_train)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.682078Z","iopub.execute_input":"2022-08-12T16:08:01.682574Z","iopub.status.idle":"2022-08-12T16:08:01.927531Z","shell.execute_reply.started":"2022-08-12T16:08:01.682526Z","shell.execute_reply":"2022-08-12T16:08:01.926319Z"},"trusted":true},"execution_count":48,"outputs":[{"execution_count":48,"output_type":"execute_result","data":{"text/plain":"Pipeline(steps=[('transformation',\n ColumnTransformer(transformers=[('loading_missing_value_imputer',\n SimpleImputer(),\n ['loading']),\n ('numerical_missing_value_imputer',\n SimpleImputer(),\n ['loading', 'measurement_3',\n 'measurement_4',\n 'measurement_5',\n 'measurement_6',\n 'measurement_7',\n 'measurement_8',\n 'measurement_9',\n 'measurement_10',\n 'measurement_11',\n 'measurement_12',\n 'measurement_13',\n 'measurement_14',\n 'measurement_15',\n 'measurement_16',\n 'measurement_17']),\n ('attribute_0_encoder',\n OneHotEncoder(),\n ['attribute_0']),\n ('attribute_1_encoder',\n OneHotEncoder(),\n ['attribute_1']),\n ('product_code_encoder',\n OneHotEncoder(),\n ['product_code'])])),\n ('model', DecisionTreeClassifier(max_depth=4))])"},"metadata":{}}]},{"cell_type":"code","source":"y_pred = pipeline.predict(X_test)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.929273Z","iopub.execute_input":"2022-08-12T16:08:01.929842Z","iopub.status.idle":"2022-08-12T16:08:01.956267Z","shell.execute_reply.started":"2022-08-12T16:08:01.929778Z","shell.execute_reply":"2022-08-12T16:08:01.955125Z"},"trusted":true},"execution_count":49,"outputs":[]},{"cell_type":"markdown","source":"# We will now save the model and create a model card with metrics about our model!","metadata":{}},{"cell_type":"markdown","source":"We will use `hub_utils` for model hosting and `card` to create a model card. First, we will initialize a local repository to contain our model, model configuration, model card and anything else that we want. (e.g. plots)","metadata":{}},{"cell_type":"code","source":"from skops import card, hub_utils\nimport pickle\n\nmodel_path = \"model.pkl\"\nlocal_repo = \"decision-tree-playground-kaggle\"\n\nwith open(model_path, mode=\"bw\") as f:\n pickle.dump(pipeline, file=f)\n\nhub_utils.init(\nmodel=model_path, \nrequirements=[f\"scikit-learn={sklearn.__version__}\"], \ndst=local_repo,\ntask=\"tabular-classification\",\ndata=X_test,\n)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.957800Z","iopub.execute_input":"2022-08-12T16:08:01.958544Z","iopub.status.idle":"2022-08-12T16:08:01.971908Z","shell.execute_reply.started":"2022-08-12T16:08:01.958496Z","shell.execute_reply":"2022-08-12T16:08:01.970902Z"},"trusted":true},"execution_count":50,"outputs":[]},{"cell_type":"markdown","source":"## We will now create our card 🃏 ","metadata":{}},{"cell_type":"markdown","source":"Creating the model card is as simple as instantiating `Card` class of `skops`. Calling `metadata_from_config` method will create metadata section of the model card from configuration file. We will use `add` method to pass information to our model card.","metadata":{}},{"cell_type":"code","source":"from pathlib import Path\nmodel_card = card.Card(pipeline, metadata=card.metadata_from_config(Path(local_repo)))\n\n## let's fill some information about the model\nlimitations = \"This model is not ready to be used in production.\"\nmodel_description = \"This is a DecisionTreeClassifier model built for Kaggle Tabular Playground Series August 2022, trained on supersoaker production failures dataset.\"\nmodel_card_authors = \"huggingface\"\nget_started_code = f\"import pickle \\nwith open({local_repo}/{model_path}, 'rb') as file: \\n clf = pickle.load(file)\"\n\n# pass this information to the card\nmodel_card.add(\n get_started_code=get_started_code,\n model_card_authors=model_card_authors,\n limitations=limitations,\n model_description=model_description,\n)\n# adding methods return the model card itself for easy method chaining","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:01.973796Z","iopub.execute_input":"2022-08-12T16:08:01.974696Z","iopub.status.idle":"2022-08-12T16:08:02.071532Z","shell.execute_reply.started":"2022-08-12T16:08:01.974655Z","shell.execute_reply":"2022-08-12T16:08:02.070310Z"},"trusted":true},"execution_count":51,"outputs":[{"execution_count":51,"output_type":"execute_result","data":{"text/plain":"Card(\n model=Pipeline(steps=[('transformat...cisionTreeClassifier(max_depth=4))]),\n metadata.library_name=sklearn,\n metadata.tags=['sklearn', 'skops', 'tabular-classification'],\n metadata.widget={...},\n get_started_code=\"import pickle \\\\n...s file: \\\\n clf = pickle.load(file)\",\n model_card_authors='huggingface',\n limitations='This model is not ready to be used in production.',\n model_description='This is a Decisi...soaker production failures dataset.',\n)"},"metadata":{}}]},{"cell_type":"markdown","source":"We will now plot and create insights about our model and write them to the model card. \nPipeline includes the decision tree in the last step of it, you can see the content of pipeline as a tuple. The second element of the tuple includes the object -the tree model- itself so if we want to plot the tree we have to first get it from the pipeline. (see below)","metadata":{}},{"cell_type":"code","source":"pipeline.steps[-1][1]","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:02.073020Z","iopub.execute_input":"2022-08-12T16:08:02.073400Z","iopub.status.idle":"2022-08-12T16:08:02.082681Z","shell.execute_reply.started":"2022-08-12T16:08:02.073367Z","shell.execute_reply":"2022-08-12T16:08:02.080924Z"},"trusted":true},"execution_count":52,"outputs":[{"execution_count":52,"output_type":"execute_result","data":{"text/plain":"DecisionTreeClassifier(max_depth=4)"},"metadata":{}}]},{"cell_type":"markdown","source":"We can use `add_metrics` to pass metrics to our model card, which skops will parse into a table for us. We will use `add_plots` to add our plots. ","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score, f1_score, ConfusionMatrixDisplay, confusion_matrix\nmodel_card.add(eval_method=\"The model is evaluated using test split, on accuracy and F1 score with micro average.\")\nmodel_card.add_metrics(accuracy=accuracy_score(y_test, y_pred))\nmodel_card.add_metrics(**{\"f1 score\": f1_score(y_test, y_pred, average=\"micro\")})\n\nmodel = pipeline.steps[-1][1]\n# we will plot the tree and add the plot to our card\nfrom sklearn.tree import plot_tree\nplt.figure()\nplot_tree(model,filled=True) \nplt.savefig(f'{local_repo}/tree.png',format='png',bbox_inches = \"tight\")\n\n# let's make a prediction and evaluate the model\n\ny_pred = pipeline.predict(X_test)\ncm = confusion_matrix(y_test, y_pred, labels=model.classes_)\ndisp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=model.classes_)\ndisp.plot()\n# save the plot\nplt.savefig(Path(local_repo) / \"confusion_matrix.png\")\n# add figures to model card with their new sections as keys to the dictionary\nmodel_card.add_plot(**{\"Tree Plot\": f'{local_repo}/tree.png', \"Confusion Matrix\": f\"{local_repo}/confusion_matrix.png\"})","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:02.084852Z","iopub.execute_input":"2022-08-12T16:08:02.085287Z","iopub.status.idle":"2022-08-12T16:08:05.482006Z","shell.execute_reply.started":"2022-08-12T16:08:02.085232Z","shell.execute_reply":"2022-08-12T16:08:05.480747Z"},"trusted":true},"execution_count":53,"outputs":[{"execution_count":53,"output_type":"execute_result","data":{"text/plain":"Card(\n model=Pipeline(steps=[('transformat...cisionTreeClassifier(max_depth=4))]),\n metadata.library_name=sklearn,\n metadata.tags=['sklearn', 'skops', 'tabular-classification'],\n metadata.widget={...},\n get_started_code=\"import pickle \\\\n...s file: \\\\n clf = pickle.load(file)\",\n model_card_authors='huggingface',\n limitations='This model is not ready to be used in production.',\n model_description='This is a Decisi...soaker production failures dataset.',\n eval_method='The model is evaluated...cy and F1 score with micro average.',\n Tree Plot='decision-tree-playground-kaggle/tree.png',\n Confusion Matrix='decision-tree-playground-kaggle/confusion_matrix.png',\n)"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 1 Axes>","image/png":"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\n"},"metadata":{"needs_background":"light"}},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 2 Axes>","image/png":"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\n"},"metadata":{"needs_background":"light"}}]},{"cell_type":"markdown","source":"We will now save our model card.","metadata":{}},{"cell_type":"code","source":"model_card.save(f\"{local_repo}/README.md\")","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:05.483575Z","iopub.execute_input":"2022-08-12T16:08:05.484066Z","iopub.status.idle":"2022-08-12T16:08:05.518708Z","shell.execute_reply.started":"2022-08-12T16:08:05.484021Z","shell.execute_reply":"2022-08-12T16:08:05.517522Z"},"trusted":true},"execution_count":54,"outputs":[]},{"cell_type":"markdown","source":"Let's push our model repository to Hub! \nHugging Face Hub requires us to authenticate ourselves, we can do that using `notebook_login`\n","metadata":{}},{"cell_type":"code","source":"from huggingface_hub import notebook_login\nnotebook_login()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:04:27.699235Z","iopub.execute_input":"2022-08-12T16:04:27.699722Z","iopub.status.idle":"2022-08-12T16:04:27.744734Z","shell.execute_reply.started":"2022-08-12T16:04:27.699676Z","shell.execute_reply":"2022-08-12T16:04:27.743310Z"},"trusted":true},"execution_count":27,"outputs":[{"output_type":"display_data","data":{"text/plain":"VBox(children=(HTML(value='<center> <img\\nsrc=https://huggingface.co/front/assets/huggingface_logo-noborder.sv…","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"c262065390b9467180ad8645dedb582f"}},"metadata":{}}]},{"cell_type":"markdown","source":"We can push our model using `hub_utils.push`","metadata":{}},{"cell_type":"code","source":"# if the repository doesn't exist remotely on the Hugging Face Hub, it will be created when we set create_remote to True\nrepo_id = \"scikit-learn/tabular-playground\"\nhub_utils.push(\n repo_id=repo_id,\n source=local_repo,\n token=token,\n commit_message=\"pushing files to the repo from the example!\",\n create_remote=True,\n)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-12T16:08:15.078202Z","iopub.execute_input":"2022-08-12T16:08:15.078653Z","iopub.status.idle":"2022-08-12T16:08:18.508240Z","shell.execute_reply.started":"2022-08-12T16:08:15.078614Z","shell.execute_reply":"2022-08-12T16:08:18.506828Z"},"trusted":true},"execution_count":55,"outputs":[]},{"cell_type":"markdown","source":"## After we push it, the widget is enabled like below:","metadata":{}},{"cell_type":"markdown","source":"![Widget](https://huggingface.co/scikit-learn/tabular-playground/resolve/main/widget_screenshot.png)","metadata":{}},{"cell_type":"markdown","source":"# See how repository and our model card looks like [here](https://huggingface.co/scikit-learn/tabular-playground) ✨","metadata":{}}]}