{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Part I\n\nThere exists some value $x$ such that it minimizes the the RMSLE metric for train. \n\nPart 1 - Find the value that minimizes training RMSLE <br>\nPart 2 - If the value that minimizes train RMSLE also translates to LB, we will go deeper and see if there is anything else we can discover"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport feather\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom numba import jit\nfrom tqdm import tqdm_notebook as tqdm\nimport warnings\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_df = feather.read_dataframe('../input/ashrae-feather/train.ft')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"RMSE is 2x as faster to calculate than RMSLE (log increases calculation time), however, we'll stick to RMSLE for our experiments.\n\nIn order to achieve optimal speed calculating the RMSLE, I made sure both prediction and ground truths are float32. Numpy makes sure to cast both arrays into the same dtype before calculating and if you don't specify float32, it will default to int64 and thus both arrays will end up casting into float64. Such a tiny detail can increase calulation time by 2x."},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# loss functions\n\n# Root Mean Squared Error\ndef rmse(ytrue, ypred):\n    return np.sqrt(np.mean(np.square(ypred - ytrue), axis=0))\n\n# Root Mean Squared Log Error\ndef rmsle(ytrue, ypred):\n    return np.sqrt(np.mean(np.square(np.log1p(ypred) - np.log1p(ytrue)), axis=0))\n\n# Function to find a singular minimum value\ndef minimize(i):\n    return rmsle(train_df['meter_reading'].values, np.full(len(train_df), i, dtype=np.float32))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f\"Mean Meter Reading: {np.mean(train_df['meter_reading'].values):.2f}\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"%%time\nm = []\nfor i in range(2117):\n    m.append(minimize(i))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.title('Finding the minimum $x$')\nplt.ylabel('RMSLE')\nplt.xlabel('$x$')\nplt.xscale('log')\nplt.plot(np.arange(2117), m)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Min RMSLE of {np.min(m):.2f} is found at x={np.argmin(m)}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Part II\n\nNow that we saw that the min value in pt. 1 translated over to LB nicely, we will look at the 'meter' variable\n\nNow let $x$ represent the variable 'meter' and $x_i$ represent the values that minimize each meter [0 - 3]\n\nThese exists some minimum for $x_0$, $x_1$, $x_2$, $x_3$ respectively such that min($x_0$) + min($x_1$) + min($x_2$) + min($x_3$) achieves the lowest RSMLE\n\nUsing the same technique above, let's see if we can find the minimum values of $x_i$"},{"metadata":{"trusted":true},"cell_type":"code","source":"def min_x(i, y_true):\n    return rmsle(y_true, np.full(len(y_true), i, dtype=np.float32))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.groupby('meter')['meter_reading'].agg(np.mean)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"%%time\nm0, m1, m2, m3 = [],[],[],[]\nfor i in tqdm(range(0,1000,10)):\n    m0.append(min_x(i, train_df[train_df['meter'] == 0]['meter_reading'].values))\n    \nfor i in tqdm(range(0,2000,10)):\n    m1.append(min_x(i, train_df[train_df['meter'] == 1]['meter_reading'].values))\n    \nfor i in tqdm(range(0,20000,10)):\n    m2.append(min_x(i, train_df[train_df['meter'] == 2]['meter_reading'].values))\n    \nfor i in tqdm(range(0,2000,10)):\n    m3.append(min_x(i, train_df[train_df['meter'] == 3]['meter_reading'].values))","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12,12))\n\nplt.subplot(221)\nplt.title('Finding the minimum $x_0$')\nplt.ylabel('RMSLE')\nplt.xlabel('$x_0$')\nplt.xscale('log')\nplt.plot(np.arange(0,1000,10), m0)\n\nplt.subplot(222)\nplt.title('Finding the minimum $x_1$')\nplt.ylabel('RMSLE')\nplt.xlabel('$x_1$')\nplt.xscale('log')\nplt.plot(np.arange(0,2000,10), m1)\n\nplt.subplot(223)\nplt.title('Finding the minimum $x_2$')\nplt.ylabel('RMSLE')\nplt.xlabel('$x_2$')\nplt.xscale('log')\nplt.plot(np.arange(0,20000,10), m2)\n\nplt.subplot(224)\nplt.title('Finding the minimum $x_3$')\nplt.ylabel('RMSLE')\nplt.xlabel('$x_3$')\nplt.xscale('log')\nplt.plot(np.arange(0,2000,10), m3)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'x0: Min RMSLE of {np.min(m0):.2f} is found at x={np.argmin(m0)*10}')\nprint(f'x1: Min RMSLE of {np.min(m1):.2f} is found at x={np.argmin(m1)*10}')\nprint(f'x2: Min RMSLE of {np.min(m2):.2f} is found at x={np.argmin(m2)*10}')\nprint(f'x3: Min RMSLE of {np.min(m3):.2f} is found at x={np.argmin(m3)*10}')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"%%time\n# do this one more time to get to a closer minimum for each x\nm0, m1, m2, m3 = [],[],[],[]\nfor i in tqdm(range(40,60)):\n    m0.append(min_x(i, train_df[train_df['meter'] == 0]['meter_reading'].values))\n    \nfor i in tqdm(range(60,80)):\n    m1.append(min_x(i, train_df[train_df['meter'] == 1]['meter_reading'].values))\n    \nfor i in tqdm(range(160,180)):\n    m2.append(min_x(i, train_df[train_df['meter'] == 2]['meter_reading'].values))\n    \nfor i in tqdm(range(10,30)):\n    m3.append(min_x(i, train_df[train_df['meter'] == 3]['meter_reading'].values))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'x0: Min RMSLE of {np.min(m0):.3f} is found at x0={np.argmin(m0)+40}')\nprint(f'x1: Min RMSLE of {np.min(m1):.3f} is found at x1={np.argmin(m1)+60}')\nprint(f'x2: Min RMSLE of {np.min(m2):.3f} is found at x2={np.argmin(m2)+160}')\nprint(f'x3: Min RMSLE of {np.min(m3):.3f} is found at x3={np.argmin(m3)+10}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"p0 = np.full(len(train_df[train_df['meter']==0]), 52)\np1 = np.full(len(train_df[train_df['meter']==1]), 69)\np2 = np.full(len(train_df[train_df['meter']==2]), 167)\np3 = np.full(len(train_df[train_df['meter']==3]), 27)\ng0 = train_df[train_df['meter']==0]['meter_reading'].values\ng1 = train_df[train_df['meter']==1]['meter_reading'].values\ng2 = train_df[train_df['meter']==2]['meter_reading'].values\ng3 = train_df[train_df['meter']==3]['meter_reading'].values\np = []\ng = []\np += list(p0)\np += list(p1)\np += list(p2)\np += list(p3)\ng += list(g0)\ng += list(g1)\ng += list(g2)\ng += list(g3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f\"Total RMSLE: {rmsle(np.array(g), np.array(p)):.3f}\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Slight decrease in RMSLE over pt. 1"},{"metadata":{},"cell_type":"markdown","source":"# Submission File"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nsub = pd.read_csv('../input/ashrae-energy-prediction/sample_submission.csv', dtype={'row_id': 'int32', 'meter_reading': 'int8'})\nsub['meter_reading'] = 62\nsub['meter_reading'] = sub['meter_reading'].astype('int8')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nsub.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}