{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Thanks for @abhishek123maurya 's [awesome notebook](https://www.kaggle.com/code/abhishek123maurya/2-anomaly-detection-features-csv) !\n#### Starting from his notebook, I made following changes:\n#### 1. Add lag features of difference with varying shift numbers (e.g., feat_lag1 = meter_reading(t)-meter_reading(t-1), feat_lag-1 = meter_reading(t)-meter_reading(t+1))\n#### 2. Split train/valid data by `building_id`\n#### 3. Post-processing the prediction result by setting zero to rows with 1.0 of `meter_reading`\n#### 4. Ensembling of lgb and xgb models","metadata":{}},{"cell_type":"markdown","source":"# <p style=\"text-align:center;font-size:150%;font-family:Roboto;background-color:#a04070;border-radius:50px;font-weight:bold;margin-bottom:0\">Large Scale Energy Anomaly Detection</p>\n\n<p style=\"font-family:Roboto;font-size:140%;color:#a04070;\">In this Notebook, I had implemented the anomaly detection model to predict whether the energy usage in a building is anomalous or not. This will help to save a lot of energy. In this notebook I had used the <code>train_features.csv</code> data to build a model. Look at my this <a href='', target='_blank'>notebook</a> in which I had implement a model by just using the train.csv data.<p> \n\n<!-- <a id='top'></a> -->\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<p style=\"background-color:#a04070;font-family:Roboto;font-size:160%;text-align:center;border-radius:50px;\">TABLE OF CONTENTS</p>   \n    \n* [1. Importing Libraries](#1)\n    \n* [2. Exploratory Data Analysis](#2)\n    \n* [3. Highly Correlated Features](#3)\n    \n* [4. Model Development](#4) \n    \n* [5. The End](#5) \n\n<a id=\"1\"></a>\n# <p style=\"background-color:#a04070;font-family:Roboto;font-size:120%;text-align:center;border-radius:50px;margin-bottom:0\">IMPORTING LIBRARIES</p>","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sb\nfrom tqdm import tqdm, trange\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelEncoder, StandardScaler\nfrom sklearn import metrics\nfrom xgboost import XGBClassifier\nfrom sklearn.linear_model import LogisticRegression\nfrom imblearn.over_sampling import RandomOverSampler\n\nimport lightgbm as lgb\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly.graph_objs as go\nimport plotly\nfrom plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot\nimport cufflinks as cf\ncf.set_config_file(offline=True)\n# Input data files are available i\n\nimport datetime\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras import layers\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:03.975127Z","iopub.execute_input":"2022-06-29T02:13:03.975522Z","iopub.status.idle":"2022-06-29T02:13:11.31023Z","shell.execute_reply.started":"2022-06-29T02:13:03.97542Z","shell.execute_reply":"2022-06-29T02:13:11.309234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2\"></a>\n# <p style=\"background-color:#a04070;font-family:Roboto;font-size:120%;text-align:center;border-radius:50px;margin-bottom:0\">Exploratory Data Analysis</p>\n<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">We have been provided with a whole lot of features. As per the Author of the competition data and cleaned and one can focused on the model building but till we are not sure with the features provided and what they represent how can we go forward.</p>","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('../input/energy-anomaly-detection/train_features.csv')\ntrain.shape","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:11.312168Z","iopub.execute_input":"2022-06-29T02:13:11.312546Z","iopub.status.idle":"2022-06-29T02:13:29.69757Z","shell.execute_reply.started":"2022-06-29T02:13:11.312509Z","shell.execute_reply":"2022-06-29T02:13:29.696989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:29.698529Z","iopub.execute_input":"2022-06-29T02:13:29.699261Z","iopub.status.idle":"2022-06-29T02:13:29.729328Z","shell.execute_reply.started":"2022-06-29T02:13:29.699229Z","shell.execute_reply":"2022-06-29T02:13:29.728436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for col in train.columns:\n    k = train[col].isnull().sum()\n    if k > 0:\n        print(f'{col} : {k}')","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:29.731477Z","iopub.execute_input":"2022-06-29T02:13:29.731738Z","iopub.status.idle":"2022-06-29T02:13:31.378151Z","shell.execute_reply.started":"2022-06-29T02:13:29.731705Z","shell.execute_reply":"2022-06-29T02:13:31.377066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">In this data as well only <code>meter_reading</code> has null values.</p>","metadata":{}},{"cell_type":"code","source":"train[train['anomaly']==1].isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:31.379399Z","iopub.execute_input":"2022-06-29T02:13:31.379654Z","iopub.status.idle":"2022-06-29T02:13:31.467663Z","shell.execute_reply.started":"2022-06-29T02:13:31.379624Z","shell.execute_reply":"2022-06-29T02:13:31.466752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">There are no such entries where it is an anomalous case and <code>meter_reading</code> is null.</p>","metadata":{}},{"cell_type":"code","source":"train[train['meter_reading']==1.0]['anomaly'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:31.468776Z","iopub.execute_input":"2022-06-29T02:13:31.469105Z","iopub.status.idle":"2022-06-29T02:13:31.497511Z","shell.execute_reply.started":"2022-06-29T02:13:31.469073Z","shell.execute_reply":"2022-06-29T02:13:31.496591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">Very nice observation indeed has been shown in this <a href='https://www.kaggle.com/competitions/energy-anomaly-detection/discussion/326252' target='_blank'>discussion</a>.</p>","metadata":{}},{"cell_type":"code","source":"for idx in tqdm(train['building_id'].unique()):\n    if train[train['building_id']==idx]['primary_use'].nunique()>1:\n        print(idx)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:31.499265Z","iopub.execute_input":"2022-06-29T02:13:31.499771Z","iopub.status.idle":"2022-06-29T02:13:35.865513Z","shell.execute_reply.started":"2022-06-29T02:13:31.499722Z","shell.execute_reply":"2022-06-29T02:13:35.864519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mean_by_use = train.groupby('primary_use').mean()['meter_reading']\nmean_by_use.plot.bar()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:35.867062Z","iopub.execute_input":"2022-06-29T02:13:35.867701Z","iopub.status.idle":"2022-06-29T02:13:37.161797Z","shell.execute_reply.started":"2022-06-29T02:13:35.86765Z","shell.execute_reply":"2022-06-29T02:13:37.161123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">Each building provides only one type of facility/usecase and above chart shows the mean usage by use case throughout the year with minimum at the religious places and highest at the Education institutions.</p>\n<br>\n<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">Now let's explore what are the different features has been provided in this data as compare to the train.csv.</p>","metadata":{}},{"cell_type":"code","source":"ints = []\nobjects = []\nfloats = []\n\nfor col in train.columns:\n    if train[col].dtype == int:\n        ints.append(col)\n    elif train[col].dtype == object:\n        objects.append(col)\n    else:\n        floats.append(col)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:37.162862Z","iopub.execute_input":"2022-06-29T02:13:37.163651Z","iopub.status.idle":"2022-06-29T02:13:37.169302Z","shell.execute_reply.started":"2022-06-29T02:13:37.163612Z","shell.execute_reply":"2022-06-29T02:13:37.168683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#cc107e;font-family:Roboto;font-size:180%;margin-bottom:0\">Analysis of the columns with <code>int</code> datatype.</p>","metadata":{}},{"cell_type":"code","source":"ints","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:37.172815Z","iopub.execute_input":"2022-06-29T02:13:37.173739Z","iopub.status.idle":"2022-06-29T02:13:37.188827Z","shell.execute_reply.started":"2022-06-29T02:13:37.173698Z","shell.execute_reply":"2022-06-29T02:13:37.187775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">Columns from <code>hour</code> to <code>is_holiday</code> is nothing but the expanded form of the timestamp so, we can remove that feature.</p>","metadata":{}},{"cell_type":"code","source":"train[ints].nunique()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:37.190437Z","iopub.execute_input":"2022-06-29T02:13:37.19096Z","iopub.status.idle":"2022-06-29T02:13:37.389682Z","shell.execute_reply.started":"2022-06-29T02:13:37.190905Z","shell.execute_reply":"2022-06-29T02:13:37.388689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.subplots(figsize=(15,15))\nsample = ['site_id', 'year_built', 'cloud_coverage', 'floor_count', 'wind_direction']\n\nfor i, col in enumerate(sample):\n    plt.subplot(3,2,i+1)\n    sb.countplot(train[col], hue=train['anomaly'])\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:37.391116Z","iopub.execute_input":"2022-06-29T02:13:37.394177Z","iopub.status.idle":"2022-06-29T02:13:40.911939Z","shell.execute_reply.started":"2022-06-29T02:13:37.394135Z","shell.execute_reply":"2022-06-29T02:13:40.910919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['year_built'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:40.913017Z","iopub.execute_input":"2022-06-29T02:13:40.913254Z","iopub.status.idle":"2022-06-29T02:13:40.932786Z","shell.execute_reply.started":"2022-06-29T02:13:40.913225Z","shell.execute_reply":"2022-06-29T02:13:40.931895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['cloud_coverage'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:40.934632Z","iopub.execute_input":"2022-06-29T02:13:40.935278Z","iopub.status.idle":"2022-06-29T02:13:40.96226Z","shell.execute_reply.started":"2022-06-29T02:13:40.935228Z","shell.execute_reply":"2022-06-29T02:13:40.961311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<ul style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\"><li><code>year_built</code> - To get the exact <code>year_built</code> add <code>1900</code> to the same </li><li><code>cloud_coverage</code> - It has all values from <code>0 - 9</code>. But the value <code>255</code> in both <code>year_built</code> and <code>cloud_coverage</code> are replacement for the null values.</li></ul>","metadata":{}},{"cell_type":"code","source":"train['cloud_coverage'] = train['cloud_coverage'].replace({255:10})\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:40.963833Z","iopub.execute_input":"2022-06-29T02:13:40.964676Z","iopub.status.idle":"2022-06-29T02:13:41.010394Z","shell.execute_reply.started":"2022-06-29T02:13:40.964627Z","shell.execute_reply":"2022-06-29T02:13:41.009462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for col in train.columns:\n    if train[col].nunique()==1:\n        print(col, train[col].dtype)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:41.012001Z","iopub.execute_input":"2022-06-29T02:13:41.012493Z","iopub.status.idle":"2022-06-29T02:13:42.945922Z","shell.execute_reply.started":"2022-06-29T02:13:41.012438Z","shell.execute_reply":"2022-06-29T02:13:42.944898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">No use of columns in the modelling with only one values for all the entries.</p>","metadata":{}},{"cell_type":"code","source":"train['date'] = pd.to_datetime(train['timestamp']).dt.date\ntrain['meterReadings_daily_std'] = train.groupby(['building_id','date'])['meter_reading'].transform('std')","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:42.94734Z","iopub.execute_input":"2022-06-29T02:13:42.94795Z","iopub.status.idle":"2022-06-29T02:13:44.598751Z","shell.execute_reply.started":"2022-06-29T02:13:42.947899Z","shell.execute_reply":"2022-06-29T02:13:44.597927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = train.drop(['timestamp', 'year', 'gte_meter'], axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:44.600364Z","iopub.execute_input":"2022-06-29T02:13:44.600817Z","iopub.status.idle":"2022-06-29T02:13:45.50247Z","shell.execute_reply.started":"2022-06-29T02:13:44.600782Z","shell.execute_reply":"2022-06-29T02:13:45.50144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#cc107e;font-family:Roboto;font-size:180%;margin-bottom:0\">Analysis of the columns with <code>object</code> datatype.</p>","metadata":{}},{"cell_type":"code","source":"objects","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:45.503668Z","iopub.execute_input":"2022-06-29T02:13:45.503952Z","iopub.status.idle":"2022-06-29T02:13:45.510261Z","shell.execute_reply.started":"2022-06-29T02:13:45.503906Z","shell.execute_reply":"2022-06-29T02:13:45.509621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['building_month'].unique()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:45.511327Z","iopub.execute_input":"2022-06-29T02:13:45.512017Z","iopub.status.idle":"2022-06-29T02:13:45.650886Z","shell.execute_reply.started":"2022-06-29T02:13:45.511957Z","shell.execute_reply":"2022-06-29T02:13:45.650264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">It seems like these features are nothing but the concatenation of the <code>building_id</code> with the <code>month</code>, <code>hour</code> or other time realted features. In my opinion these are not going to help us as none of the values will overlap with the test data as the building id's are totally different for the test data set. So, the distribution of the data will vary.</p>","metadata":{}},{"cell_type":"code","source":"train = train.drop(objects[2:], axis=1)\nprint(train.shape)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:45.652013Z","iopub.execute_input":"2022-06-29T02:13:45.65236Z","iopub.status.idle":"2022-06-29T02:13:45.910605Z","shell.execute_reply.started":"2022-06-29T02:13:45.65233Z","shell.execute_reply":"2022-06-29T02:13:45.909407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#cc107e;font-family:Roboto;font-size:180%;margin-bottom:0\">Analysis of the columns with <code>float</code> datatype.</p>","metadata":{}},{"cell_type":"code","source":"floats","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:45.911998Z","iopub.execute_input":"2022-06-29T02:13:45.912257Z","iopub.status.idle":"2022-06-29T02:13:45.918603Z","shell.execute_reply.started":"2022-06-29T02:13:45.912225Z","shell.execute_reply":"2022-06-29T02:13:45.917717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">These features from it's name seems like they are derived by feature engineering from the time and the <code>building_id</code> except for some columns let's keep them as of now. It has been given in the data section that these features has been used by the winners so, may be these features proved to be helpful.</p>","metadata":{}},{"cell_type":"code","source":"def impute_nulls(data):\n    mean_reading = data.groupby('building_id').mean()['meter_reading']\n\n    building_id = mean_reading.index\n    values = mean_reading.values\n    \n    for i, idx in tqdm(enumerate(building_id)):\n        data[data['building_id']==idx] = data[data['building_id']==idx].fillna(values[i]) \n    \n    return data\n\ntrain = impute_nulls(train)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:13:45.919526Z","iopub.execute_input":"2022-06-29T02:13:45.919738Z","iopub.status.idle":"2022-06-29T02:15:41.973999Z","shell.execute_reply.started":"2022-06-29T02:13:45.919712Z","shell.execute_reply":"2022-06-29T02:15:41.973058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n# <p style=\"background-color:#a04070;font-family:Roboto;font-size:120%;text-align:center;border-radius:50px;margin-bottom:0\">Highly Correlated Features</p>\n<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">By the name of the columns it is clear that they have been derived by combining two or more succint features. In such cases there is possibility of having high correlation between the developed feature and the original feature. And as much as I know highly correlated features doesn't help model.</p>","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15,15))\nsb.heatmap(train.corr() > 0.95, annot=True, cbar=False)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:15:41.976054Z","iopub.execute_input":"2022-06-29T02:15:41.976414Z","iopub.status.idle":"2022-06-29T02:16:01.125911Z","shell.execute_reply.started":"2022-06-29T02:15:41.976363Z","shell.execute_reply":"2022-06-29T02:16:01.124948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.columns","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:16:01.127453Z","iopub.execute_input":"2022-06-29T02:16:01.128401Z","iopub.status.idle":"2022-06-29T02:16:01.1353Z","shell.execute_reply.started":"2022-06-29T02:16:01.128355Z","shell.execute_reply":"2022-06-29T02:16:01.134421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hcorr = [#'building_id',\n         #'site_id',\n #'year_built',\n #'square_feet',\n 'primary_use',\n #'floor_count',\n #'precip_depth_1_hr', 'sea_level_pressure',\n #'wind_direction', 'wind_speed',\n 'gte_meter_hour',\n 'gte_meter_weekday',\n 'gte_meter_month',\n 'gte_meter_building_id',\n 'gte_meter_primary_use',\n 'gte_meter_site_id',\n 'gte_meter_building_id_hour',\n 'gte_meter_building_id_weekday',\n 'gte_meter_building_id_month',\n 'air_temperature_mean_lag73',\n 'air_temperature_max_lag73',\n 'air_temperature_min_lag73',\n 'air_temperature_mean_lag7',\n 'air_temperature_max_lag7',\n 'air_temperature_min_lag7']\n\ntrain = train.drop(hcorr, axis=1)\ntrain.shape","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:16:01.136717Z","iopub.execute_input":"2022-06-29T02:16:01.136973Z","iopub.status.idle":"2022-06-29T02:16:01.318338Z","shell.execute_reply.started":"2022-06-29T02:16:01.136942Z","shell.execute_reply":"2022-06-29T02:16:01.317235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(15,15))\nsb.heatmap(train.corr() > 0.75, annot=True, cbar=False)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:16:01.319915Z","iopub.execute_input":"2022-06-29T02:16:01.320267Z","iopub.status.idle":"2022-06-29T02:16:10.824832Z","shell.execute_reply.started":"2022-06-29T02:16:01.320218Z","shell.execute_reply":"2022-06-29T02:16:10.823856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">Now, there are no highly correlated features and we are good to go and build our anomaly detection model.</p>","metadata":{}},{"cell_type":"markdown","source":"<a id=\"4\"></a>\n# <p style=\"background-color:#a04070;font-family:Roboto;font-size:120%;text-align:center;border-radius:50px;margin-bottom:0\">Model Development</p>\n<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">Training an XGBClassifier on millions of rows take hell lot of time that is why I have implemented a neural network model so, that the model can go through all the examples in feasible time. By using the RandomOverSampler I had balanced the negative and the positive exmaples so, that model can perform well for the negative as well as positive examples.</p>","metadata":{}},{"cell_type":"code","source":"test = pd.read_csv('../input/energy-anomaly-detection/test_features.csv', index_col=0)\ntest = impute_nulls(test)\ntest['cloud_coverage'] = test['cloud_coverage'].replace({255:10})\n\ntest['date'] = pd.to_datetime(test['timestamp']).dt.date\ntest['meterReadings_daily_std'] = test.groupby(['building_id','date'])['meter_reading'].transform('std')\n\ntest = test.drop(['timestamp', 'year', 'gte_meter'] + objects[2:] + hcorr, axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:16:10.829061Z","iopub.execute_input":"2022-06-29T02:16:10.829434Z","iopub.status.idle":"2022-06-29T02:19:22.275999Z","shell.execute_reply.started":"2022-06-29T02:16:10.8294Z","shell.execute_reply":"2022-06-29T02:19:22.274867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train['meter_reading'] = train['meter_reading']/train.groupby('building_id')['meter_reading'].transform('std')\n#test['meter_reading'] = test['meter_reading']/test.groupby('building_id')['meter_reading'].transform('std')","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:19:22.277775Z","iopub.execute_input":"2022-06-29T02:19:22.278156Z","iopub.status.idle":"2022-06-29T02:19:22.283209Z","shell.execute_reply.started":"2022-06-29T02:19:22.278092Z","shell.execute_reply":"2022-06-29T02:19:22.282246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train['meter_reading^2'] = train['meter_reading']**2\n#test['meter_reading^2'] = test['meter_reading']**2","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:19:22.284647Z","iopub.execute_input":"2022-06-29T02:19:22.285007Z","iopub.status.idle":"2022-06-29T02:19:22.296447Z","shell.execute_reply.started":"2022-06-29T02:19:22.284959Z","shell.execute_reply":"2022-06-29T02:19:22.295735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_feature = pd.read_csv('../input/energy-anomaly-detection/train_features.csv')\nfor shift_hours in tqdm([-1,1,-24,24,-7*24,7*24]):\n    meter_reading_shift = train_feature[['building_id', 'timestamp', 'meter_reading']]\n    meter_reading_shift['timestamp'] = pd.to_datetime(meter_reading_shift['timestamp']) + datetime.timedelta(hours=shift_hours)\n    meter_reading_shift['timestamp'] = meter_reading_shift['timestamp'].astype('str')\n    meter_reading_shift = meter_reading_shift.rename(columns={'meter_reading':'lag_value_'+str(shift_hours)})\n    train_feature = train_feature.merge(meter_reading_shift, on=['building_id', 'timestamp'], how='left')\n    \n    train['lag_value_'+str(shift_hours)] = train_feature['lag_value_'+str(shift_hours)]-train_feature['meter_reading']\n    \ntest_feature = pd.read_csv('../input/energy-anomaly-detection/test_features.csv')\nfor shift_hours in tqdm([-1,1,-24,24,-7*24,7*24]):\n    meter_reading_shift = test_feature[['building_id', 'timestamp', 'meter_reading']]\n    meter_reading_shift['timestamp'] = pd.to_datetime(meter_reading_shift['timestamp']) + datetime.timedelta(hours=shift_hours)\n    meter_reading_shift['timestamp'] = meter_reading_shift['timestamp'].astype('str')\n    meter_reading_shift = meter_reading_shift.rename(columns={'meter_reading':'lag_value_'+str(shift_hours)})\n    test_feature = test_feature.merge(meter_reading_shift, on=['building_id', 'timestamp'], how='left')\n    \n    test['lag_value_'+str(shift_hours)] = test_feature['lag_value_'+str(shift_hours)]-test_feature['meter_reading']","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:19:22.29786Z","iopub.execute_input":"2022-06-29T02:19:22.298708Z","iopub.status.idle":"2022-06-29T02:21:37.393176Z","shell.execute_reply.started":"2022-06-29T02:19:22.298654Z","shell.execute_reply":"2022-06-29T02:21:37.391916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.describe()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:37.395202Z","iopub.execute_input":"2022-06-29T02:21:37.395746Z","iopub.status.idle":"2022-06-29T02:21:40.311324Z","shell.execute_reply.started":"2022-06-29T02:21:37.395695Z","shell.execute_reply":"2022-06-29T02:21:40.310192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train['is_one'] = (train['meter_reading']==1).astype('int')\n#test['is_one'] = (test['meter_reading']==1).astype('int')","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:40.313046Z","iopub.execute_input":"2022-06-29T02:21:40.313357Z","iopub.status.idle":"2022-06-29T02:21:40.317767Z","shell.execute_reply.started":"2022-06-29T02:21:40.313311Z","shell.execute_reply":"2022-06-29T02:21:40.3165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = train.drop(['date','meterReadings_daily_std'],axis=1)\ntest = test.drop(['date','meterReadings_daily_std'],axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:33.097317Z","iopub.execute_input":"2022-06-29T02:27:33.097636Z","iopub.status.idle":"2022-06-29T02:27:33.601449Z","shell.execute_reply.started":"2022-06-29T02:27:33.097604Z","shell.execute_reply":"2022-06-29T02:27:33.600633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train.shape, test.shape)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:36.080744Z","iopub.execute_input":"2022-06-29T02:27:36.081565Z","iopub.status.idle":"2022-06-29T02:27:36.086685Z","shell.execute_reply.started":"2022-06-29T02:27:36.081509Z","shell.execute_reply":"2022-06-29T02:27:36.085922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"neg = train[train['anomaly'] == 0]\npos = train[train['anomaly'] == 1]\n\nprint(neg.shape, pos.shape)\nnegs1 = neg.sample(n = 37296, random_state=10)\nnegs2 = neg.sample(n = 37296, random_state=20)\ndf_eq = pd.concat([negs1, pos, negs2, pos], axis=0)\nprint(df_eq.shape)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:36.324985Z","iopub.execute_input":"2022-06-29T02:27:36.325636Z","iopub.status.idle":"2022-06-29T02:27:36.973455Z","shell.execute_reply.started":"2022-06-29T02:27:36.325594Z","shell.execute_reply":"2022-06-29T02:27:36.972524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features = df_eq.drop(['anomaly'], axis=1)\ntarget = df_eq['anomaly']","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:36.975087Z","iopub.execute_input":"2022-06-29T02:27:36.975309Z","iopub.status.idle":"2022-06-29T02:27:37.050592Z","shell.execute_reply.started":"2022-06-29T02:27:36.975282Z","shell.execute_reply":"2022-06-29T02:27:37.049769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features.columns","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:37.052676Z","iopub.execute_input":"2022-06-29T02:27:37.05295Z","iopub.status.idle":"2022-06-29T02:27:37.059858Z","shell.execute_reply.started":"2022-06-29T02:27:37.052916Z","shell.execute_reply":"2022-06-29T02:27:37.058811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = features[train_feature['building_id']%5<4]\nX_val = features[train_feature['building_id']%5==4]\nY_train = target[train_feature['building_id']%5<4]\nY_val = target[train_feature['building_id']%5==4]\n\nprint(X_train.shape, X_val.shape)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:37.423631Z","iopub.execute_input":"2022-06-29T02:27:37.423932Z","iopub.status.idle":"2022-06-29T02:27:37.591878Z","shell.execute_reply.started":"2022-06-29T02:27:37.423899Z","shell.execute_reply":"2022-06-29T02:27:37.590889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scaler = StandardScaler()\nX_train = scaler.fit_transform(X_train)\nX_val = scaler.transform(X_val)\ntest1 = scaler.transform(test)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:37.806824Z","iopub.execute_input":"2022-06-29T02:27:37.80714Z","iopub.status.idle":"2022-06-29T02:27:39.057644Z","shell.execute_reply.started":"2022-06-29T02:27:37.807109Z","shell.execute_reply":"2022-06-29T02:27:39.05682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = [XGBClassifier(), lgb.LGBMClassifier()]\n\nfor i in range(2):\n    models[i].fit(X_train, Y_train)\n\n    print(f'{models[i]} : ')\n    print('Training Accuracy : ', metrics.roc_auc_score(Y_train, models[i].predict_proba(X_train)[:,1]))\n    print('Validation Accuracy : ', metrics.roc_auc_score(Y_val, models[i].predict_proba(X_val)[:,1]))\n    print()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:27:39.059872Z","iopub.execute_input":"2022-06-29T02:27:39.06022Z","iopub.status.idle":"2022-06-29T02:28:23.574879Z","shell.execute_reply.started":"2022-06-29T02:27:39.060174Z","shell.execute_reply":"2022-06-29T02:28:23.573909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"color:#a04070;font-family:Roboto;font-size:140%;margin-bottom:0\">As compare to the model which I build by just using the <code>train.csv</code> I achieved around <code>95%</code> validation accuracy and now <code>99%</code> which means that the presence of the extra features has certainly helped to improve the performance of the model.</p>","metadata":{}},{"cell_type":"code","source":"X_all = scaler.transform(features)","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:42.539445Z","iopub.status.idle":"2022-06-29T02:21:42.539799Z","shell.execute_reply.started":"2022-06-29T02:21:42.539622Z","shell.execute_reply":"2022-06-29T02:21:42.53964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models[0].fit(X_all, target)\npredictions_xgb = models[0].predict_proba(test1)[:,1]\n\nmodels[1].fit(X_all, target)\npredictions_lgb = models[1].predict_proba(test1)[:,1]","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:42.541335Z","iopub.status.idle":"2022-06-29T02:21:42.541669Z","shell.execute_reply.started":"2022-06-29T02:21:42.541492Z","shell.execute_reply":"2022-06-29T02:21:42.541509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss = pd.read_csv('../input/energy-anomaly-detection/sample_submission.csv')\nss['anomaly'] = (predictions_xgb + predictions_lgb)/2\nss.to_csv('Submission_ensemble.csv', index=False)\nss","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:42.542808Z","iopub.status.idle":"2022-06-29T02:21:42.543199Z","shell.execute_reply.started":"2022-06-29T02:21:42.543023Z","shell.execute_reply":"2022-06-29T02:21:42.543043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss.loc[test['meter_reading']==1.0, 'anomaly'].describe()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:42.5446Z","iopub.status.idle":"2022-06-29T02:21:42.544946Z","shell.execute_reply.started":"2022-06-29T02:21:42.544758Z","shell.execute_reply":"2022-06-29T02:21:42.544775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss.loc[test['meter_reading']==1.0, 'anomaly'] = 1\nss.to_csv('Submission_ensemble_fixed.csv', index=False)\nss","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:42.548707Z","iopub.status.idle":"2022-06-29T02:21:42.549201Z","shell.execute_reply.started":"2022-06-29T02:21:42.548975Z","shell.execute_reply":"2022-06-29T02:21:42.549003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss.loc[test['meter_reading']==1.0, 'anomaly'].describe()","metadata":{"execution":{"iopub.status.busy":"2022-06-29T02:21:42.550572Z","iopub.status.idle":"2022-06-29T02:21:42.551179Z","shell.execute_reply.started":"2022-06-29T02:21:42.550983Z","shell.execute_reply":"2022-06-29T02:21:42.551005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}