{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Predict late shipments\n", "\n", "While delays may be unavoidable, retailers and manufacturers have the ability to manage any negative impact that delays have on their supply chain, by foreseeing and mitigating potential disruptions. The difficulty in doing so today is that retailers and manufacturers are ill equipped with a lack of forward looking information. However, through the use of AI, supply chain managers can proactively anticipate irregularities in the supply chain by predicting whether deliveries will arrive on time for both outbound and inbound shipments. Using historical shipment data and features associated with deliveries such as weather and port traffic, AI learns patterns associated with on-time and late deliveries to accurately classify future shipments into either bucket and offers the top statistical reasons why. Based on this information, supply chain managers are able to implement changes that prevent avoidable late deliveries, and to mitigate the risks that stem from unavoidable late deliveries." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Import libraries" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "autoscroll": "auto" }, "outputs": [], "source": [ "import datarobot as dr\n", "import matplotlib.pyplot as plt\n", "import matplotlib.ticker as mtick\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Connect to DataRobot\n", "\n", "Read more about different options for [connecting to DataRobot from the client](https://docs.datarobot.com/en/docs/api/api-quickstart/api-qs.html)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# If the config file is not in the default location described in the API Quickstart guide, '~/.config/datarobot/drconfig.yaml', then you will need to call\n", "# dr.Client(config_path='path-to-drconfig.yaml')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import data\n", "\n", "DataRobot hosts the dataset used in this notebook: access it via the URL in the following paragraph (`data_path`). Read in the data directly from the URL into a [Pandas DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) and display the results to verify all of the data looks correct." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "autoscroll": "auto" }, "outputs": [ { "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", " \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", "
IDCountryManaged ByFulfill ViaVendor INCO TermShipment ModeLate_deliveryProduct GroupSub ClassificationVendor...Unit of Measure (Per Pack)Line Item QuantityLine Item ValuePack PriceUnit PriceManufacturing SiteFirst Line DesignationWeight (Kilograms)Freight Cost (USD)Line Item Insurance (USD)
01Cªte d'IvoirePMO - USDirect DropEXWAir0HRDTHIV testRANBAXY Fine Chemicals LTD....3019551.0029.000.97Ranbaxy Fine Chemicals LTDYes13.0780.34NaN
13VietnamPMO - USDirect DropEXWAir0ARVPediatricAurobindo Pharma Limited...24010006200.006.200.03Aurobindo Unit III, IndiaYes358.04521.50NaN
24Cªte d'IvoirePMO - USDirect DropFCAAir0HRDTHIV testAbbott GmbH & Co. KG...10050040000.0080.000.80ABBVIE GmbH & Co.KG WiesbadenYes171.01653.78NaN
315VietnamPMO - USDirect DropEXWAir0ARVAdultSUN PHARMACEUTICAL INDUSTRIES LTD (RANBAXY LAB......6031920127360.803.990.07Ranbaxy, Paonta Shahib, IndiaYes1855.016007.06NaN
416VietnamPMO - USDirect DropEXWAir0ARVAdultAurobindo Pharma Limited...6038000121600.003.200.05Aurobindo Unit III, IndiaYes7590.045450.08NaN
..................................................................
951048HaitiPMO - USDirect DropFCAAir0ARVPediatricABBVIE LOGISTICS (FORMERLY ABBOTT LOGISTICS BV)...6046472.8810.280.17ABBVIE Ludwigshafen GermanyYes10.0893.220.93
961063South AfricaPMO - USDirect DropDDPAir0ARVAdultS. BUYS WHOLESALER...30302547522.7515.710.52Aurobindo Unit III, IndiaYesNaNNaN93.14
971065South AfricaPMO - USDirect DropDDPAir0ARVAdultS. BUYS WHOLESALER...30350049840.0014.240.47Cipla, Goa, IndiaYesNaNNaN97.69
981066South AfricaPMO - USDirect DropDDPAir0ARVPediatricS. BUYS WHOLESALER...24010083588.483.560.01Aurobindo Unit III, IndiaNoNaNNaN7.03
991067South AfricaPMO - USDirect DropDDPAir0ARVPediatricS. BUYS WHOLESALER...2009601152.001.200.01BMS Meymac, FranceYesNaNNaN2.26
\n", "

100 rows × 25 columns

\n", "
" ], "text/plain": [ " ID Country Managed By Fulfill Via Vendor INCO Term \\\n", "0 1 Cªte d'Ivoire PMO - US Direct Drop EXW \n", "1 3 Vietnam PMO - US Direct Drop EXW \n", "2 4 Cªte d'Ivoire PMO - US Direct Drop FCA \n", "3 15 Vietnam PMO - US Direct Drop EXW \n", "4 16 Vietnam PMO - US Direct Drop EXW \n", ".. ... ... ... ... ... \n", "95 1048 Haiti PMO - US Direct Drop FCA \n", "96 1063 South Africa PMO - US Direct Drop DDP \n", "97 1065 South Africa PMO - US Direct Drop DDP \n", "98 1066 South Africa PMO - US Direct Drop DDP \n", "99 1067 South Africa PMO - US Direct Drop DDP \n", "\n", " Shipment Mode Late_delivery Product Group Sub Classification \\\n", "0 Air 0 HRDT HIV test \n", "1 Air 0 ARV Pediatric \n", "2 Air 0 HRDT HIV test \n", "3 Air 0 ARV Adult \n", "4 Air 0 ARV Adult \n", ".. ... ... ... ... \n", "95 Air 0 ARV Pediatric \n", "96 Air 0 ARV Adult \n", "97 Air 0 ARV Adult \n", "98 Air 0 ARV Pediatric \n", "99 Air 0 ARV Pediatric \n", "\n", " Vendor ... \\\n", "0 RANBAXY Fine Chemicals LTD. ... \n", "1 Aurobindo Pharma Limited ... \n", "2 Abbott GmbH & Co. KG ... \n", "3 SUN PHARMACEUTICAL INDUSTRIES LTD (RANBAXY LAB... ... \n", "4 Aurobindo Pharma Limited ... \n", ".. ... ... \n", "95 ABBVIE LOGISTICS (FORMERLY ABBOTT LOGISTICS BV) ... \n", "96 S. BUYS WHOLESALER ... \n", "97 S. BUYS WHOLESALER ... \n", "98 S. BUYS WHOLESALER ... \n", "99 S. BUYS WHOLESALER ... \n", "\n", " Unit of Measure (Per Pack) Line Item Quantity Line Item Value Pack Price \\\n", "0 30 19 551.00 29.00 \n", "1 240 1000 6200.00 6.20 \n", "2 100 500 40000.00 80.00 \n", "3 60 31920 127360.80 3.99 \n", "4 60 38000 121600.00 3.20 \n", ".. ... ... ... ... \n", "95 60 46 472.88 10.28 \n", "96 30 3025 47522.75 15.71 \n", "97 30 3500 49840.00 14.24 \n", "98 240 1008 3588.48 3.56 \n", "99 200 960 1152.00 1.20 \n", "\n", " Unit Price Manufacturing Site First Line Designation \\\n", "0 0.97 Ranbaxy Fine Chemicals LTD Yes \n", "1 0.03 Aurobindo Unit III, India Yes \n", "2 0.80 ABBVIE GmbH & Co.KG Wiesbaden Yes \n", "3 0.07 Ranbaxy, Paonta Shahib, India Yes \n", "4 0.05 Aurobindo Unit III, India Yes \n", ".. ... ... ... \n", "95 0.17 ABBVIE Ludwigshafen Germany Yes \n", "96 0.52 Aurobindo Unit III, India Yes \n", "97 0.47 Cipla, Goa, India Yes \n", "98 0.01 Aurobindo Unit III, India No \n", "99 0.01 BMS Meymac, France Yes \n", "\n", " Weight (Kilograms) Freight Cost (USD) Line Item Insurance (USD) \n", "0 13.0 780.34 NaN \n", "1 358.0 4521.50 NaN \n", "2 171.0 1653.78 NaN \n", "3 1855.0 16007.06 NaN \n", "4 7590.0 45450.08 NaN \n", ".. ... ... ... \n", "95 10.0 893.22 0.93 \n", "96 NaN NaN 93.14 \n", "97 NaN NaN 97.69 \n", "98 NaN NaN 7.03 \n", "99 NaN NaN 2.26 \n", "\n", "[100 rows x 25 columns]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_path = \"https://pathfinder.datarobot.com/wp-content/uploads/2020/06/Pathfinder_Training_Predict-Parts-Shortage.csv\"\n", "\n", "pathfinder_df = pd.read_csv(data_path, encoding=\"ISO-8859-1\")\n", "\n", "pathfinder_df.head(100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visualize data\n", "\n", "Below, view several examples of charts that visualize the dataset in different ways such as grouping by shipment method, average delivery time, and vendor." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "autoscroll": "auto" }, "outputs": [ { "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", "
Shipment ModeLate_delivery
0Air0.096025
1Air Charter0.115385
2Ocean0.175202
3Truck0.160777
\n", "
" ], "text/plain": [ " Shipment Mode Late_delivery\n", "0 Air 0.096025\n", "1 Air Charter 0.115385\n", "2 Ocean 0.175202\n", "3 Truck 0.160777" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1 = (\n", " pathfinder_df.where(pathfinder_df[\"Late_delivery\"] == 1)\n", " .groupby(\"Shipment Mode\")\n", " .agg({\"Late_delivery\": \"count\"})\n", ")\n", "df2 = (\n", " pathfinder_df.where(pathfinder_df[\"Late_delivery\"] == 0)\n", " .groupby(\"Shipment Mode\")\n", " .agg({\"Late_delivery\": \"count\"})\n", ")\n", "df_perc = df1 / (df2 + df1)\n", "df_perc = df_perc.reset_index() # doing this prevents html getting displayed on the x-axis\n", "\n", "df_perc" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "autoscroll": "auto" }, "outputs": [ { "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", "
Late_deliveryIDUnit of Measure (Per Pack)Line Item QuantityLine Item ValuePack PriceUnit PriceWeight (Kilograms)Freight Cost (USD)Line Item Insurance (USD)Late_delivery_str
0048029.30674178.45940017182.398446149764.73915022.8808660.6552863258.89246910823.199763229.296219On time
1174750.37352474.38111327194.209949218410.00922414.4316860.2758854656.08079513156.072446321.186624Late
\n", "
" ], "text/plain": [ " Late_delivery ID Unit of Measure (Per Pack) \\\n", "0 0 48029.306741 78.459400 \n", "1 1 74750.373524 74.381113 \n", "\n", " Line Item Quantity Line Item Value Pack Price Unit Price \\\n", "0 17182.398446 149764.739150 22.880866 0.655286 \n", "1 27194.209949 218410.009224 14.431686 0.275885 \n", "\n", " Weight (Kilograms) Freight Cost (USD) Line Item Insurance (USD) \\\n", "0 3258.892469 10823.199763 229.296219 \n", "1 4656.080795 13156.072446 321.186624 \n", "\n", " Late_delivery_str \n", "0 On time \n", "1 Late " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "avg_value_df = pathfinder_df.groupby(\"Late_delivery\").mean()\n", "avg_value_df[\"Late_delivery_str\"] = [\"On time\", \"Late\"]\n", "avg_value_df = avg_value_df.reset_index()\n", "\n", "avg_value_df" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "autoscroll": "auto" }, "outputs": [ { "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", "
IDUnit of Measure (Per Pack)Line Item QuantityLine Item ValuePack PriceUnit PriceWeight (Kilograms)Freight Cost (USD)Line Item Insurance (USD)Display
Late_delivery
048029.30674178.45940017182.398446149764.73915022.8808660.6552863258.89246910823.199763229.296219On time
174750.37352474.38111327194.209949218410.00922414.4316860.2758854656.08079513156.072446321.186624Late
\n", "
" ], "text/plain": [ " ID Unit of Measure (Per Pack) Line Item Quantity \\\n", "Late_delivery \n", "0 48029.306741 78.459400 17182.398446 \n", "1 74750.373524 74.381113 27194.209949 \n", "\n", " Line Item Value Pack Price Unit Price Weight (Kilograms) \\\n", "Late_delivery \n", "0 149764.739150 22.880866 0.655286 3258.892469 \n", "1 218410.009224 14.431686 0.275885 4656.080795 \n", "\n", " Freight Cost (USD) Line Item Insurance (USD) Display \n", "Late_delivery \n", "0 10823.199763 229.296219 On time \n", "1 13156.072446 321.186624 Late " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "avg_value_df = pathfinder_df.groupby(\"Late_delivery\").mean().replace(\"0\", \"On time\")\n", "avg_value_df[\"Display\"] = [\"On time\", \"Late\"]\n", "\n", "avg_value_df" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "autoscroll": "auto" }, "outputs": [ { "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", "
VendorLate_delivery
0ABBOTT LABORATORIES (PUERTO RICO)NaN
1ABBOTT LOGISTICS B.V.NaN
2ABBVIE LOGISTICS (FORMERLY ABBOTT LOGISTICS BV)0.011527
3ABBVIE, SRL (FORMALLY ABBOTT LABORATORIES INTE...NaN
4ACCESS BIO, INC.NaN
.........
68THE MEDICAL EXPORT GROUP BVNaN
69TURE PHARMACEUTICALS & MEDICAL SUPPLIES P.L.C.NaN
70Trinity Biotech, Plc0.002809
71WAGENIANaN
72ZEPHYR BIOMEDICALSNaN
\n", "

73 rows × 2 columns

\n", "
" ], "text/plain": [ " Vendor Late_delivery\n", "0 ABBOTT LABORATORIES (PUERTO RICO) NaN\n", "1 ABBOTT LOGISTICS B.V. NaN\n", "2 ABBVIE LOGISTICS (FORMERLY ABBOTT LOGISTICS BV) 0.011527\n", "3 ABBVIE, SRL (FORMALLY ABBOTT LABORATORIES INTE... NaN\n", "4 ACCESS BIO, INC. NaN\n", ".. ... ...\n", "68 THE MEDICAL EXPORT GROUP BV NaN\n", "69 TURE PHARMACEUTICALS & MEDICAL SUPPLIES P.L.C. NaN\n", "70 Trinity Biotech, Plc 0.002809\n", "71 WAGENIA NaN\n", "72 ZEPHYR BIOMEDICALS NaN\n", "\n", "[73 rows x 2 columns]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pandas import DataFrame\n", "\n", "df1 = (\n", " pathfinder_df.where(pathfinder_df[\"Late_delivery\"] == 1)\n", " .groupby(\"Vendor\")\n", " .agg({\"Late_delivery\": \"count\"})\n", ")\n", "df2 = (\n", " pathfinder_df.where(pathfinder_df[\"Late_delivery\"] == 0)\n", " .groupby(\"Vendor\")\n", " .agg({\"Late_delivery\": \"count\"})\n", ")\n", "\n", "df_perc = df1 / (df2 + df1)\n", "df_perc = df_perc.reset_index()\n", "\n", "df_perc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Modeling\n", " \n", "For this use case, create a DataRobot project and initiate modeling by running Autopilot in Quick mode." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "autoscroll": "auto" }, "outputs": [], "source": [ "EXISTING_PROJECT_ID = None # If you've already created a project, replace None with the ID here\n", "if EXISTING_PROJECT_ID is None:\n", " # Create project and pass in data\n", " project = dr.Project.create(sourcedata=pathfinder_df, project_name=\"Predicting Late Shipments\")\n", "\n", " # Set the project target to the appropriate feature. Use the LogLoss metric to measure performance\n", " project.set_target(target=\"Late_delivery\", mode=dr.AUTOPILOT_MODE.QUICK, worker_count=\"-1\")\n", "else:\n", " # Fetch the existing project\n", " project = dr.Project.get(EXISTING_PROJECT_ID)\n", "\n", "project.wait_for_autopilot(check_interval=30)\n", "\n", "\n", "# Get the project metric (i.e LogLoss, RMSE, etc.)\n", "metric = project.metric\n", "\n", "# Get the project ID\n", "# project_id = project.id\n", "# project_id" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### View project in UI\n", "\n", "If you want to view the project in the DataRobot UI, use the following snippet to retrieve the project's URL and use it to navigate to the application." ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "autoscroll": "auto" }, "outputs": [ { "data": { "text/plain": [ "'https://app.datarobot.com/projects/62e1533d3ee0c70bc69f0023/models'" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Get project URL\n", "project_url = project.get_leaderboard_ui_permalink()\n", "project_url" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initiate Autopilot" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "autoscroll": "auto" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "In progress: 4, queued: 0 (waited: 0s)\n", "In progress: 4, queued: 0 (waited: 0s)\n", "In progress: 4, queued: 0 (waited: 1s)\n", "In progress: 4, queued: 0 (waited: 2s)\n", "In progress: 4, queued: 0 (waited: 3s)\n", "In progress: 4, queued: 0 (waited: 5s)\n", "In progress: 4, queued: 0 (waited: 8s)\n", "In progress: 4, queued: 0 (waited: 15s)\n", "In progress: 2, queued: 0 (waited: 28s)\n", "In progress: 0, queued: 0 (waited: 54s)\n", "In progress: 7, queued: 0 (waited: 84s)\n", "In progress: 1, queued: 0 (waited: 115s)\n", "In progress: 0, queued: 0 (waited: 145s)\n", "In progress: 5, queued: 0 (waited: 175s)\n", "In progress: 1, queued: 0 (waited: 206s)\n", "In progress: 1, queued: 0 (waited: 236s)\n", "In progress: 1, queued: 0 (waited: 267s)\n", "In progress: 1, queued: 0 (waited: 297s)\n", "In progress: 1, queued: 0 (waited: 327s)\n", "In progress: 3, queued: 0 (waited: 358s)\n", "In progress: 1, queued: 0 (waited: 388s)\n", "In progress: 0, queued: 0 (waited: 418s)\n", "In progress: 0, queued: 0 (waited: 449s)\n" ] } ], "source": [ "project.wait_for_autopilot(check_interval=30)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Evaluate model performance \n", "\n", "In order to measure model performance, first select the top-performing model based on a specific performance metric (i.e., `LogLoss`) and then evaluate several different types of charts, such as Lift Chart, ROC Curve, and Feature Importance. There are two helper functions that you need to build in order simplify producing these model insights.\n", "\n", "You can reference more information about model evaluation tools [here](https://docs.datarobot.com/en/docs/modeling/analyze-models/evaluate/index.html)." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "autoscroll": "auto" }, "outputs": [], "source": [ "def sorted_by_metric(models, test_set, metric):\n", " models_with_score = [model for model in models if model.metrics[metric][test_set] is not None]\n", "\n", " return sorted(models_with_score, key=lambda model: model.metrics[metric][test_set])" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "autoscroll": "auto" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The top performing model is Model('eXtreme Gradient Boosted Trees Classifier with Early Stopping') using metric, LogLoss\n" ] } ], "source": [ "models = project.get_models()\n", "\n", "# Uncomment if this is not set above in the create project paragraph\n", "metric = project.metric\n", "\n", "# Get top performing model\n", "model_top = sorted_by_metric(models, \"crossValidation\", metric)[0]\n", "\n", "print(\n", " \"\"\"The top performing model is {model} using metric, {metric}\"\"\".format(\n", " model=str(model_top), metric=metric\n", " )\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Histogram" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "autoscroll": "auto" }, "outputs": [], "source": [ "# Set styling\n", "dr_dark_blue = \"#08233F\"\n", "dr_blue = \"#1F77B4\"\n", "dr_orange = \"#FF7F0E\"\n", "dr_red = \"#BE3C28\"\n", "dr_light_blue = \"#3CA3E8\"\n", "\n", "# Create function to build Historgrams\n", "\n", "\n", "def rebin_df(raw_df, number_of_bins):\n", " cols = [\"bin\", \"actual_mean\", \"predicted_mean\", \"bin_weight\"]\n", " new_df = pd.DataFrame(columns=cols)\n", " current_prediction_total = 0\n", " current_actual_total = 0\n", " current_row_total = 0\n", " x_index = 1\n", " bin_size = 60 / number_of_bins\n", " for rowId, data in raw_df.iterrows():\n", " current_prediction_total += data[\"predicted\"] * data[\"bin_weight\"]\n", " current_actual_total += data[\"actual\"] * data[\"bin_weight\"]\n", " current_row_total += data[\"bin_weight\"]\n", "\n", " if (rowId + 1) % bin_size == 0:\n", " x_index += 1\n", " bin_properties = {\n", " \"bin\": ((round(rowId + 1) / 60) * number_of_bins),\n", " \"actual_mean\": current_actual_total / current_row_total,\n", " \"predicted_mean\": current_prediction_total / current_row_total,\n", " \"bin_weight\": current_row_total,\n", " }\n", "\n", " new_df = new_df.append(bin_properties, ignore_index=True)\n", " current_prediction_total = 0\n", " current_actual_total = 0\n", " current_row_total = 0\n", " return new_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lift Chart\n", "\n", "A [lift chart](https://docs.datarobot.com/en/docs/modeling/analyze-models/evaluate/lift-chart.html#lift-chart) shows you how close model predictions are to the actual values of the target in the training data. The lift chart data includes the average predicted value and the average actual values" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "# Create function to build lift charts\n", "\n", "\n", "def matplotlib_lift(bins_df, bin_count, ax):\n", " grouped = rebin_df(bins_df, bin_count)\n", " ax.plot(\n", " range(1, len(grouped) + 1),\n", " grouped[\"predicted_mean\"],\n", " marker=\"+\",\n", " lw=1,\n", " color=dr_blue,\n", " label=\"predicted\",\n", " )\n", " ax.plot(\n", " range(1, len(grouped) + 1),\n", " grouped[\"actual_mean\"],\n", " marker=\"*\",\n", " lw=1,\n", " color=dr_orange,\n", " label=\"actual\",\n", " )\n", " ax.set_xlim([0, len(grouped) + 1])\n", " ax.set_facecolor(dr_dark_blue)\n", " ax.legend(loc=\"best\")\n", " ax.set_title(\"Lift chart {} bins\".format(bin_count))\n", " ax.set_xlabel(\"Sorted Prediction\")\n", " ax.set_ylabel(\"Value\")\n", " return grouped" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "autoscroll": "auto" }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "lift_chart = model_top.get_lift_chart(\"validation\")\n", "\n", "# Save the result into a pandas dataframe\n", "lift_df = pd.DataFrame(lift_chart.bins)\n", "\n", "bin_counts = [10, 15]\n", "f, axarr = plt.subplots(len(bin_counts))\n", "f.set_size_inches((8, 4 * len(bin_counts)))\n", "\n", "rebinned_dfs = []\n", "for i in range(len(bin_counts)):\n", " rebinned_dfs.append(matplotlib_lift(lift_df, bin_counts[i], axarr[i]))\n", "\n", "plt.tight_layout()\n", "# plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ROC Curve\n", "\n", "The receiver operating characteristic curve, or [ROC curve](https://docs.datarobot.com/en/docs/modeling/analyze-models/evaluate/roc-curve-tab/roc-curve.html), is a graphical plot that illustrates the performance of a binary classifier system as its discrimination threshold is varied. The curve is created by plotting the true positive rate (TPR) against the false positive rate (FPR) at various threshold settings." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "autoscroll": "auto" }, "outputs": [ { "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", " \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", "
accuracyf1_scorefalse_negative_scoretrue_negative_scoretrue_positive_scorefalse_positive_scoretrue_negative_ratefalse_positive_ratetrue_positive_ratematthews_correlation_coefficientpositive_predictive_valuenegative_predictive_valuethresholdfraction_predicted_as_positivefraction_predicted_as_negativelift_positivelift_negative
00.8849880.0000001901462001.0000000.0000000.0000000.0000000.0000000.8849881.0000000.0000001.0000000.0000001.000000
10.8843830.0000001901461010.9993160.0006840.000000-0.0088720.0000000.8849180.7419940.0006050.9993950.0000000.999921
20.8831720.0000001901459030.9979480.0020520.000000-0.0153760.0000000.8847790.6010530.0018160.9981840.0000000.999764
30.8825670.0000001901458040.9972640.0027360.000000-0.0177600.0000000.8847090.5779890.0024210.9975790.0000000.999685
40.8825670.0202021881456260.9958960.0041040.0105260.0295150.2500000.8856450.5469340.0048430.9951572.1736841.000742
......................................................
1100.1555690.21408506719013950.0458280.9541721.0000000.0741180.1198741.0000000.0024290.9594430.0405571.0422711.129959
1110.1452780.21205405019014120.0342000.9658001.0000000.0636880.1186021.0000000.0021110.9697340.0302661.0312111.129959
1120.1349880.21006103319014290.0225720.9774281.0000000.0514680.1173561.0000000.0017950.9800240.0199761.0203831.129959
1130.1253030.20821901719014450.0116280.9883721.0000000.0367590.1162081.0000000.0015890.9897090.0102911.0103981.129959
1140.1150120.2062980019014620.0000001.0000001.0000000.0000000.1150120.0000000.0009141.0000000.0000001.0000000.000000
\n", "

115 rows × 17 columns

\n", "
" ], "text/plain": [ " accuracy f1_score false_negative_score true_negative_score \\\n", "0 0.884988 0.000000 190 1462 \n", "1 0.884383 0.000000 190 1461 \n", "2 0.883172 0.000000 190 1459 \n", "3 0.882567 0.000000 190 1458 \n", "4 0.882567 0.020202 188 1456 \n", ".. ... ... ... ... \n", "110 0.155569 0.214085 0 67 \n", "111 0.145278 0.212054 0 50 \n", "112 0.134988 0.210061 0 33 \n", "113 0.125303 0.208219 0 17 \n", "114 0.115012 0.206298 0 0 \n", "\n", " true_positive_score false_positive_score true_negative_rate \\\n", "0 0 0 1.000000 \n", "1 0 1 0.999316 \n", "2 0 3 0.997948 \n", "3 0 4 0.997264 \n", "4 2 6 0.995896 \n", ".. ... ... ... \n", "110 190 1395 0.045828 \n", "111 190 1412 0.034200 \n", "112 190 1429 0.022572 \n", "113 190 1445 0.011628 \n", "114 190 1462 0.000000 \n", "\n", " false_positive_rate true_positive_rate \\\n", "0 0.000000 0.000000 \n", "1 0.000684 0.000000 \n", "2 0.002052 0.000000 \n", "3 0.002736 0.000000 \n", "4 0.004104 0.010526 \n", ".. ... ... \n", "110 0.954172 1.000000 \n", "111 0.965800 1.000000 \n", "112 0.977428 1.000000 \n", "113 0.988372 1.000000 \n", "114 1.000000 1.000000 \n", "\n", " matthews_correlation_coefficient positive_predictive_value \\\n", "0 0.000000 0.000000 \n", "1 -0.008872 0.000000 \n", "2 -0.015376 0.000000 \n", "3 -0.017760 0.000000 \n", "4 0.029515 0.250000 \n", ".. ... ... \n", "110 0.074118 0.119874 \n", "111 0.063688 0.118602 \n", "112 0.051468 0.117356 \n", "113 0.036759 0.116208 \n", "114 0.000000 0.115012 \n", "\n", " negative_predictive_value threshold fraction_predicted_as_positive \\\n", "0 0.884988 1.000000 0.000000 \n", "1 0.884918 0.741994 0.000605 \n", "2 0.884779 0.601053 0.001816 \n", "3 0.884709 0.577989 0.002421 \n", "4 0.885645 0.546934 0.004843 \n", ".. ... ... ... \n", "110 1.000000 0.002429 0.959443 \n", "111 1.000000 0.002111 0.969734 \n", "112 1.000000 0.001795 0.980024 \n", "113 1.000000 0.001589 0.989709 \n", "114 0.000000 0.000914 1.000000 \n", "\n", " fraction_predicted_as_negative lift_positive lift_negative \n", "0 1.000000 0.000000 1.000000 \n", "1 0.999395 0.000000 0.999921 \n", "2 0.998184 0.000000 0.999764 \n", "3 0.997579 0.000000 0.999685 \n", "4 0.995157 2.173684 1.000742 \n", ".. ... ... ... \n", "110 0.040557 1.042271 1.129959 \n", "111 0.030266 1.031211 1.129959 \n", "112 0.019976 1.020383 1.129959 \n", "113 0.010291 1.010398 1.129959 \n", "114 0.000000 1.000000 0.000000 \n", "\n", "[115 rows x 17 columns]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "roc = model_top.get_roc_curve(\"validation\")\n", "\n", "# Save the result into a pandas dataframe\n", "roc_df = pd.DataFrame(roc.roc_points)\n", "\n", "roc_df" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dr_roc_green = \"#03c75f\"\n", "white = \"#ffffff\"\n", "dr_purple = \"#65147D\"\n", "dr_dense_green = \"#018f4f\"\n", "\n", "threshold = roc.get_best_f1_threshold()\n", "fig = plt.figure(figsize=(8, 8))\n", "axes = fig.add_subplot(1, 1, 1, facecolor=dr_dark_blue)\n", "\n", "plt.scatter(roc_df.false_positive_rate, roc_df.true_positive_rate, color=dr_roc_green)\n", "plt.plot(roc_df.false_positive_rate, roc_df.true_positive_rate, color=dr_roc_green)\n", "plt.plot([0, 1], [0, 1], color=white, alpha=0.25)\n", "plt.title(\"ROC curve\")\n", "plt.xlabel(\"False Positive Rate\")\n", "plt.xlim([0, 1])\n", "plt.ylabel(\"True Positive Rate\")\n", "plt.ylim([0, 1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Feature Impact\n", "\n", "[Feature Impact](https://docs.datarobot.com/en/docs/modeling/analyze-models/understand/feature-impact.html) measures how important a feature is in the context of a model. It measures how much the accuracy of a model would decrease if that feature was removed.\n", "\n", "Feature Impact is available for all model types and works by altering input data and observing the effect on a model’s score. It is an on-demand feature, meaning that you must initiate a calculation to see the results. Once DataRobot computes the feature impact for a model, that information is saved with the project." ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "autoscroll": "auto" }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "feature_impacts = model_top.get_or_request_feature_impact()\n", "\n", "# Limit size to make chart look good. Display top 25 values\n", "if len(feature_impacts) > 25:\n", " feature_impacts = feature_impacts[0:24]\n", "\n", "# Formats the ticks from a float into a percent\n", "percent_tick_fmt = mtick.PercentFormatter(xmax=1.0)\n", "\n", "impact_df = pd.DataFrame(feature_impacts)\n", "impact_df.sort_values(by=\"impactNormalized\", ascending=True, inplace=True)\n", "\n", "# Positive values are blue, negative are red\n", "bar_colors = impact_df.impactNormalized.apply(lambda x: dr_red if x < 0 else dr_blue)\n", "\n", "ax = impact_df.plot.barh(\n", " x=\"featureName\", y=\"impactNormalized\", legend=False, color=bar_colors, figsize=(10, 8)\n", ")\n", "ax.xaxis.set_major_formatter(percent_tick_fmt)\n", "ax.xaxis.set_tick_params(labeltop=True)\n", "ax.xaxis.grid(True, alpha=0.2)\n", "ax.set_facecolor(dr_dark_blue)\n", "\n", "plt.ylabel(\"\")\n", "plt.xlabel(\"Effect\")\n", "plt.xlim((None, 1)) # Allow for negative impact\n", "plt.title(\"Feature Impact\", y=1.04);" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Make predictions\n", "\n", "### Test predictions\n", "\n", "After determining the top-performing model from the Leaderboard, upload the prediction test dataset to verify that the model generates predictions successfully before deploying the model to a production environment. The predictions are returned as a Pandas dataframe. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data_path_scoring = \"https://pathfinder.datarobot.com/wp-content/uploads/2020/06/Pathfinder_Scoring_Predict-Parts-Shortage.xlsx\"\n", "scoring_df = pd.read_excel(data_path_scoring, engine=\"openpyxl\")\n", "\n", "prediction_dataset = project.upload_dataset(scoring_df)\n", "predict_job = model_top.request_predictions(prediction_dataset.id)\n", "prediction_dataset.id\n", "\n", "predictions = predict_job.get_result_when_complete()\n", "pd.concat([scoring_df, predictions], axis=1)\n", "predictions.positive_probability.plot(kind=\"hist\", title=\"Predicted Probabilities\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Deploy a model to production\n", "\n", "\n", "If you are happy with the model's performance, you can deploy it to a production environment with [MLOps](https://docs.datarobot.com/en/mlops/index.html). Deploying the model will free up workers, as data scored through the deployment doesn't use any modeling workers. Furthermore, you are no longer restricted on the amount of data to score; score over 100GB with the deployment. Deployments also offer many model management benefits: monitoring service, data drift, model comparison, retraining, and more." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "autoscroll": "auto" }, "outputs": [ { "data": { "text/plain": [ "Deployment(Late Shipment Predictions)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creat a prediction server\n", "prediction_server = dr.PredictionServer.list()[0]\n", "\n", "# Get top performing model. Un comment if this did not execute in the previous section\n", "# model_top = sorted_by_metric(models, 'crossValidation', metric)[0]\n", "\n", "deployment = dr.Deployment.create_from_learning_model(\n", " model_top.id,\n", " label=\"Late Shipment Predictions\",\n", " description=\"Predict Late Shipments\",\n", " default_prediction_server_id=prediction_server.id,\n", ")\n", "deployment.id" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Configure batch predictions\n", "\n", "After the model has been deployed, DataRobot creates an endpoint for real time scoring. The deployment allows you to use DataRobot's batch prediction API to score large datasets with a deployed DataRobot model. \n", "\n", "The batch prediction API provides flexible intake and output options when scoring large datasets using prediction servers. The API is exposed through the DataRobot Public API and can be consumed using a REST-enabled client or Public API bindings for DataRobot's Python client." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Set the deployment ID" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before proceeding, provide the deployed model's deployment ID (retrieved from the deployment's [Overview tab](https://docs.datarobot.com/en/docs/mlops/monitor/dep-overview.html))." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "deployment_id = \"YOUR_DEPLOYMENT_ID\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Determine input and output options\n", "\n", "DataRobot's batch prediction API allows you to score data from and to multiple sources. You can take advantage of the credentials and data sources you have already established previously through the UI for easy scoring. Credentials are usernames and passwords, while data sources are any databases with which you have previously established a connection (e.g., Snowflake). View the example code below outlining how to query credentials and data sources.\n", "\n", "You can reference the full list of DataRobot's supported [input](https://docs.datarobot.com/en/docs/predictions/batch/batch-prediction-api/intake-options.html) and [output options](https://docs.datarobot.com/en/docs/predictions/batch/batch-prediction-api/output-options.html).\n", "\n", "Reference the DataRobot documentation for more information about [data connections](https://docs.datarobot.com/en/docs/data/connect-data/data-conn.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The snippet below shows how you can query all credentials tied to a DataRobot account." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dr.Credential.list()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The output above returns multiple sets of credentials. The alphanumeric string included in each item of the list is the credentials ID. You can use that ID to access credentials through the API." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The snippet below shows how you can query all data sources tied to a DataRobot account. The second line lists each datastore with an alphanumeric string; that is the datastore ID." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5e6696ff820e737a5bd78430\n" ] } ], "source": [ "dr.DataStore.list()\n", "print(dr.DataStore.list()[0].id)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Scoring examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The snippets below demonstrate how to score data with the Batch Prediction API. Edit the `intake_settings` and `output_settings` to suit your needs. You can mix and match until you get the outcome you prefer." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Score from CSV to CSV" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Scoring without Prediction Explanations\n", "dr.BatchPredictionJob.score(\n", " deployment_id,\n", " intake_settings={\n", " \"type\": \"localFile\",\n", " \"file\": \"inputfile.csv\", # Provide the filepath, Pandas dataframe, or file-like object here\n", " },\n", " output_settings={\"type\": \"localFile\", \"path\": \"outputfile.csv\"},\n", ")\n", "\n", "# Scoring with Prediction Explanations\n", "dr.BatchPredictionJob.score(\n", " deployment_id,\n", " intake_settings={\n", " \"type\": \"localFile\",\n", " \"file\": \"inputfile.csv\", # Provide the filepath, Pandas dataframe, or file-like object here\n", " },\n", " output_settings={\"type\": \"localFile\", \"path\": \"outputfile.csv\"},\n", " max_explanations=3, # Compute Prediction Explanations for the amount of features indicated here\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Score from S3 to S3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dr.BatchPredictionJob.score(\n", " deployment_id,\n", " intake_settings={\n", " \"type\": \"s3\",\n", " \"url\": \"s3://theos-test-bucket/lending_club_scoring.csv\", # Provide the URL of your datastore here\n", " \"credential_id\": \"YOUR_CREDENTIAL_ID_FROM_ABOVE\", # Provide your credentials here\n", " },\n", " output_settings={\n", " \"type\": \"s3\",\n", " \"url\": \"s3://theos-test-bucket/lending_club_scored2.csv\",\n", " \"credential_id\": \"YOUR_CREDENTIAL_ID_FROM_ABOVE\",\n", " },\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Score from JDBC to JDBC" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "dr.BatchPredictionJob.score(\n", " deployment_id,\n", " intake_settings={\n", " \"type\": \"jdbc\",\n", " \"table\": \"table_name\",\n", " \"schema\": \"public\",\n", " \"dataStoreId\": data_store.id, # Provide the ID of your datastore here\n", " \"credentialId\": cred.credential_id, # Provide your credentials here\n", " },\n", " output_settings={\n", " \"type\": \"jdbc\",\n", " \"table\": \"table_name\",\n", " \"schema\": \"public\",\n", " \"statementType\": \"insert\",\n", " \"dataStoreId\": data_store.id,\n", " \"credentialId\": cred.credential_id,\n", " },\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.8.8" } }, "nbformat": 4, "nbformat_minor": 4 }