{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set up Preview SDK<a class=\"anchor\" id=\"setup\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Configures your AWS CLI to now understand our up and coming service Amazon Forecast\n",
    "!aws configure add-model --service-model file://../sdk/forecastquery-2018-06-26.normal.json --service-name forecastquery\n",
    "!aws configure add-model --service-model file://../sdk/forecast-2018-06-26.normal.json --service-name forecast"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Prerequisites : 1 time install only, remove the comments to execute the lines.\n",
    "#!pip install boto3\n",
    "#!pip install pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [],
   "source": [
    "import boto3\n",
    "from time import sleep\n",
    "import subprocess"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "session = boto3.Session(region_name='us-west-2') #us-east-1 is also supported\n",
    "\n",
    "forecast = session.client(service_name='forecast')\n",
    "forecastquery = session.client(service_name='forecastquery')\n",
    "s3 = session.client('s3')\n",
    "accountId = boto3.client('sts').get_caller_identity().get('Account')\n",
    "\n",
    "bucketName = 'amazon-forecast-ttsang-data'\n",
    "key=\"accounting_data/accounting_bar.csv\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "amazon-forecast-ttsang-data/accounting_data/accounting_bar.csv\n"
     ]
    }
   ],
   "source": [
    "print('{}/{}'.format(bucketName,key))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "# One time setup only, uncomment the following command to create the role to provide to Amazon Forecast. \n",
    "# Save the generated role for all future calls to use for importing or exporting data. \n",
    "\n",
    "cmd = 'python ../setup_forecast_permissions.py '+bucketName\n",
    "p = subprocess.Popen(cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
    "roleArn = 'arn:aws:iam::%s:role/amazonforecast'%accountId"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### CreateDataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "More details about `Domain` and dataset type can be found on the [documentation](https://docs.aws.amazon.com/forecast/latest/dg/howitworks-domains-ds-types.html) . For this example, we are using [CUSTOM](https://docs.aws.amazon.com/forecast/latest/dg/custom-domain.html) domain with 3 required attributes `timestamp`, `target_value` and `item_id`. Also for your project name, update it to reflect your name in a lowercase format."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [],
   "source": [
    "DATASET_FREQUENCY = \"1M\" \n",
    "TIMESTAMP_FORMAT = \"yyyy-MM-dd hh:mm:ss\"\n",
    "project = 'accounting_forecast_v5' # Replace this with a unique name here, make sure the entire name is < 30 characters.\n",
    "datasetName= project+'_ds'\n",
    "datasetGroupName= project +'_gp'\n",
    "s3DataPath = \"s3://\"+bucketName+\"/\"+key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'accounting_forecast_v5_ds'"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "datasetName"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Specify the schema of your dataset here. Make sure the order of columns matches the raw data files.\n",
    "schema ={\n",
    "   \"Attributes\":[\n",
    "      {\n",
    "         \"AttributeName\":\"timestamp\",\n",
    "         \"AttributeType\":\"timestamp\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"item_id\",\n",
    "         \"AttributeType\":\"string\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"store_id\",\n",
    "         \"AttributeType\":\"integer\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"sales\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"target_value\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Upgraded_Download_Tracks\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Ad_Supported_Audio_Streams\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Subscription_Video_Streams\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Download_Albums\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Video_Download_Purchases\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Download_Tracks\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Subscription_Audio_Streams\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Cloud_Match_Units\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Non_interactive_Radio\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      },\n",
    "      {\n",
    "         \"AttributeName\":\"Streaming_Bonus\",\n",
    "         \"AttributeType\":\"float\"\n",
    "      }\n",
    "   ]\n",
    "}\n",
    "\n",
    "response=forecast.create_dataset(\n",
    "                    Domain=\"CUSTOM\",\n",
    "                    DatasetType='TARGET_TIME_SERIES',\n",
    "                    DataFormat='CSV',\n",
    "                    DatasetName=datasetName,\n",
    "                    DataFrequency=DATASET_FREQUENCY, \n",
    "                    TimeStampFormat=TIMESTAMP_FORMAT,\n",
    "                    Schema = schema\n",
    "                   )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DatasetName': 'accounting_forecast_v5_ds',\n",
       " 'DatasetType': 'TARGET_TIME_SERIES',\n",
       " 'DataFormat': 'CSV',\n",
       " 'Domain': 'CUSTOM',\n",
       " 'ScheduleExpression': 'none',\n",
       " 'DatasetArn': 'arn:aws:forecast:us-west-2:073138737237:ds/accounting_forecast_v5_ds',\n",
       " 'Status': 'ACTIVE',\n",
       " 'ResponseMetadata': {'RequestId': 'e0826bdd-502d-45a0-ba33-f8c8a0a38a06',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:34:14 GMT',\n",
       "   'x-amzn-requestid': 'e0826bdd-502d-45a0-ba33-f8c8a0a38a06',\n",
       "   'content-length': '245',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.describe_dataset(DatasetName=datasetName)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DatasetGroupName': 'accounting_forecast_v5_gp',\n",
       " 'DatasetGroupArn': 'arn:aws:forecast:us-west-2:073138737237:dsgroup/accounting_forecast_v5_gp',\n",
       " 'ResponseMetadata': {'RequestId': 'e69c51df-7826-4142-90a4-20d882724795',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:34:17 GMT',\n",
       "   'x-amzn-requestid': 'e69c51df-7826-4142-90a4-20d882724795',\n",
       "   'content-length': '142',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.create_dataset_group(DatasetGroupName=datasetGroupName,RoleArn=roleArn,DatasetNames=[datasetName])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you have an existing datasetgroup, you can update it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DatasetGroupName': 'accounting_forecast_v5_gp',\n",
       " 'DatasetGroupArn': 'arn:aws:forecast:us-west-2:073138737237:dsgroup/accounting_forecast_v5_gp',\n",
       " 'Datasets': ['accounting_forecast_v5_ds'],\n",
       " 'RoleArn': 'arn:aws:iam::073138737237:role/amazonforecast',\n",
       " 'ResponseMetadata': {'RequestId': 'bbba8521-ec6b-4dfe-87c6-9a2380dedb76',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:34:22 GMT',\n",
       "   'x-amzn-requestid': 'bbba8521-ec6b-4dfe-87c6-9a2380dedb76',\n",
       "   'content-length': '241',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.describe_dataset_group(DatasetGroupName=datasetGroupName)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create Data Import Job\n",
    "Brings the data into Amazon Forecast system ready to forecast from raw data. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1be23fa8\n"
     ]
    }
   ],
   "source": [
    "ds_import_job_response=forecast.create_dataset_import_job(DatasetName=datasetName,Delimiter=',', DatasetGroupName =datasetGroupName ,S3Uri= s3DataPath)\n",
    "ds_versionId=ds_import_job_response['VersionId']\n",
    "print(ds_versionId)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "QUEUED\n",
      "0\n",
      "CREATING\n",
      "10\n",
      "CREATING\n",
      "20\n",
      "CREATING\n",
      "30\n",
      "CREATING\n",
      "40\n",
      "CREATING\n",
      "50\n",
      "CREATING\n",
      "60\n",
      "CREATING\n",
      "70\n",
      "CREATING\n",
      "80\n",
      "CREATING\n",
      "90\n",
      "CREATING\n",
      "100\n",
      "CREATING\n",
      "110\n",
      "CREATING\n",
      "120\n",
      "CREATING\n",
      "130\n",
      "CREATING\n",
      "140\n",
      "CREATING\n",
      "150\n",
      "CREATING\n",
      "160\n",
      "CREATING\n",
      "170\n",
      "CREATING\n",
      "180\n",
      "CREATING\n",
      "190\n",
      "CREATING\n",
      "200\n",
      "CREATING\n",
      "210\n",
      "CREATING\n",
      "220\n",
      "CREATING\n",
      "230\n",
      "CREATING\n",
      "240\n",
      "CREATING\n",
      "250\n",
      "CREATING\n",
      "260\n",
      "CREATING\n",
      "270\n",
      "CREATING\n",
      "280\n",
      "CREATING\n",
      "290\n",
      "CREATING\n",
      "300\n",
      "CREATING\n",
      "310\n",
      "CREATING\n",
      "320\n",
      "CREATING\n",
      "330\n",
      "CREATING\n",
      "340\n",
      "CREATING\n",
      "350\n",
      "CREATING\n",
      "360\n",
      "CREATING\n",
      "370\n",
      "CREATING\n",
      "380\n",
      "CREATING\n",
      "390\n",
      "CREATING\n",
      "400\n",
      "CREATING\n",
      "410\n",
      "CREATING\n",
      "420\n",
      "CREATING\n",
      "430\n",
      "CREATING\n",
      "440\n",
      "CREATING\n",
      "450\n",
      "CREATING\n",
      "460\n",
      "CREATING\n",
      "470\n",
      "CREATING\n",
      "480\n",
      "CREATING\n",
      "490\n",
      "CREATING\n",
      "500\n",
      "CREATING\n",
      "510\n",
      "CREATING\n",
      "520\n",
      "CREATING\n",
      "530\n",
      "CREATING\n",
      "540\n",
      "CREATING\n",
      "550\n",
      "CREATING\n",
      "560\n",
      "CREATING\n",
      "570\n",
      "CREATING\n",
      "580\n",
      "CREATING\n",
      "590\n",
      "CREATING\n",
      "600\n",
      "CREATING\n",
      "610\n",
      "CREATING\n",
      "620\n",
      "CREATING\n",
      "630\n",
      "CREATING\n",
      "640\n",
      "CREATING\n",
      "650\n",
      "CREATING\n",
      "660\n",
      "CREATING\n",
      "670\n",
      "CREATING\n",
      "680\n",
      "CREATING\n",
      "690\n",
      "CREATING\n",
      "700\n",
      "CREATING\n",
      "710\n",
      "CREATING\n",
      "720\n",
      "CREATING\n",
      "730\n",
      "CREATING\n",
      "740\n",
      "CREATING\n",
      "750\n",
      "CREATING\n",
      "760\n",
      "CREATING\n",
      "770\n",
      "CREATING\n",
      "780\n",
      "CREATING\n",
      "790\n",
      "CREATING\n",
      "800\n",
      "CREATING\n",
      "810\n",
      "CREATING\n",
      "820\n",
      "CREATING\n",
      "830\n",
      "CREATING\n",
      "840\n",
      "CREATING\n",
      "850\n",
      "CREATING\n",
      "860\n",
      "CREATING\n",
      "870\n",
      "CREATING\n",
      "880\n",
      "CREATING\n",
      "890\n",
      "CREATING\n",
      "900\n",
      "CREATING\n",
      "910\n",
      "CREATING\n",
      "920\n",
      "CREATING\n",
      "930\n",
      "CREATING\n",
      "940\n",
      "CREATING\n",
      "950\n",
      "CREATING\n",
      "960\n",
      "CREATING\n",
      "970\n",
      "CREATING\n",
      "980\n",
      "CREATING\n",
      "990\n",
      "CREATING\n",
      "1000\n",
      "CREATING\n",
      "1010\n",
      "CREATING\n",
      "1020\n",
      "CREATING\n",
      "1030\n",
      "CREATING\n",
      "1040\n",
      "CREATING\n",
      "1050\n",
      "CREATING\n",
      "1060\n",
      "CREATING\n",
      "1070\n",
      "CREATING\n",
      "1080\n",
      "CREATING\n",
      "1090\n",
      "CREATING\n",
      "1100\n",
      "CREATING\n",
      "1110\n",
      "CREATING\n",
      "1120\n",
      "CREATING\n",
      "1130\n",
      "CREATING\n",
      "1140\n",
      "CREATING\n",
      "1150\n",
      "CREATING\n",
      "1160\n",
      "CREATING\n",
      "1170\n",
      "ACTIVE\n",
      "1180\n"
     ]
    }
   ],
   "source": [
    "i=0\n",
    "while True:\n",
    "    dataImportStatus = forecast.describe_dataset_import_job(DatasetName=datasetName,VersionId=ds_versionId)['Status']\n",
    "    print(dataImportStatus)\n",
    "    print(i*10)\n",
    "    i=i+1\n",
    "    if dataImportStatus != 'ACTIVE' and dataImportStatus != 'FAILED':\n",
    "        sleep(10)\n",
    "    else:\n",
    "        break\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DatasetArn': 'arn:aws:forecast:us-west-2:073138737237:ds/accounting_forecast_v5_ds',\n",
       " 'DatasetName': 'accounting_forecast_v5_ds',\n",
       " 'VersionId': '1be23fa8',\n",
       " 'Status': 'ACTIVE',\n",
       " 'FieldStatistics': {'Ad_Supported_Audio_Streams': {'Count': 312,\n",
       "   'CountDistinct': 172,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '1942.272323',\n",
       "   'Avg': 334.7521734839743,\n",
       "   'Stddev': 591.004853991729},\n",
       "  'Cloud_Match_Units': {'Count': 312,\n",
       "   'CountDistinct': 39,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '22483.502715',\n",
       "   'Avg': 119.56898417628206,\n",
       "   'Stddev': 1281.5244932753742},\n",
       "  'Download_Albums': {'Count': 312,\n",
       "   'CountDistinct': 133,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '112708.799995',\n",
       "   'Avg': 5212.891631464743,\n",
       "   'Stddev': 10614.360376791536},\n",
       "  'Download_Tracks': {'Count': 312,\n",
       "   'CountDistinct': 140,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '43508.244579',\n",
       "   'Avg': 2869.129437939103,\n",
       "   'Stddev': 5566.332855863449},\n",
       "  'Non_interactive_Radio': {'Count': 312,\n",
       "   'CountDistinct': 28,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '512.163509',\n",
       "   'Avg': 16.662813272435894,\n",
       "   'Stddev': 66.676748316807},\n",
       "  'Streaming_Bonus': {'Count': 312,\n",
       "   'CountDistinct': 2,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '373.100929',\n",
       "   'Avg': 1.195836310897436,\n",
       "   'Stddev': 21.12268066623567},\n",
       "  'Subscription_Audio_Streams': {'Count': 312,\n",
       "   'CountDistinct': 217,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '20274.749353',\n",
       "   'Avg': 3885.9500986250014,\n",
       "   'Stddev': 6044.261336145459},\n",
       "  'Subscription_Video_Streams': {'Count': 312,\n",
       "   'CountDistinct': 26,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '33.964542',\n",
       "   'Avg': 1.5041982179487179,\n",
       "   'Stddev': 5.228372027066128},\n",
       "  'Upgraded_Download_Tracks': {'Count': 312,\n",
       "   'CountDistinct': 32,\n",
       "   'CountNull': 0,\n",
       "   'Min': '-0.15',\n",
       "   'Max': '34.342685',\n",
       "   'Avg': 0.32573170192307693,\n",
       "   'Stddev': 2.2880563569632755},\n",
       "  'Video_Download_Purchases': {'Count': 312,\n",
       "   'CountDistinct': 95,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.0',\n",
       "   'Max': '309.055397',\n",
       "   'Avg': 8.601176131410256,\n",
       "   'Stddev': 26.880984105560252},\n",
       "  'date': {'Count': 312,\n",
       "   'CountDistinct': 132,\n",
       "   'CountNull': 0,\n",
       "   'Min': '2004-03-01T00:00:00Z',\n",
       "   'Max': '2018-08-01T00:00:00Z'},\n",
       "  'item': {'Count': 312, 'CountDistinct': 1, 'CountNull': 0},\n",
       "  'sales': {'Count': 312,\n",
       "   'CountDistinct': 312,\n",
       "   'CountNull': 0,\n",
       "   'Min': '29.0',\n",
       "   'Max': '1.2157463E7',\n",
       "   'Avg': 1180733.173076923,\n",
       "   'Stddev': 1810509.33123693},\n",
       "  'store_id': {'Count': 312,\n",
       "   'CountDistinct': 3,\n",
       "   'CountNull': 0,\n",
       "   'Min': '1',\n",
       "   'Max': '348',\n",
       "   'Avg': 180.92307692307693,\n",
       "   'Stddev': 156.0844251088596},\n",
       "  'target': {'Count': 312,\n",
       "   'CountDistinct': 312,\n",
       "   'CountNull': 0,\n",
       "   'Min': '0.2175',\n",
       "   'Max': '127327.130063',\n",
       "   'Avg': 12460.616849096154,\n",
       "   'Stddev': 14137.171761760064}},\n",
       " 'ResponseMetadata': {'RequestId': '3efba0c6-87ea-4049-b541-154945f527cc',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:55:11 GMT',\n",
       "   'x-amzn-requestid': '3efba0c6-87ea-4049-b541-154945f527cc',\n",
       "   'content-length': '2320',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.describe_dataset_import_job(DatasetName=datasetName,VersionId=ds_versionId)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Recipe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'RecipeNames': ['forecast_ARIMA',\n",
       "  'forecast_DEEP_AR',\n",
       "  'forecast_DEEP_AR_PLUS',\n",
       "  'forecast_ETS',\n",
       "  'forecast_MDN',\n",
       "  'forecast_MQRNN',\n",
       "  'forecast_NPTS',\n",
       "  'forecast_PROPHET',\n",
       "  'forecast_SQF'],\n",
       " 'ResponseMetadata': {'RequestId': '6ff68ce2-2ce2-4028-bcf5-972243bf0aa1',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:55:34 GMT',\n",
       "   'x-amzn-requestid': '6ff68ce2-2ce2-4028-bcf5-972243bf0aa1',\n",
       "   'content-length': '174',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recipesResponse=forecast.list_recipes()\n",
    "recipesResponse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get details about each recipe."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Recipe': {'Name': 'forecast_MQRNN',\n",
       "  'Train': [{'TrainingInfo': {'TrainedModelName': 'algorithm_MQRNN',\n",
       "     'AlgorithmName': 'MQRNN',\n",
       "     'TrainingParameters': {'epochs': '60',\n",
       "      'learning_rate': '3E-3',\n",
       "      'mini_batch_size': '32',\n",
       "      'quantiles': '[0.1,0.5,0.9]'}},\n",
       "    'BackTestWindowCount': 1,\n",
       "    'MetricsBuckets': []}]},\n",
       " 'ResponseMetadata': {'RequestId': '089d72d0-ebae-430e-854f-029294010531',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:55:37 GMT',\n",
       "   'x-amzn-requestid': '089d72d0-ebae-430e-854f-029294010531',\n",
       "   'content-length': '281',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.describe_recipe(RecipeName='forecast_MQRNN')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create Solution with customer forecast horizon"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Forecast horizon is how long in future the forecast should be predicting. For weekly data, a value of 12 means 1 weeks. Our example is hourly data, we try forecast the next day, so we can set to 24."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "predictorName= project+'_mqrnn'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "forecastHorizon = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "createPredictorResponse=forecast.create_predictor(RecipeName='forecast_MQRNN',DatasetGroupName= datasetGroupName ,PredictorName=predictorName, \n",
    "  ForecastHorizon = forecastHorizon)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "predictorVerionId=createPredictorResponse['VersionId']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'PredictorVersions': [{'PredictorName': 'accounting_forecast_v5_mqrnn',\n",
       "   'VersionId': '2fe7438b'}],\n",
       " 'ResponseMetadata': {'RequestId': '96dd400e-ea33-4f66-b54f-a5c247a72e2d',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 15:56:04 GMT',\n",
       "   'x-amzn-requestid': '96dd400e-ea33-4f66-b54f-a5c247a72e2d',\n",
       "   'content-length': '95',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.list_predictor_versions(PredictorName=predictorName)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the status of solutions, when the status change from **CREATING** to **ACTIVE**, we can continue to next steps. Depending on data size, model selection and hyper parameters，it can take 10 mins to more than one hour to be **ACTIVE**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CREATING\n",
      "0\n",
      "CREATING\n",
      "10\n",
      "CREATING\n",
      "20\n",
      "CREATING\n",
      "30\n",
      "CREATING\n",
      "40\n",
      "CREATING\n",
      "50\n",
      "CREATING\n",
      "60\n",
      "CREATING\n",
      "70\n",
      "CREATING\n",
      "80\n",
      "CREATING\n",
      "90\n",
      "CREATING\n",
      "100\n",
      "CREATING\n",
      "110\n",
      "CREATING\n",
      "120\n",
      "CREATING\n",
      "130\n",
      "CREATING\n",
      "140\n",
      "CREATING\n",
      "150\n",
      "CREATING\n",
      "160\n",
      "CREATING\n",
      "170\n",
      "CREATING\n",
      "180\n",
      "CREATING\n",
      "190\n",
      "CREATING\n",
      "200\n",
      "CREATING\n",
      "210\n",
      "FAILED\n",
      "220\n"
     ]
    }
   ],
   "source": [
    "i=0\n",
    "while True:\n",
    "    predictorStatus = forecast.describe_predictor(PredictorName=predictorName,VersionId=predictorVerionId)['Status']\n",
    "    print(predictorStatus)\n",
    "    print(i*10)\n",
    "    i=i+1\n",
    "    if predictorStatus != 'ACTIVE' and predictorStatus != 'FAILED':\n",
    "        sleep(10)\n",
    "    else:\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'PredictorName': 'accounting_forecast_v5_mqrnn',\n",
       " 'VersionId': '2fe7438b',\n",
       " 'Status': 'FAILED',\n",
       " 'CreationStartTime': '2019-01-11T15:55:53.596Z',\n",
       " 'PredictorArn': 'arn:aws:forecast:us-west-2:073138737237:predictor/accounting_forecast_v5_mqrnn',\n",
       " 'RecipeName': 'forecast_MQRNN',\n",
       " 'DatasetGroup': 'accounting_forecast_v5_gp',\n",
       " 'RecipeParameters': {},\n",
       " 'ResponseMetadata': {'RequestId': '678003f0-5698-4e49-bb5a-fd2c7661a3b7',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 16:00:12 GMT',\n",
       "   'x-amzn-requestid': '678003f0-5698-4e49-bb5a-fd2c7661a3b7',\n",
       "   'content-length': '327',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecast.describe_predictor(PredictorName=predictorName,VersionId=predictorVerionId)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get Error Metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'ModelMetrics': {},\n",
       " 'ResponseMetadata': {'RequestId': '9060e831-df45-40f7-a6f7-12a396b20982',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 07:44:15 GMT',\n",
       "   'x-amzn-requestid': '9060e831-df45-40f7-a6f7-12a396b20982',\n",
       "   'content-length': '19',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forecastquery.get_accuracy_metrics(PredictorName=predictorName)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Deploy Predictor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forecast.deploy_predictor(PredictorName=predictorName)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "deployedPredictorsResponse=forecast.list_deployed_predictors()\n",
    "print(deployedPredictorsResponse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Please note that the following cell can also take 10 minutes or more to be fully operational. There's no output here, but that is fine as long as the * is there."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "while True:\n",
    "    deployedPredictorStatus = forecast.describe_deployed_predictor(PredictorName=predictorName)['Status']\n",
    "    print(deployedPredictorStatus)\n",
    "    if deployedPredictorStatus != 'ACTIVE' and deployedPredictorStatus != 'FAILED':\n",
    "        sleep(30)\n",
    "    else:\n",
    "        break\n",
    "print(deployedPredictorStatus)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get Forecast"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When the solution is deployed and forecast results are ready, you can view them. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forecastResponse = forecastquery.get_forecast(\n",
    "    PredictorName=predictorName,\n",
    "    Interval=\"hour\",\n",
    "    Filters={\"item_id\":\"client_12\"}\n",
    ")\n",
    "print(forecastResponse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Export Forecast"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### You can batch export forecast to s3 bucket. To do so an role with s3 put access is needed, but this has already been created."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forecastInfoList= forecast.list_forecasts(PredictorName=predictorName)['ForecastInfoList']\n",
    "forecastId= forecastInfoList[0]['ForecastId']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "outputPath=\"s3://\"+bucketName+\"/output\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forecastExportResponse = forecast.create_forecast_export_job(ForecastId=forecastId, OutputPath={\"S3Uri\": outputPath,\"RoleArn\":roleArn})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "forecastExportJobId = forecastExportResponse['ForecastExportJobId']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "while True:\n",
    "    forecastExportStatus = forecast.describe_forecast_export_job(ForecastExportJobId=forecastExportJobId)['Status']\n",
    "    print(forecastExportStatus)\n",
    "    if forecastExportStatus != 'ACTIVE' and forecastExportStatus != 'FAILED':\n",
    "        sleep(30)\n",
    "    else:\n",
    "        break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check s3 bucket for results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s3.list_objects(Bucket=bucketName,Prefix=\"output\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cleanup\n",
    "\n",
    "While Forecast is in preview there are no charges for using it, but to future proof this work below are the instructions to cleanup your work space."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete Deployed Predictor \n",
    "forecast.delete_deployed_predictor(PredictorName=predictorName)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'PredictorName': 'accounting_forecast_V3_mqrnn',\n",
       " 'ResponseMetadata': {'RequestId': 'aa05047b-e14c-4e0b-9be6-42c90f4b0194',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 14:51:32 GMT',\n",
       "   'x-amzn-requestid': 'aa05047b-e14c-4e0b-9be6-42c90f4b0194',\n",
       "   'content-length': '48',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Delete the Predictor: \n",
    "forecast.delete_predictor(PredictorName=predictorName)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DatasetName': 'accounting_forecast_V3_ds',\n",
       " 'ResponseMetadata': {'RequestId': '64dd406d-1529-49b7-8d52-a83239bcc01a',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 14:51:27 GMT',\n",
       "   'x-amzn-requestid': '64dd406d-1529-49b7-8d52-a83239bcc01a',\n",
       "   'content-length': '43',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Delete Import\n",
    "forecast.delete_dataset_import(DatasetName=datasetName)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'ResponseMetadata': {'RequestId': '74570c74-e159-4909-b366-95198928f5cb',\n",
       "  'HTTPStatusCode': 200,\n",
       "  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1',\n",
       "   'date': 'Fri, 11 Jan 2019 14:51:31 GMT',\n",
       "   'x-amzn-requestid': '74570c74-e159-4909-b366-95198928f5cb',\n",
       "   'content-length': '2',\n",
       "   'connection': 'keep-alive'},\n",
       "  'RetryAttempts': 0}}"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Delete Dataset Group\n",
    "forecast.delete_dataset_group(DatasetGroupName=datasetGroupName)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "conda_python3",
   "language": "python",
   "name": "conda_python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
