From 84324ee0a931f39f893af0739b83f81e984b73a1 Mon Sep 17 00:00:00 2001 From: Jim Dowling Date: Sat, 23 Mar 2024 07:31:45 +0000 Subject: [PATCH] fixes --- .../ch03/1_air_quality_feature_backfill.ipynb | 497 +++++- .../ch03/4_air_quality_batch_inference.ipynb | 1429 +++-------------- notebooks/ch03/5_function_calling.ipynb | 395 +++-- 3 files changed, 928 insertions(+), 1393 deletions(-) diff --git a/notebooks/ch03/1_air_quality_feature_backfill.ipynb b/notebooks/ch03/1_air_quality_feature_backfill.ipynb index f6d2d1c9..24250e00 100644 --- a/notebooks/ch03/1_air_quality_feature_backfill.ipynb +++ b/notebooks/ch03/1_air_quality_feature_backfill.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "5d72ce40", + "id": "b0e9f6e9", "metadata": {}, "source": [ "- Part 01: Feature Backfill for Air Quality Data\n", @@ -20,7 +20,7 @@ }, { "cell_type": "markdown", - "id": "0700e4c7", + "id": "c82e0e05", "metadata": {}, "source": [ "### 📝 Imports" @@ -29,7 +29,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "11a1bef0", + "id": "bdbf3ac0", "metadata": {}, "outputs": [], "source": [ @@ -52,7 +52,7 @@ } }, "cell_type": "markdown", - "id": "0e98543b", + "id": "a75ae054", "metadata": {}, "source": [ "## What is an Air Quality Sensor?\n", @@ -76,7 +76,7 @@ } }, "cell_type": "markdown", - "id": "2f9a9a4b", + "id": "f759bbc9", "metadata": {}, "source": [ "## 🌍 STEP 1: Pick your Air Quality Sensor\n", @@ -99,7 +99,7 @@ }, { "cell_type": "markdown", - "id": "c88a7f35", + "id": "d440d711", "metadata": {}, "source": [ "---" @@ -112,7 +112,7 @@ } }, "cell_type": "markdown", - "id": "0c985274", + "id": "1520e391", "metadata": {}, "source": [ "## 🌍 STEP 2: Download the Historical Air Quality \n", @@ -131,7 +131,7 @@ }, { "cell_type": "markdown", - "id": "a41c70b3", + "id": "9311072e", "metadata": {}, "source": [ "## 🌍 STEP 3: Change the Country, City, Street names to match your Sensor \n", @@ -142,7 +142,7 @@ { "cell_type": "code", "execution_count": 2, - "id": "b153aaed", + "id": "c5ac0627", "metadata": {}, "outputs": [], "source": [ @@ -166,7 +166,7 @@ }, { "cell_type": "markdown", - "id": "8933ca43", + "id": "1ccacadf", "metadata": {}, "source": [ "## 🌍 STEP 4: Read your CSV file into a DataFrame \n", @@ -176,12 +176,144 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "c3ff3228", + "execution_count": 3, + "id": "51431ee1", "metadata": { "tags": [] }, - "outputs": [], + "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", + "
datepm25pm10no2
02024-03-0146.023.03.0
12024-03-0259.018.04.0
22024-03-0348.0NaNNaN
32024-02-0122.033.010.0
42024-02-0222.019.06.0
...............
23012017-10-24NaNNaN5.0
23022017-10-25NaNNaN10.0
23032017-10-26NaNNaN14.0
23042017-10-27NaNNaN9.0
23052017-10-28NaNNaN4.0
\n", + "

2306 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " date pm25 pm10 no2\n", + "0 2024-03-01 46.0 23.0 3.0\n", + "1 2024-03-02 59.0 18.0 4.0\n", + "2 2024-03-03 48.0 NaN NaN\n", + "3 2024-02-01 22.0 33.0 10.0\n", + "4 2024-02-02 22.0 19.0 6.0\n", + "... ... ... ... ...\n", + "2301 2017-10-24 NaN NaN 5.0\n", + "2302 2017-10-25 NaN NaN 10.0\n", + "2303 2017-10-26 NaN NaN 14.0\n", + "2304 2017-10-27 NaN NaN 9.0\n", + "2305 2017-10-28 NaN NaN 4.0\n", + "\n", + "[2306 rows x 4 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df = pd.read_csv(csv_file, parse_dates=['date'], skipinitialspace=True)\n", "df" @@ -189,7 +321,7 @@ }, { "cell_type": "markdown", - "id": "f3017b00", + "id": "b8b7ad44", "metadata": {}, "source": [ "## Check the data types for the columns in your DataFrame" @@ -197,17 +329,35 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "d1123cc1", + "execution_count": 4, + "id": "b29d85d3", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 2306 entries, 0 to 2305\n", + "Data columns (total 4 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 2306 non-null datetime64[ns]\n", + " 1 pm25 2269 non-null float64 \n", + " 2 pm10 2269 non-null float64 \n", + " 3 no2 2280 non-null float64 \n", + "dtypes: datetime64[ns](1), float64(3)\n", + "memory usage: 72.2 KB\n" + ] + } + ], "source": [ "df.info()" ] }, { "cell_type": "markdown", - "id": "6c23f68d", + "id": "4a473a3a", "metadata": {}, "source": [ "## 🌍 STEP 5: Drop any rows with missing data \n", @@ -216,10 +366,142 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "e5225558", + "execution_count": 5, + "id": "81c49746", "metadata": {}, - "outputs": [], + "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", + "
datepm25pm10no2
02024-03-0146.023.03.0
12024-03-0259.018.04.0
32024-02-0122.033.010.0
42024-02-0222.019.06.0
52024-02-0312.025.08.0
...............
22632017-12-2514.04.06.0
22642017-12-2616.04.07.0
22652017-12-2710.020.06.0
22662017-12-2855.014.013.0
22672017-12-2942.06.09.0
\n", + "

2240 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " date pm25 pm10 no2\n", + "0 2024-03-01 46.0 23.0 3.0\n", + "1 2024-03-02 59.0 18.0 4.0\n", + "3 2024-02-01 22.0 33.0 10.0\n", + "4 2024-02-02 22.0 19.0 6.0\n", + "5 2024-02-03 12.0 25.0 8.0\n", + "... ... ... ... ...\n", + "2263 2017-12-25 14.0 4.0 6.0\n", + "2264 2017-12-26 16.0 4.0 7.0\n", + "2265 2017-12-27 10.0 20.0 6.0\n", + "2266 2017-12-28 55.0 14.0 13.0\n", + "2267 2017-12-29 42.0 6.0 9.0\n", + "\n", + "[2240 rows x 4 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df.dropna(inplace=True)\n", "df" @@ -227,7 +509,7 @@ }, { "cell_type": "markdown", - "id": "ae709030", + "id": "b89b1e70", "metadata": {}, "source": [ "## 🌍 STEP 6: Drop unnecessary columns and add country, city, street to the DataFrame \n", @@ -241,8 +523,8 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "a49f4963", + "execution_count": 6, + "id": "8c33be10", "metadata": {}, "outputs": [], "source": [ @@ -259,7 +541,7 @@ }, { "cell_type": "markdown", - "id": "27e34b6f", + "id": "310cc9d5", "metadata": {}, "source": [ "---" @@ -267,7 +549,7 @@ }, { "cell_type": "markdown", - "id": "48cc9fed", + "id": "057ebd1e", "metadata": { "tags": [] }, @@ -277,7 +559,7 @@ }, { "cell_type": "markdown", - "id": "cfffb4ad", + "id": "a060ef0a", "metadata": {}, "source": [ "## 🌍 STEP 7: Download the Historical Weather Data \n", @@ -298,10 +580,21 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "d60b7f77", + "execution_count": 7, + "id": "c0d2f9b1", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Coordinates 59.29701232910156°N 18.163265228271484°E\n", + "Elevation 18.0 m asl\n", + "Timezone None None\n", + "Timezone difference to GMT+0 0 s\n" + ] + } + ], "source": [ "earliest_aq_date = pd.Series.min(df_aq['date'])\n", "earliest_aq_date = earliest_aq_date.strftime('%Y-%m-%d')\n", @@ -312,17 +605,37 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "957eba1d", + "execution_count": 8, + "id": "0af37455", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Index: 2359 entries, 0 to 2358\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 2359 non-null datetime64[ns]\n", + " 1 temperature_2m_mean 2359 non-null float32 \n", + " 2 precipitation_sum 2359 non-null float32 \n", + " 3 wind_speed_10m_max 2359 non-null float32 \n", + " 4 wind_direction_10m_dominant 2359 non-null float32 \n", + " 5 city 2359 non-null object \n", + "dtypes: datetime64[ns](1), float32(4), object(1)\n", + "memory usage: 92.1+ KB\n" + ] + } + ], "source": [ "weather_df.info()" ] }, { "cell_type": "markdown", - "id": "83331cce", + "id": "7abfa5e6", "metadata": {}, "source": [ "## 🌍 STEP 8: Define Data Validation Rules \n", @@ -336,10 +649,21 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "0ae36ed4", + "execution_count": 9, + "id": "b3aeda64", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{\"kwargs\": {\"column\": \"pm25\", \"min_value\": -0.1, \"max_value\": 500.0, \"strict_min\": true}, \"expectation_type\": \"expect_column_min_to_be_between\", \"meta\": {}}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import great_expectations as ge\n", "aq_expectation_suite = ge.core.ExpectationSuite(\n", @@ -361,7 +685,7 @@ }, { "cell_type": "markdown", - "id": "e4801c29", + "id": "2f325912", "metadata": {}, "source": [ "## Expectations for Weather Data\n", @@ -370,8 +694,8 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "db0f29b0", + "execution_count": 10, + "id": "cafa5d56", "metadata": {}, "outputs": [], "source": [ @@ -398,7 +722,7 @@ }, { "cell_type": "markdown", - "id": "bdd9871a", + "id": "24fdc6eb", "metadata": {}, "source": [ "---" @@ -406,7 +730,7 @@ }, { "cell_type": "markdown", - "id": "cabbb3a9", + "id": "84165f28", "metadata": {}, "source": [ "### 🔮 STEP 9: Connect to Hopsworks and save the sensor country, city, street names as a secret" @@ -414,8 +738,8 @@ }, { "cell_type": "code", - "execution_count": 3, - "id": "8721ae31", + "execution_count": 11, + "id": "2221c5f2", "metadata": {}, "outputs": [ { @@ -439,7 +763,7 @@ }, { "cell_type": "markdown", - "id": "ed29bd35", + "id": "313c9413", "metadata": {}, "source": [ "#### Save country, city, street names as a secret\n", @@ -449,8 +773,8 @@ }, { "cell_type": "code", - "execution_count": 6, - "id": "d0c416f9", + "execution_count": 13, + "id": "2d28fbb0", "metadata": {}, "outputs": [ { @@ -458,7 +782,7 @@ "output_type": "stream", "text": [ "Connected. Call `.close()` to terminate connection gracefully.\n", - "SENSOR_LOCATION_JSON already exists\n" + "SENSOR_LOCATION_JSON already exists. If you want to update it, delete the secret in the Hopworks UI and re-run.\n" ] } ], @@ -479,9 +803,52 @@ " print(\"SENSOR_LOCATION_JSON already exists. If you want to update it, delete the secret in the Hopworks UI and re-run.\")" ] }, + { + "cell_type": "code", + "execution_count": 24, + "id": "9833fe82", + "metadata": {}, + "outputs": [ + { + "ename": "FeatureStoreException", + "evalue": "Statistics not supported for this Feature Group type", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRestAPIError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_store.py\u001b[0m in \u001b[0;36mget_or_create_spine_group\u001b[0;34m(self, name, version, description, primary_key, event_time, features, dataframe)\u001b[0m\n\u001b[1;32m 1102\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1103\u001b[0;31m spine = self._feature_group_api.get(\n\u001b[0m\u001b[1;32m 1104\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeature_group_api\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFeatureGroupApi\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSPINE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_group_api.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, feature_store_id, name, version, fg_type)\u001b[0m\n\u001b[1;32m 81\u001b[0m \u001b[0mquery_params\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mversion\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m\"version\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mversion\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 82\u001b[0;31m \u001b[0mjson_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_client\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_send_request\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"GET\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpath_params\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mquery_params\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 83\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/decorators.py\u001b[0m in \u001b[0;36mif_connected\u001b[0;34m(inst, *args, **kwargs)\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mNoHopsworksConnectionError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 35\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minst\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 36\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/client/base.py\u001b[0m in \u001b[0;36m_send_request\u001b[0;34m(self, method, path_params, query_params, headers, data, stream, files)\u001b[0m\n\u001b[1;32m 178\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[0;34m//\u001b[0m \u001b[0;36m100\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 179\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mRestAPIError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 180\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mRestAPIError\u001b[0m: Metadata operation error: (url: https://hopsworks.glassfish.service.consul:8182/hopsworks-api/api/project/5240/featurestores/5188/featuregroups/air_spine). Server response: \nHTTP code: 404, HTTP reason: Not Found, body: b'{\"errorCode\":270009,\"usrMsg\":\"feature group name: air_spine feature group version: 1\",\"errorMsg\":\"Featuregroup wasn\\'t found.\"}', error code: 270009, error msg: Featuregroup wasn't found., user msg: feature group name: air_spine feature group version: 1", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mFeatureStoreException\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m spine_group = fs.get_or_create_spine_group(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"air_spine\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mversion\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mdescription\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"AQI\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprimary_key\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'country'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'street'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'date'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/usage.py\u001b[0m in \u001b[0;36mwrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 196\u001b[0m \u001b[0;31m# Disable usage AFTER import hsfs, return function itself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0m_is_enabled\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 198\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 199\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[0mstart_time\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mperf_counter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_store.py\u001b[0m in \u001b[0;36mget_or_create_spine_group\u001b[0;34m(self, name, version, description, primary_key, event_time, features, dataframe)\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m404\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1113\u001b[0m ):\n\u001b[0;32m-> 1114\u001b[0;31m spine = feature_group.SpineGroup(\n\u001b[0m\u001b[1;32m 1115\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1116\u001b[0m \u001b[0mversion\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mversion\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_group.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, storage_connector, query, data_format, path, options, name, version, description, primary_key, featurestore_id, featurestore_name, created, creator, id, features, location, statistics_config, event_time, expectation_suite, online_enabled, href, online_topic_name, topic_name, spine, dataframe, deprecated, **kwargs)\u001b[0m\n\u001b[1;32m 3746\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3747\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprimary_key\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mprimary_key\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3748\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatistics_config\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstatistics_config\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3749\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_features\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfeatures\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3750\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_group.py\u001b[0m in \u001b[0;36mstatistics_config\u001b[0;34m(self, statistics_config)\u001b[0m\n\u001b[1;32m 1476\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mstatistics_config\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetter\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1477\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mstatistics_config\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstatistics_config\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1478\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_check_statistics_support\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# raises an error if stats not supported\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1479\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstatistics_config\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mStatisticsConfig\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1480\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_statistics_config\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstatistics_config\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_group.py\u001b[0m in \u001b[0;36m_check_statistics_support\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1863\u001b[0m \u001b[0;34m\"\"\"Check for statistics support on the current Feature Group type\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1864\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_are_statistics_supported\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1865\u001b[0;31m raise FeatureStoreException(\n\u001b[0m\u001b[1;32m 1866\u001b[0m \u001b[0;34m\"Statistics not supported for this Feature Group type\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1867\u001b[0m )\n", + "\u001b[0;31mFeatureStoreException\u001b[0m: Statistics not supported for this Feature Group type" + ] + } + ], + "source": [ + "\n", + "spine_group = fs.get_or_create_spine_group(\n", + " name=\"air_spine\",\n", + " version=1,\n", + " description=\"AQI\",\n", + " primary_key=['country','street','date'],\n", + " event_time=\"date\",\n", + " dataframe=df_aq,\n", + "# statistics_config=None,\n", + " )" + ] + }, { "cell_type": "markdown", - "id": "41f3af8a", + "id": "e6d650db", "metadata": {}, "source": [ "### 🔮 STEP 10: Create the Feature Groups and insert the DataFrames in them " @@ -489,7 +856,7 @@ }, { "cell_type": "markdown", - "id": "af47a547", + "id": "14a74373", "metadata": {}, "source": [ "### 🌫 Air Quality Data\n", @@ -503,7 +870,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a96b343a", + "id": "6fc741e5", "metadata": { "scrolled": true, "tags": [] @@ -524,7 +891,7 @@ }, { "cell_type": "markdown", - "id": "b473dc63", + "id": "10a18825", "metadata": {}, "source": [ "#### Insert the DataFrame into the Feature Group" @@ -533,16 +900,16 @@ { "cell_type": "code", "execution_count": null, - "id": "0d2122d8", + "id": "20a8250c", "metadata": {}, "outputs": [], "source": [ - "air_quality_fg.insert(df_air_quality)" + "air_quality_fg.insert(df_aq)" ] }, { "cell_type": "markdown", - "id": "84924af9", + "id": "174c5ed6", "metadata": {}, "source": [ "#### Enter a description for each feature in the Feature Group" @@ -551,7 +918,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8fc9b662", + "id": "dbcd4194", "metadata": {}, "outputs": [], "source": [ @@ -564,7 +931,7 @@ }, { "cell_type": "markdown", - "id": "1e87c468", + "id": "af03ab21", "metadata": {}, "source": [ "### 🌦 Weather Data\n", @@ -578,7 +945,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6a2070d1", + "id": "ba02ebe3", "metadata": {}, "outputs": [], "source": [ @@ -595,7 +962,7 @@ }, { "cell_type": "markdown", - "id": "5566c3be", + "id": "0bb94e9c", "metadata": {}, "source": [ "#### Insert the DataFrame into the Feature Group" @@ -604,7 +971,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6623b873", + "id": "75b25c7e", "metadata": { "tags": [] }, @@ -616,7 +983,7 @@ }, { "cell_type": "markdown", - "id": "fcd1630e", + "id": "4cd7fd2b", "metadata": {}, "source": [ "#### Enter a description for each feature in the Feature Group" @@ -625,7 +992,7 @@ { "cell_type": "code", "execution_count": null, - "id": "29dc9db6", + "id": "4ae58684", "metadata": {}, "outputs": [], "source": [ @@ -639,7 +1006,7 @@ }, { "cell_type": "markdown", - "id": "df0e9322", + "id": "2b4eb465", "metadata": {}, "source": [ "## ⏭️ **Next:** Part 02: Daily Feature Pipeline \n", @@ -648,7 +1015,7 @@ }, { "cell_type": "markdown", - "id": "dc76f6fb", + "id": "a2bbab3c", "metadata": {}, "source": [ "## ⏭️ **Exercises:** \n", @@ -660,7 +1027,7 @@ }, { "cell_type": "markdown", - "id": "6742390c", + "id": "1e1e00d6", "metadata": {}, "source": [ "---" diff --git a/notebooks/ch03/4_air_quality_batch_inference.ipynb b/notebooks/ch03/4_air_quality_batch_inference.ipynb index 7b482676..390f7a9f 100644 --- a/notebooks/ch03/4_air_quality_batch_inference.ipynb +++ b/notebooks/ch03/4_air_quality_batch_inference.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "9651412e", + "id": "a90be666", "metadata": {}, "source": [ "# **Air Quality** - Part 04: Batch Inference\n", @@ -16,7 +16,7 @@ }, { "cell_type": "markdown", - "id": "efe26f52", + "id": "6ccb5a6d", "metadata": {}, "source": [ "## 📝 Imports" @@ -25,9 +25,17 @@ { "cell_type": "code", "execution_count": 1, - "id": "8023fb9f", + "id": "b6843d55", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-03-21 20:35:24,101 INFO: generated new fontManager\n" + ] + } + ], "source": [ "import datetime\n", "import pandas as pd\n", @@ -39,18 +47,18 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "ec73d2f3", + "execution_count": 23, + "id": "56eb74ec", "metadata": {}, "outputs": [], "source": [ - "today = datetime.date.today()\n", + "today = datetime.datetime.now() #date.today()\n", "tomorrow = today + datetime.timedelta(days = 1)" ] }, { "cell_type": "markdown", - "id": "1b538aa1", + "id": "90180026", "metadata": {}, "source": [ "## 📡 Connect to Hopsworks Feature Store " @@ -59,7 +67,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "1e86f859", + "id": "e076e59b", "metadata": {}, "outputs": [ { @@ -90,7 +98,7 @@ }, { "cell_type": "markdown", - "id": "c720336b", + "id": "8d475fd1", "metadata": {}, "source": [ "## ⚙️ Feature View Retrieval\n" @@ -99,19 +107,19 @@ { "cell_type": "code", "execution_count": 4, - "id": "01bbe5a5", + "id": "19c9cb3a", "metadata": {}, "outputs": [], "source": [ - "feature_view = fs.get_feature_view(\n", - " name='air_quality_fv',\n", - " version=1,\n", - ")" + "# feature_view = fs.get_feature_view(\n", + "# name='air_quality_fv',\n", + "# version=1,\n", + "# )" ] }, { "cell_type": "markdown", - "id": "62630eb4", + "id": "2ad55ddb", "metadata": {}, "source": [ "## 🪝 Download the model from Model Registry" @@ -120,7 +128,7 @@ { "cell_type": "code", "execution_count": 5, - "id": "9ca3c5f9", + "id": "78afbaa6", "metadata": {}, "outputs": [ { @@ -147,7 +155,7 @@ { "cell_type": "code", "execution_count": 6, - "id": "06129323", + "id": "9922d3cd", "metadata": {}, "outputs": [ { @@ -210,7 +218,7 @@ }, { "cell_type": "markdown", - "id": "ba36ed5c", + "id": "8b1678b0", "metadata": {}, "source": [ "## ✨ Get Weather Forecast Features with Feature View \n", @@ -219,213 +227,17 @@ }, { "cell_type": "code", - "execution_count": 7, - "id": "e6cc4b14", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.47s) \n" - ] - } - ], - "source": [ - "weather_fg = fs.get_feature_group(\n", - " name='weather',\n", - " version=1,\n", - ")\n", - "\n", - "f = weather_fg.read()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c91dbcd6", + "execution_count": 25, + "id": "496c66bf", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.53s) \n" + "Finished: Reading data from Hopsworks, using ArrowFlight (0.44s) \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", - "
datepm25countrycitystreet
14652017-10-04 00:00:00+00:0013.0swedenstockholmstockholm-hornsgatan-108-gata
10762017-10-05 00:00:00+00:009.0swedenstockholmstockholm-hornsgatan-108-gata
19172017-10-06 00:00:00+00:008.0swedenstockholmstockholm-hornsgatan-108-gata
19412017-10-07 00:00:00+00:0013.0swedenstockholmstockholm-hornsgatan-108-gata
13552017-10-08 00:00:00+00:008.0swedenstockholmstockholm-hornsgatan-108-gata
..................
22772024-03-13 00:00:00+00:0051.0swedenstockholmstockholm-hornsgatan-108-gata
22782024-03-14 00:00:00+00:0041.0swedenstockholmstockholm-hornsgatan-108-gata
22792024-03-15 00:00:00+00:0054.0swedenstockholmstockholm-hornsgatan-108-gata
22802024-03-16 00:00:00+00:0045.0swedenstockholmstockholm-hornsgatan-108-gata
22812024-03-19 00:00:00+00:0017.0swedenstockholmstockholm-hornsgatan-108-gata
\n", - "

2282 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " date pm25 country city \\\n", - "1465 2017-10-04 00:00:00+00:00 13.0 sweden stockholm \n", - "1076 2017-10-05 00:00:00+00:00 9.0 sweden stockholm \n", - "1917 2017-10-06 00:00:00+00:00 8.0 sweden stockholm \n", - "1941 2017-10-07 00:00:00+00:00 13.0 sweden stockholm \n", - "1355 2017-10-08 00:00:00+00:00 8.0 sweden stockholm \n", - "... ... ... ... ... \n", - "2277 2024-03-13 00:00:00+00:00 51.0 sweden stockholm \n", - "2278 2024-03-14 00:00:00+00:00 41.0 sweden stockholm \n", - "2279 2024-03-15 00:00:00+00:00 54.0 sweden stockholm \n", - "2280 2024-03-16 00:00:00+00:00 45.0 sweden stockholm \n", - "2281 2024-03-19 00:00:00+00:00 17.0 sweden stockholm \n", - "\n", - " street \n", - "1465 stockholm-hornsgatan-108-gata \n", - "1076 stockholm-hornsgatan-108-gata \n", - "1917 stockholm-hornsgatan-108-gata \n", - "1941 stockholm-hornsgatan-108-gata \n", - "1355 stockholm-hornsgatan-108-gata \n", - "... ... \n", - "2277 stockholm-hornsgatan-108-gata \n", - "2278 stockholm-hornsgatan-108-gata \n", - "2279 stockholm-hornsgatan-108-gata \n", - "2280 stockholm-hornsgatan-108-gata \n", - "2281 stockholm-hornsgatan-108-gata \n", - "\n", - "[2282 rows x 5 columns]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "air_quality_fg = fs.get_feature_group(\n", - " name='air_quality',\n", - " version=1,\n", - ")\n", - "a = air_quality_fg.read()\n", - "a = a.sort_values(by=['date'])\n", - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "b3608c12", - "metadata": {}, - "outputs": [ { "data": { "text/html": [ @@ -457,84 +269,84 @@ " \n", " \n", " \n", - " 2359\n", - " 2024-03-20 00:00:00+00:00\n", - " 2.85\n", + " 0\n", + " 2024-03-22 00:00:00+00:00\n", + " 8.45\n", " 0.1\n", - " 9.178235\n", - " 191.309891\n", + " 24.066206\n", + " 248.039383\n", " stockholm\n", " \n", " \n", - " 2360\n", - " 2024-03-21 00:00:00+00:00\n", - " 4.50\n", - " 0.1\n", - " 6.369050\n", - " 312.709381\n", + " 1\n", + " 2024-03-23 00:00:00+00:00\n", + " 7.35\n", + " 0.0\n", + " 13.004921\n", + " 265.236450\n", " stockholm\n", " \n", " \n", - " 2361\n", - " 2024-03-22 00:00:00+00:00\n", - " 6.95\n", - " 0.0\n", - " 16.418526\n", - " 217.875046\n", + " 2\n", + " 2024-03-24 00:00:00+00:00\n", + " 5.35\n", + " 0.6\n", + " 6.608722\n", + " 60.642342\n", " stockholm\n", " \n", " \n", - " 2362\n", - " 2024-03-23 00:00:00+00:00\n", - " 8.60\n", + " 3\n", + " 2024-03-25 00:00:00+00:00\n", + " 2.80\n", " 0.0\n", - " 15.978486\n", - " 255.650635\n", + " 1.440000\n", + " 270.000000\n", " stockholm\n", " \n", " \n", - " 2363\n", - " 2024-03-24 00:00:00+00:00\n", - " 9.00\n", - " 0.0\n", - " 4.843305\n", - " 138.012863\n", + " 4\n", + " 2024-03-27 00:00:00+00:00\n", + " 1.90\n", + " 0.4\n", + " 12.727921\n", + " 28.739704\n", " stockholm\n", " \n", " \n", - " 2364\n", - " 2024-03-25 00:00:00+00:00\n", - " 4.25\n", - " 0.0\n", - " 8.854829\n", - " 153.435013\n", + " 5\n", + " 2024-03-26 00:00:00+00:00\n", + " 3.25\n", + " 0.1\n", + " 11.841756\n", + " 160.463257\n", " stockholm\n", " \n", " \n", - " 2366\n", - " 2024-03-26 00:00:00+00:00\n", - " 3.65\n", + " 6\n", + " 2024-03-28 00:00:00+00:00\n", + " 3.35\n", " 0.0\n", - " 13.661038\n", - " 161.564957\n", + " 22.702845\n", + " 345.302643\n", " stockholm\n", " \n", " \n", - " 2365\n", - " 2024-03-27 00:00:00+00:00\n", - " 7.80\n", + " 7\n", + " 2024-03-29 00:00:00+00:00\n", + " 4.65\n", " 0.0\n", - " 22.104116\n", - " 142.943390\n", + " 15.141414\n", + " 18.004259\n", " stockholm\n", " \n", " \n", - " 2367\n", - " 2024-03-28 00:00:00+00:00\n", - " 7.45\n", - " 0.1\n", - " 14.578890\n", - " 147.094757\n", + " 8\n", + " 2024-03-30 00:00:00+00:00\n", + " 4.30\n", + " 0.0\n", + " 9.659814\n", + " 63.435013\n", " stockholm\n", " \n", " \n", @@ -542,74 +354,67 @@ "" ], "text/plain": [ - " date temperature_2m_mean precipitation_sum \\\n", - "2359 2024-03-20 00:00:00+00:00 2.85 0.1 \n", - "2360 2024-03-21 00:00:00+00:00 4.50 0.1 \n", - "2361 2024-03-22 00:00:00+00:00 6.95 0.0 \n", - "2362 2024-03-23 00:00:00+00:00 8.60 0.0 \n", - "2363 2024-03-24 00:00:00+00:00 9.00 0.0 \n", - "2364 2024-03-25 00:00:00+00:00 4.25 0.0 \n", - "2366 2024-03-26 00:00:00+00:00 3.65 0.0 \n", - "2365 2024-03-27 00:00:00+00:00 7.80 0.0 \n", - "2367 2024-03-28 00:00:00+00:00 7.45 0.1 \n", + " date temperature_2m_mean precipitation_sum \\\n", + "0 2024-03-22 00:00:00+00:00 8.45 0.1 \n", + "1 2024-03-23 00:00:00+00:00 7.35 0.0 \n", + "2 2024-03-24 00:00:00+00:00 5.35 0.6 \n", + "3 2024-03-25 00:00:00+00:00 2.80 0.0 \n", + "4 2024-03-27 00:00:00+00:00 1.90 0.4 \n", + "5 2024-03-26 00:00:00+00:00 3.25 0.1 \n", + "6 2024-03-28 00:00:00+00:00 3.35 0.0 \n", + "7 2024-03-29 00:00:00+00:00 4.65 0.0 \n", + "8 2024-03-30 00:00:00+00:00 4.30 0.0 \n", "\n", - " wind_speed_10m_max wind_direction_10m_dominant city \n", - "2359 9.178235 191.309891 stockholm \n", - "2360 6.369050 312.709381 stockholm \n", - "2361 16.418526 217.875046 stockholm \n", - "2362 15.978486 255.650635 stockholm \n", - "2363 4.843305 138.012863 stockholm \n", - "2364 8.854829 153.435013 stockholm \n", - "2366 13.661038 161.564957 stockholm \n", - "2365 22.104116 142.943390 stockholm \n", - "2367 14.578890 147.094757 stockholm " + " wind_speed_10m_max wind_direction_10m_dominant city \n", + "0 24.066206 248.039383 stockholm \n", + "1 13.004921 265.236450 stockholm \n", + "2 6.608722 60.642342 stockholm \n", + "3 1.440000 270.000000 stockholm \n", + "4 12.727921 28.739704 stockholm \n", + "5 11.841756 160.463257 stockholm \n", + "6 22.702845 345.302643 stockholm \n", + "7 15.141414 18.004259 stockholm \n", + "8 9.659814 63.435013 stockholm " ] }, - "execution_count": 9, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "batch_data = f[f['date'] > str(today)]\n", - "batch_data = batch_data.sort_values(by=['date'])\n", + "weather_fg = fs.get_feature_group(\n", + " name='weather',\n", + " version=1,\n", + ")\n", + "\n", + "batch_data = weather_fg.filter(weather_fg.date >= today).read()\n", "batch_data" ] }, { "cell_type": "code", - "execution_count": 10, - "id": "09a2d087", + "execution_count": null, + "id": "ae964360", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Index: 9 entries, 2359 to 2367\n", - "Data columns (total 6 columns):\n", - " # Column Non-Null Count Dtype \n", - "--- ------ -------------- ----- \n", - " 0 date 9 non-null datetime64[us, UTC]\n", - " 1 temperature_2m_mean 9 non-null float32 \n", - " 2 precipitation_sum 9 non-null float32 \n", - " 3 wind_speed_10m_max 9 non-null float32 \n", - " 4 wind_direction_10m_dominant 9 non-null float32 \n", - " 5 city 9 non-null object \n", - "dtypes: datetime64[us, UTC](1), float32(4), object(1)\n", - "memory usage: 360.0+ bytes\n" - ] - } - ], + "outputs": [], "source": [ - "batch_data.info()" + "spine_df = pd.Dataframe()\n", + "\n", + "spine_group = fs.get_or_create_spine_group(\n", + " name=\"sales\",\n", + " version=1,\n", + " description=\"Physical shop sales features\",\n", + " primary_key=['ss_store_sk'],\n", + " event_time='sale_date',\n", + " dataframe=spine_df\n", + " )" ] }, { "cell_type": "code", - "execution_count": 11, - "id": "9e8e7e23", + "execution_count": null, + "id": "da77789a", "metadata": {}, "outputs": [], "source": [ @@ -620,7 +425,7 @@ }, { "cell_type": "markdown", - "id": "6aa7eac3", + "id": "f4ec4080", "metadata": {}, "source": [ "### 🤖 Making the predictions" @@ -628,8 +433,8 @@ }, { "cell_type": "code", - "execution_count": 12, - "id": "7f514d7b", + "execution_count": 26, + "id": "e0f07cd0", "metadata": {}, "outputs": [ { @@ -664,135 +469,124 @@ " \n", " \n", " \n", - " 2359\n", - " 2024-03-20 00:00:00+00:00\n", - " 2.85\n", + " 0\n", + " 2024-03-22 00:00:00+00:00\n", + " 8.45\n", " 0.1\n", - " 9.178235\n", - " 191.309891\n", + " 24.066206\n", + " 248.039383\n", " stockholm\n", - " 45.177952\n", + " 18.452847\n", " \n", " \n", - " 2360\n", - " 2024-03-21 00:00:00+00:00\n", - " 4.50\n", - " 0.1\n", - " 6.369050\n", - " 312.709381\n", + " 1\n", + " 2024-03-23 00:00:00+00:00\n", + " 7.35\n", + " 0.0\n", + " 13.004921\n", + " 265.236450\n", " stockholm\n", - " 34.422592\n", + " 21.591589\n", " \n", " \n", - " 2361\n", - " 2024-03-22 00:00:00+00:00\n", - " 6.95\n", - " 0.0\n", - " 16.418526\n", - " 217.875046\n", + " 2\n", + " 2024-03-24 00:00:00+00:00\n", + " 5.35\n", + " 0.6\n", + " 6.608722\n", + " 60.642342\n", " stockholm\n", - " 29.082672\n", + " 46.818920\n", " \n", " \n", - " 2362\n", - " 2024-03-23 00:00:00+00:00\n", - " 8.60\n", + " 3\n", + " 2024-03-25 00:00:00+00:00\n", + " 2.80\n", " 0.0\n", - " 15.978486\n", - " 255.650635\n", + " 1.440000\n", + " 270.000000\n", " stockholm\n", - " 31.080534\n", + " 35.114464\n", " \n", " \n", - " 2363\n", - " 2024-03-24 00:00:00+00:00\n", - " 9.00\n", - " 0.0\n", - " 4.843305\n", - " 138.012863\n", + " 4\n", + " 2024-03-27 00:00:00+00:00\n", + " 1.90\n", + " 0.4\n", + " 12.727921\n", + " 28.739704\n", " stockholm\n", - " 41.252338\n", + " 25.125097\n", " \n", " \n", - " 2364\n", - " 2024-03-25 00:00:00+00:00\n", - " 4.25\n", - " 0.0\n", - " 8.854829\n", - " 153.435013\n", + " 5\n", + " 2024-03-26 00:00:00+00:00\n", + " 3.25\n", + " 0.1\n", + " 11.841756\n", + " 160.463257\n", " stockholm\n", - " 58.888611\n", + " 47.233841\n", " \n", " \n", - " 2366\n", - " 2024-03-26 00:00:00+00:00\n", - " 3.65\n", + " 6\n", + " 2024-03-28 00:00:00+00:00\n", + " 3.35\n", " 0.0\n", - " 13.661038\n", - " 161.564957\n", + " 22.702845\n", + " 345.302643\n", " stockholm\n", - " 47.218639\n", + " 17.074268\n", " \n", " \n", - " 2365\n", - " 2024-03-27 00:00:00+00:00\n", - " 7.80\n", + " 7\n", + " 2024-03-29 00:00:00+00:00\n", + " 4.65\n", " 0.0\n", - " 22.104116\n", - " 142.943390\n", + " 15.141414\n", + " 18.004259\n", " stockholm\n", - " 39.180153\n", + " 37.657612\n", " \n", " \n", - " 2367\n", - " 2024-03-28 00:00:00+00:00\n", - " 7.45\n", - " 0.1\n", - " 14.578890\n", - " 147.094757\n", + " 8\n", + " 2024-03-30 00:00:00+00:00\n", + " 4.30\n", + " 0.0\n", + " 9.659814\n", + " 63.435013\n", " stockholm\n", - " 39.908024\n", + " 44.778652\n", " \n", " \n", "\n", "" ], "text/plain": [ - " date temperature_2m_mean precipitation_sum \\\n", - "2359 2024-03-20 00:00:00+00:00 2.85 0.1 \n", - "2360 2024-03-21 00:00:00+00:00 4.50 0.1 \n", - "2361 2024-03-22 00:00:00+00:00 6.95 0.0 \n", - "2362 2024-03-23 00:00:00+00:00 8.60 0.0 \n", - "2363 2024-03-24 00:00:00+00:00 9.00 0.0 \n", - "2364 2024-03-25 00:00:00+00:00 4.25 0.0 \n", - "2366 2024-03-26 00:00:00+00:00 3.65 0.0 \n", - "2365 2024-03-27 00:00:00+00:00 7.80 0.0 \n", - "2367 2024-03-28 00:00:00+00:00 7.45 0.1 \n", - "\n", - " wind_speed_10m_max wind_direction_10m_dominant city \\\n", - "2359 9.178235 191.309891 stockholm \n", - "2360 6.369050 312.709381 stockholm \n", - "2361 16.418526 217.875046 stockholm \n", - "2362 15.978486 255.650635 stockholm \n", - "2363 4.843305 138.012863 stockholm \n", - "2364 8.854829 153.435013 stockholm \n", - "2366 13.661038 161.564957 stockholm \n", - "2365 22.104116 142.943390 stockholm \n", - "2367 14.578890 147.094757 stockholm \n", + " date temperature_2m_mean precipitation_sum \\\n", + "0 2024-03-22 00:00:00+00:00 8.45 0.1 \n", + "1 2024-03-23 00:00:00+00:00 7.35 0.0 \n", + "2 2024-03-24 00:00:00+00:00 5.35 0.6 \n", + "3 2024-03-25 00:00:00+00:00 2.80 0.0 \n", + "4 2024-03-27 00:00:00+00:00 1.90 0.4 \n", + "5 2024-03-26 00:00:00+00:00 3.25 0.1 \n", + "6 2024-03-28 00:00:00+00:00 3.35 0.0 \n", + "7 2024-03-29 00:00:00+00:00 4.65 0.0 \n", + "8 2024-03-30 00:00:00+00:00 4.30 0.0 \n", "\n", - " predicted_pm25 \n", - "2359 45.177952 \n", - "2360 34.422592 \n", - "2361 29.082672 \n", - "2362 31.080534 \n", - "2363 41.252338 \n", - "2364 58.888611 \n", - "2366 47.218639 \n", - "2365 39.180153 \n", - "2367 39.908024 " + " wind_speed_10m_max wind_direction_10m_dominant city predicted_pm25 \n", + "0 24.066206 248.039383 stockholm 18.452847 \n", + "1 13.004921 265.236450 stockholm 21.591589 \n", + "2 6.608722 60.642342 stockholm 46.818920 \n", + "3 1.440000 270.000000 stockholm 35.114464 \n", + "4 12.727921 28.739704 stockholm 25.125097 \n", + "5 11.841756 160.463257 stockholm 47.233841 \n", + "6 22.702845 345.302643 stockholm 17.074268 \n", + "7 15.141414 18.004259 stockholm 37.657612 \n", + "8 9.659814 63.435013 stockholm 44.778652 " ] }, - "execution_count": 12, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -805,8 +599,8 @@ }, { "cell_type": "code", - "execution_count": 13, - "id": "e0811662", + "execution_count": 27, + "id": "b182d147", "metadata": {}, "outputs": [ { @@ -814,7 +608,7 @@ "output_type": "stream", "text": [ "\n", - "Index: 9 entries, 2359 to 2367\n", + "RangeIndex: 9 entries, 0 to 8\n", "Data columns (total 7 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", @@ -826,7 +620,7 @@ " 5 city 9 non-null object \n", " 6 predicted_pm25 9 non-null float32 \n", "dtypes: datetime64[us, UTC](1), float32(5), object(1)\n", - "memory usage: 396.0+ bytes\n" + "memory usage: 452.0+ bytes\n" ] } ], @@ -836,7 +630,7 @@ }, { "cell_type": "markdown", - "id": "5705ca86", + "id": "c0aefef5", "metadata": {}, "source": [ "### 🤖 Saving the predictions (for monitoring) to a Feature Group" @@ -844,216 +638,10 @@ }, { "cell_type": "code", - "execution_count": 14, - "id": "67765a94", + "execution_count": null, + "id": "9cf01f8b", "metadata": {}, - "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", - "
datetemperature_2m_meanprecipitation_sumwind_speed_10m_maxwind_direction_10m_dominantcitypredicted_pm25streetcountrydays_before_forecast_day
23592024-03-20 00:00:00+00:002.850.19.178235191.309891stockholm45.177952stockholm-hornsgatan-108-gatasweden1
23602024-03-21 00:00:00+00:004.500.16.369050312.709381stockholm34.422592stockholm-hornsgatan-108-gatasweden2
23612024-03-22 00:00:00+00:006.950.016.418526217.875046stockholm29.082672stockholm-hornsgatan-108-gatasweden3
23622024-03-23 00:00:00+00:008.600.015.978486255.650635stockholm31.080534stockholm-hornsgatan-108-gatasweden4
23632024-03-24 00:00:00+00:009.000.04.843305138.012863stockholm41.252338stockholm-hornsgatan-108-gatasweden5
23642024-03-25 00:00:00+00:004.250.08.854829153.435013stockholm58.888611stockholm-hornsgatan-108-gatasweden6
23662024-03-26 00:00:00+00:003.650.013.661038161.564957stockholm47.218639stockholm-hornsgatan-108-gatasweden7
23652024-03-27 00:00:00+00:007.800.022.104116142.943390stockholm39.180153stockholm-hornsgatan-108-gatasweden8
23672024-03-28 00:00:00+00:007.450.114.578890147.094757stockholm39.908024stockholm-hornsgatan-108-gatasweden9
\n", - "
" - ], - "text/plain": [ - " date temperature_2m_mean precipitation_sum \\\n", - "2359 2024-03-20 00:00:00+00:00 2.85 0.1 \n", - "2360 2024-03-21 00:00:00+00:00 4.50 0.1 \n", - "2361 2024-03-22 00:00:00+00:00 6.95 0.0 \n", - "2362 2024-03-23 00:00:00+00:00 8.60 0.0 \n", - "2363 2024-03-24 00:00:00+00:00 9.00 0.0 \n", - "2364 2024-03-25 00:00:00+00:00 4.25 0.0 \n", - "2366 2024-03-26 00:00:00+00:00 3.65 0.0 \n", - "2365 2024-03-27 00:00:00+00:00 7.80 0.0 \n", - "2367 2024-03-28 00:00:00+00:00 7.45 0.1 \n", - "\n", - " wind_speed_10m_max wind_direction_10m_dominant city \\\n", - "2359 9.178235 191.309891 stockholm \n", - "2360 6.369050 312.709381 stockholm \n", - "2361 16.418526 217.875046 stockholm \n", - "2362 15.978486 255.650635 stockholm \n", - "2363 4.843305 138.012863 stockholm \n", - "2364 8.854829 153.435013 stockholm \n", - "2366 13.661038 161.564957 stockholm \n", - "2365 22.104116 142.943390 stockholm \n", - "2367 14.578890 147.094757 stockholm \n", - "\n", - " predicted_pm25 street country \\\n", - "2359 45.177952 stockholm-hornsgatan-108-gata sweden \n", - "2360 34.422592 stockholm-hornsgatan-108-gata sweden \n", - "2361 29.082672 stockholm-hornsgatan-108-gata sweden \n", - "2362 31.080534 stockholm-hornsgatan-108-gata sweden \n", - "2363 41.252338 stockholm-hornsgatan-108-gata sweden \n", - "2364 58.888611 stockholm-hornsgatan-108-gata sweden \n", - "2366 47.218639 stockholm-hornsgatan-108-gata sweden \n", - "2365 39.180153 stockholm-hornsgatan-108-gata sweden \n", - "2367 39.908024 stockholm-hornsgatan-108-gata sweden \n", - "\n", - " days_before_forecast_day \n", - "2359 1 \n", - "2360 2 \n", - "2361 3 \n", - "2362 4 \n", - "2363 5 \n", - "2364 6 \n", - "2366 7 \n", - "2365 8 \n", - "2367 9 " - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "batch_data['street'] = street\n", "batch_data['city'] = city\n", @@ -1065,41 +653,17 @@ }, { "cell_type": "code", - "execution_count": 15, - "id": "e2a4496b", + "execution_count": null, + "id": "2ca4225c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Index: 9 entries, 2359 to 2367\n", - "Data columns (total 10 columns):\n", - " # Column Non-Null Count Dtype \n", - "--- ------ -------------- ----- \n", - " 0 date 9 non-null datetime64[us, UTC]\n", - " 1 temperature_2m_mean 9 non-null float32 \n", - " 2 precipitation_sum 9 non-null float32 \n", - " 3 wind_speed_10m_max 9 non-null float32 \n", - " 4 wind_direction_10m_dominant 9 non-null float32 \n", - " 5 city 9 non-null object \n", - " 6 predicted_pm25 9 non-null float32 \n", - " 7 street 9 non-null object \n", - " 8 country 9 non-null object \n", - " 9 days_before_forecast_day 9 non-null int64 \n", - "dtypes: datetime64[us, UTC](1), float32(5), int64(1), object(3)\n", - "memory usage: 612.0+ bytes\n" - ] - } - ], + "outputs": [], "source": [ "batch_data.info()" ] }, { "cell_type": "markdown", - "id": "74d9fc28", + "id": "02065bbf", "metadata": {}, "source": [ "### Create Forecast Graph\n", @@ -1109,21 +673,10 @@ }, { "cell_type": "code", - "execution_count": 16, - "id": "d0d812c9", + "execution_count": null, + "id": "c7cb38dd", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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AOAQSjcAAAAAAA6hdAMAAAAA4BBKNwAAAAAADqF0AwAAAADgEEo3AABoUVVVVW6PgGYoLi52ewQ0w4EDB7R//363x0ATtm3bppdfftntMdBGUbottHv3bq1atUrvv/++ysrK3B4HjaisrFQoFHJ7DDRh//79+vLLL7Vy5Uq3R0ETdu7cqffee0+vvfaadu/e7fY4aMQXX3yhu+66S7m5uW6PgpNYt26dhgwZok2bNrk9Ck5iw4YNGj16tJYsWcKLJG1YXl6ehg8frueff97tUXASW7Zs0Zw5c3T//ffr1VdfbdV/m9Jtmby8PGVnZ+v222/XxRdfrIsvvljz5s1zeyycID8/X5MnT9bKlStljHF7HDRi48aNuvjii3X11Vdr1KhRuuGGG3hS00bVPvGcPXu2brzxRt10000qKipyeyycoKqqSvfdd59ef/11vfDCC1qzZk34On4Xth3r16/XqFGjNHHiRJ155pmSyKctKigo0JgxYzR+/HhNmDBBqampbo+EBqxfv17nnnuuLrjgAn311Vf685//7PZIaMCGDRs0atQorV69Wm+//baef/55vfPOO63271O6LXLgwAFdf/31mjRpkt555x0VFhZq0KBBeuONN/TTn/7U7fFQo7CwUJdffrneeOMNTZ8+XZ999hlPZtqggoICXXjhhbr00kv1yiuv6JNPPtHbb7+tZ5991u3RcIIvvvhCF110kW644QYtWbJEW7Zs0QcffKDVq1e7PRpOEBMToy5duigzM1Pr1q3TM888o1WrVkmSPB6PJLEHkMs2btyoc889Vz//+c/1+OOPS5KOHDmirVu3ujwZjhcKhfTkk0/qsssu09NPP60uXbro73//u1555RX94x//cHs81Kgt3HfffbfeeustjRs3TgsWLFB5eTnP/dqQvXv36vrrr9dtt92mhQsXavny5SorK9OuXbtabQZKt0V2794tv9+vm2++WT179lSfPn307//+75o4caJWrVql6dOnuz1ixKuqqtJ//dd/6eyzz9bGjRt15MgR3XrrrXWKN7+E3VdaWqrZs2fr2muv1ezZszV8+HB997vf1X333adly5ZJohi0FSUlJZo1a5Z++MMfavbs2UpNTVW/fv10xRVXaOfOnXruuef00UcfuT0mdOx32/Dhw3XnnXfq17/+tTZu3Kjf//73+vrrr/XEE08oFArJ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kn72s59pxYoVev3115WXl6cf/vCHuuSSS/TVV1+59r0BAGATjzHGuD0EAAD4dm6++WYdPnxYCxcurHfdxIkTlZeXp/z8/HrXvfnmm5oyZYr2798vqfqY7nvuuUeHDx8O32b79u3q37+/tm/frvT09PDlF110kc455xw99thjLf79AADQ3kS5PQAAAHCGMUYej0eS9MEHH2ju3Ln64osvVFJSokAgoKNHj6q8vFwJCQkN3n/Dhg0KBoMaOHBgncsrKyvVuXNnx+cHAKA9oHQDANBOff755+rXr5+2bdumyy67THfeeaceffRRderUSR9//LFuu+02VVVVNVq6S0tL5fP5tGbNGvl8vjrXJSUltca3AACA9SjdAAC0Q8uWLdOGDRs0ffp0rVmzRqFQSE8++aS83urlXP77v/+7zu1jYmIUDAbrXDZ8+HAFg0Ht27dP559/fqvNDgBAe0LpBgDAcpWVldqzZ4+CwaD27t2r9957T3PnztVll12myZMna+PGjfL7/Xruued0+eWX65///Kd+//vf1/kaffv2VWlpqZYuXaqhQ4cqISFBAwcO1I033qjJkyfrySef1PDhw1VUVKSlS5dqyJAh+sEPfuDSdwwAgD1YvRwAAMu999576tGjh/r27atLLrlE//jHP/Tss89q0aJF8vl8Gjp0qJ566ik9/vjjOuuss/Tqq69q7ty5db7GqFGjNGXKFF1//fXq2rWr5s2bJ0l66aWXNHnyZN13330644wzdNVVVyk3N1e9e/d241sFAMA6rF4OAAAAAIBD2NINAAAAAIBDKN0AAAAAADiE0g0AAAAAgEMo3QAAAAAAOITSDQAAAACAQyjdAAAAAAA4hNINAAAAAIBDKN0AAAAAADiE0g0AAAAAgEMo3QAAAAAAOITSDQAAAACAQyjdAAAAAAA45P8DUdracEJmpTAAAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "file_path = \"../../docs/air-quality/assets/img/pm25_forecast.png\"\n", "plt = util.plot_air_quality_forecast(city, street, batch_data, file_path)\n", @@ -1132,8 +685,8 @@ }, { "cell_type": "code", - "execution_count": 17, - "id": "51885b34", + "execution_count": null, + "id": "6019752e", "metadata": {}, "outputs": [], "source": [ @@ -1149,418 +702,48 @@ }, { "cell_type": "code", - "execution_count": 18, - "id": "fdcd8dae", + "execution_count": null, + "id": "450dca1a", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "9609c667af6043aa97e91bbf0c4adf3d", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Uploading Dataframe: 0.00% | | Rows 0/9 | Elapsed Time: 00:00 | Remaining Time: ?" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Launching job: aq_monitoring_1_offline_fg_materialization\n", - "Job started successfully, you can follow the progress at \n", - "https://snurran.hops.works/p/5240/jobs/named/aq_monitoring_1_offline_fg_materialization/executions\n" - ] - }, - { - "data": { - "text/plain": [ - "(, None)" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "monitor_fg.insert(batch_data, wait=True)" ] }, { "cell_type": "code", - "execution_count": 19, - "id": "e5f4d9af", + "execution_count": null, + "id": "312261ad", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.50s) \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", - "
datetemperature_2m_meanprecipitation_sumwind_speed_10m_maxwind_direction_10m_dominantcitypredicted_pm25streetcountrydays_before_forecast_day
02024-03-09 00:00:00+00:000.700.010.49571359.036320stockholm35.458157stockholm-hornsgatan-108-gatasweden1
12024-03-10 00:00:00+00:000.500.015.790833114.227737stockholm36.469070stockholm-hornsgatan-108-gatasweden1
22024-03-11 00:00:00+00:003.500.012.224107103.627014stockholm38.769756stockholm-hornsgatan-108-gatasweden1
32024-03-12 00:00:00+00:005.400.07.903619120.068497stockholm54.161850stockholm-hornsgatan-108-gatasweden1
42024-03-13 00:00:00+00:003.400.09.793058197.102814stockholm32.752457stockholm-hornsgatan-108-gatasweden1
52024-03-16 00:00:00+00:008.800.111.525623181.789871stockholm41.385178stockholm-hornsgatan-108-gatasweden1
62024-03-19 00:00:00+00:003.800.01.835647191.309891stockholm47.807198stockholm-hornsgatan-108-gatasweden1
72024-03-20 00:00:00+00:002.850.19.178235191.309891stockholm45.177952stockholm-hornsgatan-108-gatasweden1
\n", - "
" - ], - "text/plain": [ - " date temperature_2m_mean precipitation_sum \\\n", - "0 2024-03-09 00:00:00+00:00 0.70 0.0 \n", - "1 2024-03-10 00:00:00+00:00 0.50 0.0 \n", - "2 2024-03-11 00:00:00+00:00 3.50 0.0 \n", - "3 2024-03-12 00:00:00+00:00 5.40 0.0 \n", - "4 2024-03-13 00:00:00+00:00 3.40 0.0 \n", - "5 2024-03-16 00:00:00+00:00 8.80 0.1 \n", - "6 2024-03-19 00:00:00+00:00 3.80 0.0 \n", - "7 2024-03-20 00:00:00+00:00 2.85 0.1 \n", - "\n", - " wind_speed_10m_max wind_direction_10m_dominant city predicted_pm25 \\\n", - "0 10.495713 59.036320 stockholm 35.458157 \n", - "1 15.790833 114.227737 stockholm 36.469070 \n", - "2 12.224107 103.627014 stockholm 38.769756 \n", - "3 7.903619 120.068497 stockholm 54.161850 \n", - "4 9.793058 197.102814 stockholm 32.752457 \n", - "5 11.525623 181.789871 stockholm 41.385178 \n", - "6 1.835647 191.309891 stockholm 47.807198 \n", - "7 9.178235 191.309891 stockholm 45.177952 \n", - "\n", - " street country days_before_forecast_day \n", - "0 stockholm-hornsgatan-108-gata sweden 1 \n", - "1 stockholm-hornsgatan-108-gata sweden 1 \n", - "2 stockholm-hornsgatan-108-gata sweden 1 \n", - "3 stockholm-hornsgatan-108-gata sweden 1 \n", - "4 stockholm-hornsgatan-108-gata sweden 1 \n", - "5 stockholm-hornsgatan-108-gata sweden 1 \n", - "6 stockholm-hornsgatan-108-gata sweden 1 \n", - "7 stockholm-hornsgatan-108-gata sweden 1 " - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "# air_quality_fg = fs.get_feature_group(\n", + "# name='air_quality',\n", + "# version=1,\n", + "# )\n", + "# a = air_quality_fg.read()\n", + "# a = a.sort_values(by=['date'])\n", + "# a" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a413bda", + "metadata": {}, + "outputs": [], "source": [ - "from hsfs.feature import Feature\n", - "\n", "# We will create a hindcast chart for only the forecasts made 1 day beforehand\n", - "monitoring_df = monitor_fg.filter(Feature(\"days_before_forecast_day\") == 1).read()\n", + "monitoring_df = monitor_fg.filter(monitor_fg.days_before_forecast_day == 1).read()\n", "monitoring_df" ] }, { "cell_type": "code", - "execution_count": 20, - "id": "eac263ef", + "execution_count": null, + "id": "147c0412", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.44s) \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", - "
datepm25countrycitystreet
02017-10-18 00:00:00+00:0010.0swedenstockholmstockholm-hornsgatan-108-gata
12020-06-17 00:00:00+00:0030.0swedenstockholmstockholm-hornsgatan-108-gata
22023-04-12 00:00:00+00:0062.0swedenstockholmstockholm-hornsgatan-108-gata
32020-03-22 00:00:00+00:0016.0swedenstockholmstockholm-hornsgatan-108-gata
42018-11-11 00:00:00+00:0057.0swedenstockholmstockholm-hornsgatan-108-gata
..................
22772024-03-13 00:00:00+00:0051.0swedenstockholmstockholm-hornsgatan-108-gata
22782024-03-14 00:00:00+00:0041.0swedenstockholmstockholm-hornsgatan-108-gata
22792024-03-15 00:00:00+00:0054.0swedenstockholmstockholm-hornsgatan-108-gata
22802024-03-16 00:00:00+00:0045.0swedenstockholmstockholm-hornsgatan-108-gata
22812024-03-19 00:00:00+00:0017.0swedenstockholmstockholm-hornsgatan-108-gata
\n", - "

2282 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " date pm25 country city \\\n", - "0 2017-10-18 00:00:00+00:00 10.0 sweden stockholm \n", - "1 2020-06-17 00:00:00+00:00 30.0 sweden stockholm \n", - "2 2023-04-12 00:00:00+00:00 62.0 sweden stockholm \n", - "3 2020-03-22 00:00:00+00:00 16.0 sweden stockholm \n", - "4 2018-11-11 00:00:00+00:00 57.0 sweden stockholm \n", - "... ... ... ... ... \n", - "2277 2024-03-13 00:00:00+00:00 51.0 sweden stockholm \n", - "2278 2024-03-14 00:00:00+00:00 41.0 sweden stockholm \n", - "2279 2024-03-15 00:00:00+00:00 54.0 sweden stockholm \n", - "2280 2024-03-16 00:00:00+00:00 45.0 sweden stockholm \n", - "2281 2024-03-19 00:00:00+00:00 17.0 sweden stockholm \n", - "\n", - " street \n", - "0 stockholm-hornsgatan-108-gata \n", - "1 stockholm-hornsgatan-108-gata \n", - "2 stockholm-hornsgatan-108-gata \n", - "3 stockholm-hornsgatan-108-gata \n", - "4 stockholm-hornsgatan-108-gata \n", - "... ... \n", - "2277 stockholm-hornsgatan-108-gata \n", - "2278 stockholm-hornsgatan-108-gata \n", - "2279 stockholm-hornsgatan-108-gata \n", - "2280 stockholm-hornsgatan-108-gata \n", - "2281 stockholm-hornsgatan-108-gata \n", - "\n", - "[2282 rows x 5 columns]" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "air_quality_fg = fs.get_feature_group(\n", " name='air_quality',\n", @@ -1572,99 +755,10 @@ }, { "cell_type": "code", - "execution_count": 21, - "id": "7a95e9e6", + "execution_count": null, + "id": "033a03f5", "metadata": {}, - "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", - "
datepredicted_pm25pm25
02024-03-09 00:00:00+00:0035.45815735.0
12024-03-10 00:00:00+00:0036.46907024.0
22024-03-11 00:00:00+00:0038.76975626.0
32024-03-12 00:00:00+00:0054.16185046.0
42024-03-13 00:00:00+00:0032.75245751.0
52024-03-16 00:00:00+00:0041.38517845.0
62024-03-19 00:00:00+00:0047.80719817.0
\n", - "
" - ], - "text/plain": [ - " date predicted_pm25 pm25\n", - "0 2024-03-09 00:00:00+00:00 35.458157 35.0\n", - "1 2024-03-10 00:00:00+00:00 36.469070 24.0\n", - "2 2024-03-11 00:00:00+00:00 38.769756 26.0\n", - "3 2024-03-12 00:00:00+00:00 54.161850 46.0\n", - "4 2024-03-13 00:00:00+00:00 32.752457 51.0\n", - "5 2024-03-16 00:00:00+00:00 41.385178 45.0\n", - "6 2024-03-19 00:00:00+00:00 47.807198 17.0" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "outcome_df = air_quality_df[['date', 'pm25']]\n", "preds_df = monitoring_df[['date', 'predicted_pm25']]\n", @@ -1676,7 +770,7 @@ }, { "cell_type": "markdown", - "id": "e789a01d", + "id": "1d4cf23a", "metadata": {}, "source": [ "### Plot the Hindcast comparing predicted with forecasted values (1-day prior forecast)" @@ -1684,21 +778,10 @@ }, { "cell_type": "code", - "execution_count": 22, - "id": "3e7c850c", + "execution_count": null, + "id": "cecae3b2", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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EqZpam0uWrRI7733npYuXap//etf1CZMcTa/yyXp+eef15QpU3jzHKZoal3u2bNH8+bN0+uvv66PPvrI1J+XjHS3cQUFBdqwYUO98zr79u2r5557Ti6XS9dff72WLFmi7t27q2fPnpo0aZLuvvtu9erVK3CdRpsWFham8ePHKzIyUjfffLPi4+P12muvSVKjPxRnzJihKVOmqE+fPi3dXQSJptZlamqq7w3M7/oDEzhXTa3NtLQ05eXl6X/+53/Ur1+/QHQZQaCpdVm7r8DPf/7zQHQXQaKpdZmUlKTrrrtOd955p7p162Zq3xjpbuMOHz7sO6rhoYceUkxMjO/emjVr9NOf/lT33XefbrrppgD2EsGmdtOp2uk7L730kt544w2NHj1a999/v/r06SOXy6XCwsIG04AAs5xJXVZVVamgoECJiYlsToUW09TadLvdfje1ApoTv8thRWf687KwsFAdO3ZssX4x0t3GJSUlafz48frss880cOBAzZgxQ+Hh4ZKkkSNHyu12a9WqVYRutKjaGqz9w/BnP/uZJOmNN96QJM2dO1d/+ctftGbNGi1fvlwOh4M1iTDd2dQl0BKoTVgRv8thRVatS0J3G1Y7CvPUU0/phhtu0LPPPqvy8nLdeuutvoLs3bs3u0CjxdXuChkSEiKXyyWHw+H7ofj222/r448/1pEjR7RkyZIGGwQBZqEuYVXUJqyIuoQVWbUumV7ehp0+vWz27NnauHGjEhISdNlll2nr1q167733tHbtWg0aNCiAPUUwqa3LkpISRUdHS1K9abojR47U9u3btWzZMg0dOjSQXUUQoS5hVdQmrIi6hBVZuS5ZjNYGGYah6upqhYSE6JtvvtH48eOVm5urefPm6d5771XHjh21cOFCHT9+XCtXriRwo0WcXpfTpk3TypUrJXnPO3a5XLr99tu1du1afkmjxVCXsCpqE1ZEXcKKWkNdMr28lduzZ48WLVqko0ePatSoUbr66qtls9kUGhqq3bt36+KLL9bll1+uwYMHy2azaebMmZo5c6YqKytlt9tZ9wVTnGldjh492vc1DodDF1xwgX7yk5/wSxqmoC5hVdQmrIi6hBW11rpkenkrlpOToyuvvFIDBgxQRUWFvvrqKy1atEhTp06VJF122WXq0KGD/va3v7FxBVrM2dRl7fobwCzUJayK2oQVUZewotZc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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "file_path = \"../../docs/air-quality/assets/img/pm25_hindcast_1day.png\"\n", "plt = util.plot_air_quality_forecast(city, street, hindcast_df, file_path, hindcast=True)\n", @@ -1707,7 +790,7 @@ }, { "cell_type": "markdown", - "id": "03bf29ef", + "id": "dc275158", "metadata": {}, "source": [ "---" diff --git a/notebooks/ch03/5_function_calling.ipynb b/notebooks/ch03/5_function_calling.ipynb index b87bf6c1..b2ce819c 100644 --- a/notebooks/ch03/5_function_calling.ipynb +++ b/notebooks/ch03/5_function_calling.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "fe2456d8", + "id": "ec5c843d", "metadata": {}, "source": [ "## 📝 Imports" @@ -11,7 +11,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "e17c4d7d", + "id": "2c1def4f", "metadata": {}, "outputs": [], "source": [ @@ -25,7 +25,7 @@ }, { "cell_type": "markdown", - "id": "ed51eb7a", + "id": "f87af501", "metadata": {}, "source": [ "## 🔮 Connect to Hopsworks Feature Store " @@ -34,7 +34,7 @@ { "cell_type": "code", "execution_count": 2, - "id": "2ed21b3f", + "id": "3b184211", "metadata": {}, "outputs": [ { @@ -56,7 +56,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "5a030ddc", + "id": "ee5cae5d", "metadata": {}, "outputs": [], "source": [ @@ -72,7 +72,7 @@ }, { "cell_type": "markdown", - "id": "353c58bd", + "id": "42ad4152", "metadata": {}, "source": [ "## 🪝 Retrieve AirQuality Model from Model Registry" @@ -81,7 +81,7 @@ { "cell_type": "code", "execution_count": 4, - "id": "e8089ca8", + "id": "5ce84f6d", "metadata": {}, "outputs": [ { @@ -110,7 +110,7 @@ { "cell_type": "code", "execution_count": 5, - "id": "aacaf40a", + "id": "af0980d4", "metadata": {}, "outputs": [ { @@ -174,14 +174,14 @@ { "cell_type": "code", "execution_count": 6, - "id": "21a0b2db", + "id": "85725259", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.91s) \n", + "Finished: Reading data from Hopsworks, using ArrowFlight (1.22s) \n", " date pm25\n", "0 2024-02-02 22.0\n", "1 2024-02-03 12.0\n", @@ -200,7 +200,7 @@ }, { "cell_type": "markdown", - "id": "f1c7dc35", + "id": "65da74f3", "metadata": {}, "source": [ "## ⬇️ LLM Loading" @@ -209,13 +209,13 @@ { "cell_type": "code", "execution_count": 7, - "id": "83306e66", + "id": "23f8ba92", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "fac2bbf753e34af3809fb7828925e138", + "model_id": "964c36517adf4840b74afb03d7ee568b", "version_major": 2, "version_minor": 0 }, @@ -229,7 +229,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3c8fa35365734cb1b283dc6271d887c7", + "model_id": "a6a149733f904425a2a411282914b514", "version_major": 2, "version_minor": 0 }, @@ -243,7 +243,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "da70e8a43cf84af8a595637141095ff3", + "model_id": "83b139f7a3e944b89c7c3892e1769fec", "version_major": 2, "version_minor": 0 }, @@ -257,7 +257,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5205062438ff4421a13eda2b631734ab", + "model_id": "d63114559cca4698a6236d8ebb585e11", "version_major": 2, "version_minor": 0 }, @@ -279,7 +279,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "219ae6362ba246f6b5e87c510b075e45", + "model_id": "8f7aa9e49c95417796a14e43dc0c3722", "version_major": 2, "version_minor": 0 }, @@ -293,7 +293,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c9ac294748614e21a2361ac6cb40b3ac", + "model_id": "944613632e7a4e67872c9d4a3af221a7", "version_major": 2, "version_minor": 0 }, @@ -307,7 +307,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "4f7704d4c0b64cf285fcf25910feb0bf", + "model_id": "93a2c642ecde44e5a5466566ad0acf94", "version_major": 2, "version_minor": 0 }, @@ -321,7 +321,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3cca5e0ea79741b8ba831778e0b091ac", + "model_id": "d3146bf6f0a14232a68b127d7150322e", "version_major": 2, "version_minor": 0 }, @@ -335,7 +335,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c7437476e213417c8084ade4db9c4ad9", + "model_id": "9ff306ba109946e7a2797e273a85a224", "version_major": 2, "version_minor": 0 }, @@ -346,10 +346,17 @@ "metadata": {}, "output_type": "display_data" }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-03-20 10:49:25,327 INFO: We will use 90% of the memory on device 0 for storing the model, and 10% for the buffer to avoid OOM. You can set `max_memory` in to a higher value to use more memory (at your own risk).\n" + ] + }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5ea2cb4874e74fd3b4126e5f130ab62e", + "model_id": "21cfb5b7591b49148eaecd999cf20d93", "version_major": 2, "version_minor": 0 }, @@ -363,7 +370,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "abb92c36d7be40f6919ce3b886d54b5f", + "model_id": "656d440932b0419ab35e4daa488ce1f0", "version_major": 2, "version_minor": 0 }, @@ -382,7 +389,7 @@ }, { "cell_type": "markdown", - "id": "f8d43069", + "id": "67ec613b", "metadata": {}, "source": [ "## ⛓️ LangChain" @@ -391,7 +398,7 @@ { "cell_type": "code", "execution_count": 8, - "id": "0b44b78d", + "id": "85a33460", "metadata": {}, "outputs": [], "source": [ @@ -404,7 +411,7 @@ }, { "cell_type": "markdown", - "id": "2a1943c5", + "id": "239d1133", "metadata": {}, "source": [ "## 🧬 Model Inference\n" @@ -413,14 +420,14 @@ { "cell_type": "code", "execution_count": 9, - "id": "e4501f50", + "id": "036a5f1d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 \n", "\n", "Hello! How can I assist you with air quality information?\n" @@ -446,17 +453,17 @@ { "cell_type": "code", "execution_count": 10, - "id": "e3ea9983", + "id": "9466a2a0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 \n", "\n", - "I am an AI Air Quality Assistant, here to help you with air quality information.\n" + "I am an AI Air Quality Assistant, designed to provide you with information about air quality in the city provided by you. I can answer your questions about air quality and offer advice based on the data you provide.\n" ] } ], @@ -479,15 +486,15 @@ { "cell_type": "code", "execution_count": 11, - "id": "5df67b87", + "id": "10cd1831", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.89s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (1.12s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "Date: 2024-01-10; Air Quality: 9.0\n", "Date: 2024-01-11; Air Quality: 8.0\n", @@ -496,7 +503,7 @@ "Date: 2024-01-14; Air Quality: 13.0\n", "Date: 2024-01-15; Air Quality: 8.0\n", "\n", - "The average air quality from 2024-01-10 till 2024-01-14 was 10.6. The air quality during that period ranged from safe to moderately polluted, so it would be advisable to limit outdoor activities on days with higher pollution levels.\n" + "The average air quality from 2024-01-10 to 2024-01-14 was 10.4. This indicates that the air quality during that period was generally good, with no need to worry about going outside.\n" ] } ], @@ -519,29 +526,24 @@ { "cell_type": "code", "execution_count": 12, - "id": "086d9b42", + "id": "a022bf44", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (1.04s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.91s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "Date: 2024-03-12; Air Quality: 46.0\n", "Date: 2024-03-13; Air Quality: 51.0\n", "Date: 2024-03-14; Air Quality: 41.0\n", "Date: 2024-03-15; Air Quality: 54.0\n", "Date: 2024-03-16; Air Quality: 45.0\n", + "Date: 2024-03-19; Air Quality: 17.0\n", "\n", - "Last week, the air quality was as follows:\n", - "\n", - "- On 2024-03-12, the air quality was 46.0, which indicates very polluted air. It is not recommended to engage in outdoor activities on this day.\n", - "- On 2024-03-13, the air quality was 51.0, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On 2024-03-14, the air quality was 41.0, which indicates moderately polluted air. It would be advisable to limit outdoor activities on this day.\n", - "- On 2024-03-15, the air quality was 54.0, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On 2024-03-16, the air quality was 45.0, which indicates moderately polluted air. It would be advisable to limit outdoor activities on this day.\n" + "Last week, on 2024-03-12, the air quality was 46.0, indicating that the air quality was unhealthy for sensitive groups. On 2024-03-13, the air quality was 51.0, which is also unhealthy for sensitive groups. On 2024-03-14, the air quality improved to 41.0, which was considered unhealthy. On 2024-03-15, the air quality was 54.0, which is unhealthy for sensitive groups. On 2024-03-16, the air quality was 45.0, which is also unhealthy for sensitive groups. On 2024-03-19, the air quality improved to 17.0, which is considered safe for everyone.\n" ] } ], @@ -564,15 +566,15 @@ { "cell_type": "code", "execution_count": 13, - "id": "481f2083", + "id": "4bf5a093", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.82s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.93s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "Date: 2024-01-10; Air Quality: 9.0\n", "Date: 2024-01-11; Air Quality: 8.0\n", @@ -581,7 +583,7 @@ "Date: 2024-01-14; Air Quality: 13.0\n", "Date: 2024-01-15; Air Quality: 8.0\n", "\n", - "The minimum air quality from 2024-01-10 till 2024-01-14 was on 2024-01-15, with an air quality of 8.0. This indicates clean air, and it is safe to engage in outdoor activities.\n" + "The minimum air quality from 2024-01-10 to 2024-01-14 was on 2024-01-15, with an air quality of 8.0. This indicates that the air quality during that period was generally good, with no need to worry about going outside.\n" ] } ], @@ -604,29 +606,24 @@ { "cell_type": "code", "execution_count": 14, - "id": "0784cdee", + "id": "96f61c8e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.83s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (1.02s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", - "Date: 2024-03-12; Air Quality: 46.0\n", "Date: 2024-03-13; Air Quality: 51.0\n", "Date: 2024-03-14; Air Quality: 41.0\n", "Date: 2024-03-15; Air Quality: 54.0\n", "Date: 2024-03-16; Air Quality: 45.0\n", + "Date: 2024-03-19; Air Quality: 17.0\n", + "Date: 2024-03-20; Air Quality: 17.0\n", "\n", - "Last week, the air quality was as follows:\n", - "\n", - "- On 2024-03-12, the air quality was 46.0, which indicates very polluted air. It is not recommended to engage in outdoor activities on this day.\n", - "- On 2024-03-13, the air quality was 51.0, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On 2024-03-14, the air quality was 41.0, which indicates moderately polluted air. It would be advisable to limit outdoor activities on this day.\n", - "- On 2024-03-15, the air quality was 54.0, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On 2024-03-16, the air quality was 45.0, which indicates moderately polluted air. It would be advisable to limit outdoor activities on this day.\n" + "Last week, the air quality was generally good. On 2024-03-19 and 2024-03-20, the air quality was 17.0, indicating that the air quality was safe for everyone. On 2024-03-15, the air quality was 54.0, which is unhealthy for sensitive groups. On 2024-03-16, the air quality was 45.0, which is also unhealthy for sensitive groups. On 2024-03-13, the air quality was 51.0, which is unhealthy for sensitive groups. On 2024-03-14, the air quality was 41.0, which was considered unhealthy.\n" ] } ], @@ -649,19 +646,19 @@ { "cell_type": "code", "execution_count": 15, - "id": "63ce7f09", + "id": "075b424c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished: Reading data from Hopsworks, using ArrowFlight (0.88s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.97s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", + "Date: 2024-03-19; Air Quality: 17.0\n", "\n", - "\n", - "Yesterday, on 2024-03-18, the air quality was 48.0, which indicates very polluted air. It is not recommended to engage in outdoor activities on this day.\n" + "Yesterday, the air quality was safe for everyone. The air quality measurement was 17.0, indicating that the air quality was safe for everyone.\n" ] } ], @@ -684,7 +681,7 @@ { "cell_type": "code", "execution_count": 16, - "id": "d80d48d0", + "id": "565c0be6", "metadata": {}, "outputs": [ { @@ -696,12 +693,12 @@ "\n", "Logged in to project, explore it here https://snurran.hops.works/p/5240\n", "Connected. Call `.close()` to terminate connection gracefully.\n", - "Finished: Reading data from Hopsworks, using ArrowFlight (0.35s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.53s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "\n", "\n", - "On 2024-03-20, the air quality is expected to be 50.0, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n" + "On 2024-03-20, the air quality was 17.0, indicating that the air quality was safe for everyone. You can go outside and enjoy the day without any concerns about the air quality.\n" ] } ], @@ -724,7 +721,7 @@ { "cell_type": "code", "execution_count": 17, - "id": "c060d7b8", + "id": "f404beb4", "metadata": {}, "outputs": [ { @@ -736,12 +733,12 @@ "\n", "Logged in to project, explore it here https://snurran.hops.works/p/5240\n", "Connected. Call `.close()` to terminate connection gracefully.\n", - "Finished: Reading data from Hopsworks, using ArrowFlight (0.41s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.46s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "\n", "\n", - "On 2024-03-21, the air quality is expected to be 49.0, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n" + "I'm sorry, but I can't predict the air quality for the day after tomorrow. The air quality can change depending on various factors such as weather, pollution sources, and other environmental conditions.\n" ] } ], @@ -764,7 +761,7 @@ { "cell_type": "code", "execution_count": 18, - "id": "44187569", + "id": "b48c5623", "metadata": {}, "outputs": [ { @@ -776,12 +773,12 @@ "\n", "Logged in to project, explore it here https://snurran.hops.works/p/5240\n", "Connected. Call `.close()` to terminate connection gracefully.\n", - "Finished: Reading data from Hopsworks, using ArrowFlight (0.40s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.56s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "\n", "\n", - "On Sunday, 2024-03-24, the air quality is expected to be 48.0, which indicates very polluted air. It is not recommended to engage in outdoor activities on this day.\n" + "I'm sorry, but I can't predict the air quality for this Sunday. The air quality can change depending on various factors such as weather, pollution sources, and other environmental conditions.\n" ] } ], @@ -804,7 +801,7 @@ { "cell_type": "code", "execution_count": 19, - "id": "9b166ce8", + "id": "b38ec00e", "metadata": {}, "outputs": [ { @@ -816,26 +813,16 @@ "\n", "Logged in to project, explore it here https://snurran.hops.works/p/5240\n", "Connected. Call `.close()` to terminate connection gracefully.\n", - "Finished: Reading data from Hopsworks, using ArrowFlight (0.37s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.62s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", - "Date: 2024-03-19 00:00:00; Air Quality: 47.81\n", - "Date: 2024-03-20 00:00:00; Air Quality: 38.51\n", - "Date: 2024-03-21 00:00:00; Air Quality: 36.06\n", - "Date: 2024-03-22 00:00:00; Air Quality: 40.23\n", - "Date: 2024-03-23 00:00:00; Air Quality: 24.64\n", - "Date: 2024-03-24 00:00:00; Air Quality: 28.36\n", - "Date: 2024-03-25 00:00:00; Air Quality: 18.81\n", - "\n", - "The air quality for the rest of the week is expected to be as follows:\n", - "\n", - "- On Wednesday, 2024-03-20, the air quality is expected to be 38.51, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On Thursday, 2024-03-21, the air quality is expected to be 36.06, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On Friday, 2024-03-22, the air quality is expected to be 40.23, which indicates very polluted air. It is not recommended to engage in outdoor activities on this day.\n", - "- On Saturday, 2024-03-23, the air quality is expected to be 24.64, which indicates moderate air quality. It is safe to engage in outdoor activities, but sensitive individuals may want to limit prolonged exposure.\n", - "- On Sunday, 2024-03-24, the air quality is expected to be 28.36, which indicates moderate air quality. It is safe to engage in outdoor activities, but sensitive individuals may want to limit prolonged exposure.\n", + "Date: 2024-03-24 00:00:00; Air Quality: 41.25\n", + "Date: 2024-03-25 00:00:00; Air Quality: 58.89\n", + "Date: 2024-03-26 00:00:00; Air Quality: 47.22\n", + "Date: 2024-03-27 00:00:00; Air Quality: 39.18\n", + "Date: 2024-03-28 00:00:00; Air Quality: 39.91\n", "\n", - "Please remember that these predictions are based on the provided air quality measurements and may be subject to change due to various factors.\n" + "I'm sorry, but I can't predict the air quality for the rest of the week. The air quality can change depending on various factors such as weather, pollution sources, and other environmental conditions.\n" ] } ], @@ -858,7 +845,7 @@ { "cell_type": "code", "execution_count": 20, - "id": "d5b3c441", + "id": "87bfe6cf", "metadata": {}, "outputs": [ { @@ -870,26 +857,16 @@ "\n", "Logged in to project, explore it here https://snurran.hops.works/p/5240\n", "Connected. Call `.close()` to terminate connection gracefully.\n", - "Finished: Reading data from Hopsworks, using ArrowFlight (0.37s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.45s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", - "Date: 2024-03-19 00:00:00; Air Quality: 47.81\n", - "Date: 2024-03-20 00:00:00; Air Quality: 38.51\n", - "Date: 2024-03-21 00:00:00; Air Quality: 36.06\n", - "Date: 2024-03-22 00:00:00; Air Quality: 40.23\n", - "Date: 2024-03-23 00:00:00; Air Quality: 24.64\n", - "Date: 2024-03-24 00:00:00; Air Quality: 28.36\n", - "Date: 2024-03-25 00:00:00; Air Quality: 18.81\n", + "Date: 2024-03-24 00:00:00; Air Quality: 41.25\n", + "Date: 2024-03-25 00:00:00; Air Quality: 58.89\n", + "Date: 2024-03-26 00:00:00; Air Quality: 47.22\n", + "Date: 2024-03-27 00:00:00; Air Quality: 39.18\n", + "Date: 2024-03-28 00:00:00; Air Quality: 39.91\n", "\n", - "The air quality for the rest of the week is expected to be as follows:\n", - "\n", - "- On Wednesday, 2024-03-20, the air quality is expected to be 38.51, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On Thursday, 2024-03-21, the air quality is expected to be 36.06, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day.\n", - "- On Friday, 2024-03-22, the air quality is expected to be 40.23, which indicates very polluted air. It is not recommended to engage in outdoor activities on this day.\n", - "- On Saturday, 2024-03-23, the air quality is expected to be 24.64, which indicates moderate air quality. It is safe to engage in outdoor activities, but sensitive individuals may want to limit prolonged exposure.\n", - "- On Sunday, 2024-03-24, the air quality is expected to be 28.36, which indicates moderate air quality. It is safe to engage in outdoor activities, but sensitive individuals may want to limit prolonged exposure.\n", - "\n", - "Please remember that these predictions are based on the provided air quality measurements and may be subject to change due to various factors.\n" + "I'm sorry, but I can't predict the air quality for the rest of the week. The air quality can change depending on various factors such as weather, pollution sources, and other environmental conditions.\n" ] } ], @@ -912,7 +889,7 @@ { "cell_type": "code", "execution_count": 21, - "id": "713261c4", + "id": "80a256ce", "metadata": {}, "outputs": [ { @@ -924,12 +901,12 @@ "\n", "Logged in to project, explore it here https://snurran.hops.works/p/5240\n", "Connected. Call `.close()` to terminate connection gracefully.\n", - "Finished: Reading data from Hopsworks, using ArrowFlight (0.42s) \n", - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "Finished: Reading data from Hopsworks, using ArrowFlight (0.43s) \n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 Air Quality Measurements:\n", "\n", "\n", - "On Wednesday, 2024-03-20, the air quality is expected to be 38.51, which indicates extremely polluted air. It is advisable to limit outdoor activities on this day. While it is not considered dangerous, it is not recommended for sensitive individuals or those with respiratory issues to engage in prolonged outdoor activities.\n" + "I'm sorry, but I can't predict the air quality for tomorrow. The air quality can change depending on various factors such as weather, pollution sources, and other environmental conditions.\n" ] } ], @@ -952,25 +929,31 @@ { "cell_type": "code", "execution_count": 22, - "id": "df7fe89b", + "id": "abef7d17", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "🗓️ Today's date: Tuesday, 2024-03-19\n", + "🗓️ Today's date: Wednesday, 2024-03-20\n", "📖 \n", "\n", - "Certainly! Air quality levels are typically measured on a scale, with different levels indicating varying degrees of air pollution. Here is a general breakdown of air quality levels:\n", + "Of course! Air quality levels are typically measured using an index, such as the Air Quality Index (AQI), which ranges from 0 to 500. Here's a brief explanation of the different air quality levels:\n", + "\n", + "0-50: Good air quality, which means the air is clean and poses little or no risk.\n", + "\n", + "51-100: Moderate air quality, which means the air is generally clean, but there may be some health concerns for sensitive groups, such as the elderly or those with respiratory issues.\n", + "\n", + "101-150: Unhealthy for sensitive groups, which means that although the air quality is still considered moderate, it may pose health risks for certain groups, such as children, the elderly, and those with respiratory issues.\n", + "\n", + "151-200: Unhealthy air quality, which means that the air quality is not safe for the general public, particularly for those with respiratory issues or heart disease.\n", + "\n", + "201-300: Very unhealthy air quality, which means that the air quality is hazardous and can cause serious health effects for everyone, including healthy individuals.\n", "\n", - "1. Good (0-50): Air quality is considered good, and it is safe for everyone to engage in outdoor activities.\n", - "2. Moderate (51-100): Air quality is acceptable, but sensitive groups (such as children, the elderly, and those with respiratory issues) may want to limit prolonged exposure.\n", - "3. Poor (101-150): Air quality is not considered healthy, and groups sensitive to air pollution may experience health effects. It is advisable to limit outdoor activities.\n", - "4. Very Poor (151-200): Air quality is significantly polluted, and the general public may experience health effects. It is not recommended to engage in outdoor activities.\n", - "5. Hazardous (200+): Air quality is extremely polluted, and it is dangerous for everyone to engage in outdoor activities.\n", + "301-500: Hazardous air quality, which means that the air quality is extremely dangerous and can cause severe health effects, such as death, in a short period of time.\n", "\n", - "These levels may vary depending on the specific air quality index used, but this general breakdown should give you an idea of the different air quality levels.\n" + "Please let me know if you have any further questions or if you need information on the air quality for a specific date.\n" ] } ], @@ -993,15 +976,15 @@ { "cell_type": "code", "execution_count": 23, - "id": "c0993dc1", + "id": "28597822", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2024-03-19 06:52:24,184 INFO: generated new fontManager\n", - "2024-03-19 06:52:24,549 INFO: HTTP Request: GET https://api.gradio.app/gradio-messaging/en \"HTTP/1.1 200 OK\"\n" + "2024-03-20 10:51:51,163 INFO: generated new fontManager\n", + "2024-03-20 10:51:51,477 INFO: HTTP Request: GET https://api.gradio.app/gradio-messaging/en \"HTTP/1.1 200 OK\"\n" ] } ], @@ -1017,13 +1000,13 @@ { "cell_type": "code", "execution_count": 24, - "id": "9b506b7f", + "id": "3e7d1d9b", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6a59b17bcc2b49fd9c69e9f1f9c21fd1", + "model_id": "d7f241282e9f4e0fb9d45f13e1966c01", "version_major": 2, "version_minor": 0 }, @@ -1037,7 +1020,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "66e6a915106a405eba8c43f5c16753f8", + "model_id": "0585b9c33fbf459181893be988221eeb", "version_major": 2, "version_minor": 0 }, @@ -1051,7 +1034,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d72c4c8a687349d69e68b6f6e2e40ce6", + "model_id": "15e18c6b3adc457f9882efbac94935e4", "version_major": 2, "version_minor": 0 }, @@ -1065,7 +1048,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "647936e18ff740f5b5abab51ebac0134", + "model_id": "1fe85b0c39e84ce8a6123a5275ac467d", "version_major": 2, "version_minor": 0 }, @@ -1079,7 +1062,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "35d0f745134141a2b1e47ae1ce95b538", + "model_id": "69c11734f6ed4311bef9a3196433c0ce", "version_major": 2, "version_minor": 0 }, @@ -1093,7 +1076,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "15d3da23eb5940aab424c0cbc09436bf", + "model_id": "8e7409ef9fa648a59a88c07737aebbf8", "version_major": 2, "version_minor": 0 }, @@ -1107,7 +1090,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b58a174c697e4dbc8d68040036a81157", + "model_id": "2b56591f7a7341c9bb35baa34947ef6b", "version_major": 2, "version_minor": 0 }, @@ -1121,7 +1104,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "62e0d3d57334441d8ef8ccb961bc510e", + "model_id": "cb5c228ee04f4975865dbd012d2bcb03", "version_major": 2, "version_minor": 0 }, @@ -1135,7 +1118,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a36930789672481fa27f2a25da850d3d", + "model_id": "336bc6cfbf034763953a2bc865d975b6", "version_major": 2, "version_minor": 0 }, @@ -1149,7 +1132,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "fe1c833d5a434975996b878233d78c4e", + "model_id": "3eaf111c66464482a548f7f54f54b56c", "version_major": 2, "version_minor": 0 }, @@ -1163,7 +1146,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "7362246fdfdf46cabfd0d4887f2fd9d4", + "model_id": "0d62ce2910c440699844c8e25161d131", "version_major": 2, "version_minor": 0 }, @@ -1179,23 +1162,23 @@ "output_type": "stream", "text": [ "Running on local URL: http://127.0.0.1:7860\n", - "2024-03-19 06:52:32,787 INFO: HTTP Request: GET http://127.0.0.1:7860/startup-events \"HTTP/1.1 200 OK\"\n", - "2024-03-19 06:52:32,810 INFO: HTTP Request: GET https://checkip.amazonaws.com/ \"HTTP/1.1 200 \"\n", - "2024-03-19 06:52:33,305 INFO: HTTP Request: GET https://api.gradio.app/pkg-version \"HTTP/1.1 200 OK\"\n", - "2024-03-19 06:52:33,627 INFO: HTTP Request: POST https://api.gradio.app/gradio-initiated-analytics/ \"HTTP/1.1 200 OK\"\n", - "2024-03-19 06:52:34,872 INFO: HTTP Request: HEAD http://127.0.0.1:7860/ \"HTTP/1.1 200 OK\"\n", - "2024-03-19 06:52:38,123 INFO: HTTP Request: GET https://api.gradio.app/v2/tunnel-request \"HTTP/1.1 200 OK\"\n", - "2024-03-19 06:52:38,278 INFO: HTTP Request: GET https://cdn-media.huggingface.co/frpc-gradio-0.2/frpc_linux_amd64 \"HTTP/1.1 200 OK\"\n", - "Running on public URL: https://2a42de7877ff3aa594.gradio.live\n", + "2024-03-20 10:52:00,100 INFO: HTTP Request: GET http://127.0.0.1:7860/startup-events \"HTTP/1.1 200 OK\"\n", + "2024-03-20 10:52:00,174 INFO: HTTP Request: GET https://checkip.amazonaws.com/ \"HTTP/1.1 200 \"\n", + "2024-03-20 10:52:00,689 INFO: HTTP Request: GET https://api.gradio.app/pkg-version \"HTTP/1.1 200 OK\"\n", + "2024-03-20 10:52:00,944 INFO: HTTP Request: POST https://api.gradio.app/gradio-initiated-analytics/ \"HTTP/1.1 200 OK\"\n", + "2024-03-20 10:52:02,176 INFO: HTTP Request: HEAD http://127.0.0.1:7860/ \"HTTP/1.1 200 OK\"\n", + "2024-03-20 10:52:11,599 INFO: HTTP Request: GET https://api.gradio.app/v2/tunnel-request \"HTTP/1.1 200 OK\"\n", + "2024-03-20 10:52:11,732 INFO: HTTP Request: GET https://cdn-media.huggingface.co/frpc-gradio-0.2/frpc_linux_amd64 \"HTTP/1.1 200 OK\"\n", + "Running on public URL: https://b28c6fa14cfcdba855.gradio.live\n", "\n", "This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)\n", - "2024-03-19 06:52:40,009 INFO: HTTP Request: HEAD https://2a42de7877ff3aa594.gradio.live \"HTTP/1.1 200 OK\"\n" + "2024-03-20 10:52:13,272 INFO: HTTP Request: HEAD https://b28c6fa14cfcdba855.gradio.live \"HTTP/1.1 200 OK\"\n" ] }, { "data": { "text/html": [ - "
" + "
" ], "text/plain": [ "" @@ -1216,7 +1199,109 @@ "name": "stdout", "output_type": "stream", "text": [ - "2024-03-19 06:52:40,785 INFO: HTTP Request: POST https://api.gradio.app/gradio-launched-telemetry/ \"HTTP/1.1 200 OK\"\n" + "2024-03-20 10:52:13,992 INFO: HTTP Request: POST https://api.gradio.app/gradio-launched-telemetry/ \"HTTP/1.1 200 OK\"\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Traceback (most recent call last):\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/queueing.py\", line 501, in call_prediction\n", + " output = await route_utils.call_process_api(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/route_utils.py\", line 253, in call_process_api\n", + " output = await app.get_blocks().process_api(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/blocks.py\", line 1695, in process_api\n", + " result = await self.call_function(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/blocks.py\", line 1235, in call_function\n", + " prediction = await anyio.to_thread.run_sync(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/anyio/to_thread.py\", line 56, in run_sync\n", + " return await get_async_backend().run_sync_in_worker_thread(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py\", line 2134, in run_sync_in_worker_thread\n", + " return await future\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/asyncio/futures.py\", line 285, in __await__\n", + " yield self # This tells Task to wait for completion.\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/asyncio/tasks.py\", line 304, in __wakeup\n", + " future.result()\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/asyncio/futures.py\", line 201, in result\n", + " raise self._exception.with_traceback(self._exception_tb)\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py\", line 851, in run\n", + " result = context.run(func, *args)\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/utils.py\", line 692, in wrapper\n", + " response = f(*args, **kwargs)\n", + " File \"\", line 31, in handle_input\n", + " return generate_query_response(user_query)\n", + " File \"\", line 13, in generate_query_response\n", + " response = generate_response(\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/llm_chain.py\", line 175, in generate_response\n", + " context = get_context_data(\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/context_engineering.py\", line 184, in get_context_data\n", + " data = invoke_function(functions[0], feature_view, model_air_quality)\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/context_engineering.py\", line 143, in invoke_function\n", + " function_output = getattr(sys.modules[__name__], function_name)(\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/air_quality_data_retrieval.py\", line 22, in get_historical_data_for_date\n", + " features_df, labels_df = feature_view.training_data(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/usage.py\", line 198, in wrapper\n", + " return func(*args, **kwargs)\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_view.py\", line 2033, in training_data\n", + " td, df = self._feature_view_engine.get_training_data(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_view_engine.py\", line 298, in get_training_data\n", + " td_updated = self._create_training_data_metadata(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_view_engine.py\", line 667, in _create_training_data_metadata\n", + " td = self._feature_view_api.create_training_dataset(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_view_api.py\", line 190, in create_training_dataset\n", + " self._client._send_request(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/decorators.py\", line 34, in if_connected\n", + " raise NoHopsworksConnectionError\n", + "hsfs.decorators.NoHopsworksConnectionError: Connection is not active. Needs to be connected for feature store operations.\n", + "Traceback (most recent call last):\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/queueing.py\", line 501, in call_prediction\n", + " output = await route_utils.call_process_api(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/route_utils.py\", line 253, in call_process_api\n", + " output = await app.get_blocks().process_api(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/blocks.py\", line 1695, in process_api\n", + " result = await self.call_function(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/blocks.py\", line 1235, in call_function\n", + " prediction = await anyio.to_thread.run_sync(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/anyio/to_thread.py\", line 56, in run_sync\n", + " return await get_async_backend().run_sync_in_worker_thread(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py\", line 2134, in run_sync_in_worker_thread\n", + " return await future\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/asyncio/futures.py\", line 285, in __await__\n", + " yield self # This tells Task to wait for completion.\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/asyncio/tasks.py\", line 304, in __wakeup\n", + " future.result()\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/asyncio/futures.py\", line 201, in result\n", + " raise self._exception.with_traceback(self._exception_tb)\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py\", line 851, in run\n", + " result = context.run(func, *args)\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/gradio/utils.py\", line 692, in wrapper\n", + " response = f(*args, **kwargs)\n", + " File \"\", line 31, in handle_input\n", + " return generate_query_response(user_query)\n", + " File \"\", line 13, in generate_query_response\n", + " response = generate_response(\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/llm_chain.py\", line 175, in generate_response\n", + " context = get_context_data(\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/context_engineering.py\", line 184, in get_context_data\n", + " data = invoke_function(functions[0], feature_view, model_air_quality)\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/context_engineering.py\", line 143, in invoke_function\n", + " function_output = getattr(sys.modules[__name__], function_name)(\n", + " File \"/home/yarnapp/hopsfs/Jupyter/mlfs-book/notebooks/ch03/functions/air_quality_data_retrieval.py\", line 22, in get_historical_data_for_date\n", + " features_df, labels_df = feature_view.training_data(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/usage.py\", line 198, in wrapper\n", + " return func(*args, **kwargs)\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/feature_view.py\", line 2033, in training_data\n", + " td, df = self._feature_view_engine.get_training_data(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_view_engine.py\", line 298, in get_training_data\n", + " td_updated = self._create_training_data_metadata(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_view_engine.py\", line 667, in _create_training_data_metadata\n", + " td = self._feature_view_api.create_training_dataset(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/core/feature_view_api.py\", line 190, in create_training_dataset\n", + " self._client._send_request(\n", + " File \"/srv/hops/anaconda/envs/theenv/lib/python3.10/site-packages/hsfs/decorators.py\", line 34, in if_connected\n", + " raise NoHopsworksConnectionError\n", + "hsfs.decorators.NoHopsworksConnectionError: Connection is not active. Needs to be connected for feature store operations.\n" ] } ], @@ -1268,7 +1353,7 @@ }, { "cell_type": "markdown", - "id": "02dd2450", + "id": "9ab87d6d", "metadata": {}, "source": [ "---"