{ "cells": [ { "cell_type": "markdown", "id": "8275cfcb", "metadata": {}, "source": [ "# Persisting trained models and scalers" ] }, { "cell_type": "markdown", "id": "7e4422a4", "metadata": {}, "source": [ "## 1. Abstract" ] }, { "cell_type": "markdown", "id": "97a6e0e1", "metadata": {}, "source": [ "The normal work of data analysts generally consists of analyzing them using statistical and machine learning techniques and their subsequent presentation in a report.
\n", "This is different when the data model is to be used by an application at runtime. In these cases, training a model and using it to predict each instance is often very inefficient. It would be more convenient to train the model, store it, and have it available to be used later by the program or by the part of the program that needs it.
\n", "Python pickles can be used for this: the model (and the scalers obtained after training) can be stored for later use in order to avoid training the same model for each prediction need." ] }, { "cell_type": "code", "execution_count": 1, "id": "0cb47789", "metadata": {}, "outputs": [], "source": [ "import os\n", "import random\n", "import pickle\n", "import pandas as pd\n", "import numpy as np\n", "import sklearn\n", "from sklearn import datasets\n", "from sklearn import model_selection\n", "from sklearn import preprocessing\n", "from sklearn.metrics import classification_report\n", "from sklearn.preprocessing import StandardScaler\n", "#\n", "separador=os.sep" ] }, { "cell_type": "markdown", "id": "6b9e9d26", "metadata": {}, "source": [ "## 2. Basic use of Pickle" ] }, { "attachments": { "imagen.png": { "image/png": "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7du3c84551TO7zgO6XSa0dFRFi9ezI033shFF13EokWLKlmesbEx9u/fz6uvvsqvf/1renp66OjoIBqNVkyUlyxZQl9fH7fffjv33Xcf55133knHeODAAb797W/z4osv0tjYWHn8jDEMDg7ieR7Lly/nsssuY8WKFSxbtmzS8+V5Hr29vWzatIlf/vKXbN68uSKWypnBcpZq2bJlPP3003R1dXHrrbee0uN6LGaMeCp/yCg0RQJTTFkavVJ+01gss4E3egbY1zdMvOl4hkWW6UKGmimm1pIZepmW+dPTr3E469at45577kFKydKlSysf5J7n0d/fz/z587nxxhu5+uqrWb58+THP1dTUxMqVK1m5ciXXX389Dz74IFu3bmXhwoUVUaC1ZvHixfz617/me9/7Hh/5yEem/T7Wg8suu4zLLrtswrFvfOMbbNmyZZJ4yuVy3HLLLZX+qGohhKCpqYmHHnoIrTVLly5FCEGhUGBgYIBYLMab3/xmLr/8clasWMGiRYsmlAdTqVSlz2nHjh0sWLCgUrorX/eWLFnCT3/6Uy677DKuueaak4pPa83nP/95duzYwZIlSyqvPcdxGBwcxHVdPvrRj/Kud72LeDw+6fYNDQ3Mnz+fK664gve+97088sgjPPbYY+TzeVpbWyubF+bNm8fAwABf+MIX+OpXv3rcEuXh8T399NN85zvfIZlMsmDBAqSUSClJJpOMjIywcuVK3vnOd3LNNddM6BM7klAoRHd3N93d3dx000088sgjfP/732dkZIS2trYJAkoIweLFi3nooYe4+uqrOf/880/qcT0eM8IUoyKMKulj+23dMnvZ3TNINps/5oeAZbrf5cEu3Xxyx7SuAsEuq/vuu49wOMzcuXMrH+C+71MsFnnve9/L/fffz5/92Z8dVzgdydKlS7n//vtZsWIFBw8enPSaWrhwIf/5n//J9u3bq3Z/ZjrFYnHS4yCEQErJ+Pj4tKzp+z7Nzc2VrNbBgwcZHx/n2muv5c477+TOO+/kpptuYunSpZP6quLxONdddx33338/V111FQcOHJiQDChnStrb2/nud79LPp8/qdi+/vWvs2nTJrq7uycIp76+PlpaWrj33nv5wAc+MKVwOpK2tjZuvfXWSqlrZGSk8lgrpZgzZw6ZTIZ77733hEugL7/8Ml/84hcxxrBo0aKKcMxms0Sj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bDhDd8stt/DUU0/xpS99ia9//eucO3eOmZkZms3m4BTearPLq3++rm5DEGOk3W6zuLhIs9nkIx/5CJ/4xCc2nLlbffyKoljTxLQoik3dzoW3fky34loWPBmzRT71jx7lOy/8jP/1rRc4cts+iNEaC2whEU/R/iUAB9//J9teVO+958KFCwA8+uijPProozz33HP87d/+LS+++CKnT59GRGg0GmRZRpIkgyex1SeBTqdDt9sdtBd4/PHH+dCHPrTpa221WvzRH/0RDz/8MM888wwnTpxgZWWFLMvWrG01uFh9nec5IkKz2WR2dpZjx45x9OhR7r33Xm677UpH/LcqWL7ejuBZlvGHf/iHPPLIIzz77LO89NJLnD17dvAx5xzOOfr9/mBr7+30+31WVlbodruD96kq7XZ70+f+FUVBu91+07VWVlau61pJkvD7v//7PPbYY5w5/4UAABx2SURBVHzta1/jBz/4Aa+99tpgiG+apmt+1laDizzP6fV6OOfYvXs3TzzxBI8//viGZyW+8X42m8013+92u73pTU3zPL/mY7oV3z8LnozZQp//Nx/nd//1F/k/P/gJt92yhyT1aLQQanMJIo7+8o/RsMgtjz5LY2r7CsWv9sbg4Pjx4xw/fpzTp0/z/PPP85Of/IQzZ85w8eJFVlZWBn8dJ0nC9PQ0u3bt4tChQ9xzzz3cd999W77eRx55hEceeYQTJ07wox/9iJMnT7K4uEi32yWEQJqmg226iYmJQc3WwYMH2b9//5ou1G98HK7Vl+laWayNePDBB3nwwQd59dVX+fGPf8yZM2c4e/Ys7XabPM8JIZAkyTtmTz760Y/ygQ98YM2sttXgYqO1ZW/lt37rt7jrrrvWDNtVVfI8Z8+ePW9zy3fn1ltv5dOf/jRLS0s8//zznDx5klOnTrG0tDR4XADSNKXZbDI5Ocm+ffs4fPgwx44de9PBgI26//77+fznP78mYIOyK/4bM5HX64knnhhsla9afUz37du3qdey4MmYLTRer/HX//6f8rmn/pqvfv27JKlnftcUSeKtDuq6CaAUvbMUyz+jPvsbHHj/f2B87qHtXtg7WlhYYGFhgQ9/+MMALC0tsby8DJS/7JMkYWpq6i239Lba0aNHOXr06ODtXq9HURRkWbahI+rXyvis3s/N9G4GI7+d+fn5TdsOfSezs7PMzs5u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" } }, "cell_type": "markdown", "id": "3ff0335c", "metadata": {}, "source": [ "![imagen.png](attachment:imagen.png)" ] }, { "cell_type": "markdown", "id": "a37bbe41", "metadata": {}, "source": [ "Image obtained from: https://www.programaenlinea.net/los-pickles-python/" ] }, { "cell_type": "markdown", "id": "73e38338", "metadata": {}, "source": [ "Picke es una librería que permite serializar y des-serializar objetos. Dado un objeto el mismo puede almacenarse en formato binario y en el futuro, puede recuperarse el objeto a partir del archivo binario almacenado. Para más información visitar: https://docs.python.org/3/library/pickle.html." ] }, { "cell_type": "markdown", "id": "41deebff", "metadata": {}, "source": [ "### 2.1. Saving a simple object" ] }, { "cell_type": "markdown", "id": "706925bb", "metadata": {}, "source": [ "#### Object Creation;" ] }, { "cell_type": "code", "execution_count": 2, "id": "863dd78a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Object: <__main__.Car object at 0x7b76cc62b010>\n", "Attribute: brand= Jeep\n" ] } ], "source": [ "# Definition or a class\n", "class Car():\n", " def __init__(self, brand):\n", " self.brand = brand\n", "# Creation of an instance of this class:\n", "carOne=Car('Jeep')\n", "print('Object: ',carOne)\n", "print('Attribute: brand=',carOne.brand)" ] }, { "cell_type": "markdown", "id": "7f004710", "metadata": {}, "source": [ "#### Saving the object:" ] }, { "cell_type": "code", "execution_count": 3, "id": "2dda300c", "metadata": {}, "outputs": [], "source": [ "fileName='object.pkl'\n", "pickle.dump(carOne, open(fileName, 'wb'))" ] }, { "cell_type": "markdown", "id": "2c340193", "metadata": {}, "source": [ "#### Retrieving the object from file:" ] }, { "cell_type": "code", "execution_count": 4, "id": "7dc2e86c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Attribute loaded: brand= Jeep\n" ] } ], "source": [ "otherCar=pickle.load(open(fileName,'rb'))\n", "print('Attribute loaded: brand=',otherCar.brand)\n", "# Erase file after retrieving object\n", "os.remove(fileName)" ] }, { "cell_type": "markdown", "id": "1cfdbbb4", "metadata": {}, "source": [ "## 3. Pickling a model and a scaler" ] }, { "cell_type": "markdown", "id": "5d08433a", "metadata": {}, "source": [ "### 3.1. Training a model: Diabetes Prediction" ] }, { "cell_type": "markdown", "id": "3290c76b", "metadata": {}, "source": [ "#### Context" ] }, { "cell_type": "markdown", "id": "38d6c501", "metadata": {}, "source": [ "This dataset is originally from the National Institute of Diabetes and Digestive and Kidney Diseases. The objective is to predict based on diagnostic measurements whether a patient has diabetes. The dataset can be downloaded from the site of Kaggle (link: 'click here' )." ] }, { "cell_type": "markdown", "id": "0425965c", "metadata": {}, "source": [ "#### The dataset" ] }, { "cell_type": "code", "execution_count": 5, "id": "7e8eb121", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age', 'Diabetes']\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PregnanciesGlucoseBloodPressureSkinThicknessInsulinBMIDiabetesPedigreeFunctionAgeDiabetes
061487235033.6627.00501
11856629026.6351.00310
28183640023.3672.00321
318966239428.1167.00210
40137403516843.12288.00331
..............................
76310101764818032.9171.00630
76421227027036.80.34270
7655121722311226.2245.00300
7661126600030.1349.00471
7671937031030.4315.00230
\n", "

768 rows × 9 columns

\n", "
" ], "text/plain": [ " Pregnancies Glucose BloodPressure SkinThickness Insulin BMI \\\n", "0 6 148 72 35 0 33.6 \n", "1 1 85 66 29 0 26.6 \n", "2 8 183 64 0 0 23.3 \n", "3 1 89 66 23 94 28.1 \n", "4 0 137 40 35 168 43.1 \n", ".. ... ... ... ... ... ... \n", "763 10 101 76 48 180 32.9 \n", "764 2 122 70 27 0 36.8 \n", "765 5 121 72 23 112 26.2 \n", "766 1 126 60 0 0 30.1 \n", "767 1 93 70 31 0 30.4 \n", "\n", " DiabetesPedigreeFunction Age Diabetes \n", "0 627.00 50 1 \n", "1 351.00 31 0 \n", "2 672.00 32 1 \n", "3 167.00 21 0 \n", "4 2288.00 33 1 \n", ".. ... ... ... \n", "763 171.00 63 0 \n", "764 0.34 27 0 \n", "765 245.00 30 0 \n", "766 349.00 47 1 \n", "767 315.00 23 0 \n", "\n", "[768 rows x 9 columns]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The Dataset from csv file\n", "df = pd.read_csv('datasets'+str(separador)+'diabetes.csv')\n", "fields=df.columns.tolist()\n", "print(fields)\n", "df" ] }, { "cell_type": "code", "execution_count": 6, "id": "c57d37c7", "metadata": {}, "outputs": [], "source": [ "# Preparing the data\n", "X_ = df.iloc[:,:len(fields)-1].values\n", "y_=df.iloc[:,len(fields)-1]\n", "y=np.array(y_)\n", "# Scaling data\n", "sc = StandardScaler()\n", "X = sc.fit_transform(X_)\n", "# Split in Train and Test\n", "X_train, X_test, Y_train, Y_test = model_selection.train_test_split(X, y, test_size=0.2, random_state=7)" ] }, { "cell_type": "markdown", "id": "f1c03467", "metadata": {}, "source": [ "#### Training a Model" ] }, { "cell_type": "code", "execution_count": 7, "id": "407552e1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Reporte de las Clasificaciones\n", " precision recall f1-score support\n", "\n", " 0 0.79 0.92 0.85 97\n", " 1 0.81 0.60 0.69 57\n", "\n", " accuracy 0.80 154\n", " macro avg 0.80 0.76 0.77 154\n", "weighted avg 0.80 0.80 0.79 154\n", "\n" ] } ], "source": [ "# Training the Logistic Regression model\n", "from sklearn import linear_model\n", "model = linear_model.LogisticRegression()\n", "model.fit(X_train,Y_train)\n", "predictions = model.predict(X_test)\n", "print('\\nReporte de las Clasificaciones\\n',classification_report(Y_test, predictions))" ] }, { "cell_type": "markdown", "id": "17b6b024", "metadata": {}, "source": [ "#### Persistance of Model and Scaler" ] }, { "cell_type": "markdown", "id": "9a8e4be2", "metadata": {}, "source": [ "Trained models and scalers can be deployed as pickle files in big applications or complex systems where training models in prediction instances is not allowed because of performance issues. Pickle files contain a summary of the training process in compressed form. " ] }, { "cell_type": "code", "execution_count": 8, "id": "27b50662", "metadata": {}, "outputs": [], "source": [ "# Saving model and Scaler\n", "fileModel=('model.pkl')\n", "pickle.dump(model, open(fileModel, 'wb'))\n", "fileScaler=('scaler.pkl')\n", "pickle.dump(sc, open(fileScaler, 'wb'))" ] }, { "cell_type": "code", "execution_count": 9, "id": "0573c2ee", "metadata": {}, "outputs": [], "source": [ "# Loading model and scaler from binary files:\n", "modelLoaded=pickle.load(open(fileModel,'rb'))\n", "scalerLoaded=pickle.load(open(fileScaler,'rb'))\n", "# Erase files after retrieving objects\n", "os.remove(fileModel)\n", "os.remove(fileScaler)" ] }, { "cell_type": "markdown", "id": "6612b9f5", "metadata": {}, "source": [ "#### Predictions" ] }, { "cell_type": "markdown", "id": "351a1d56", "metadata": {}, "source": [ "In this step we use information loaded from pickle files in order to predict diabetes diagnoses of some random rows." ] }, { "cell_type": "code", "execution_count": 10, "id": "94ef7393", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[-0.64549722 0.25226125 0.38164503 1.22698758 -0.5 0.17611091\n", " -1.03804971 -0.60328193]\n", " [-0.64549722 -0.80371607 0.31584416 1.17171787 2. 1.66294894\n", " -0.30763394 -0.60328193]\n", " [-0.64549722 1.30823857 -1.78978358 -0.98380086 -0.5 -0.1125955\n", " 1.72464054 -0.07868895]\n", " [ 1.93649167 0.6922518 1.2370563 -0.98380086 -0.5 -0.27138403\n", " 0.43567153 1.95410886]\n", " [ 0. -1.44903555 -0.14476191 -0.43110375 -0.5 -1.45508032\n", " -0.81462842 -0.66885605]]\n" ] } ], "source": [ "# We select some random rows from the Dataset\n", "nb_of_rows=5\n", "X_n=[]\n", "random_rows=[]\n", "for i in range(nb_of_rows):\n", " random_num=random.randint(0,df.shape[0])\n", " X_n.append(list(X_[random_num]))\n", " random_rows.append(random_num)\n", "X_New=np.array(X_n)\n", "X_New_Norm=scalerLoaded.fit_transform(X_New)\n", "print(X_New_Norm)" ] }, { "cell_type": "code", "execution_count": 11, "id": "97cc9f06", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Predicted: [0 0 1 1 0] - Real: [1 0 1 1 0]\n" ] } ], "source": [ "# Prediction:\n", "y_pred=modelLoaded.predict(X_New_Norm)\n", "y_real=[]\n", "for i in range(nb_of_rows):\n", " y_real.append(y_[random_rows[i]])\n", "print('Predicted: ',y_pred,' - Real:',np.array(y_real))" ] }, { "cell_type": "markdown", "id": "44a8b0c0", "metadata": {}, "source": [ "## 4. Conclusions" ] }, { "cell_type": "markdown", "id": "c6ccf291", "metadata": {}, "source": [ "The Pickle library is a great tool for persisting objects present in memory, so that they can be used in another instance.\n", "It is also convenient when more than one prediction must be made after a learning. In this case, using the models stored in pickle avoids unnecessarily repeating the training of the models, making the systems more performant." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.3" } }, "nbformat": 4, "nbformat_minor": 5 }