{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":9994,"databundleVersionId":752467,"sourceType":"competition"}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:28:32.772696Z","iopub.execute_input":"2025-10-11T16:28:32.772926Z","iopub.status.idle":"2025-10-11T16:28:32.778753Z","shell.execute_reply.started":"2025-10-11T16:28:32.772912Z","shell.execute_reply":"2025-10-11T16:28:32.778155Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Basic libraries\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Settings\npd.set_option('display.max_columns', None)\nsns.set(style=\"whitegrid\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:16:46.834957Z","iopub.execute_input":"2025-10-11T16:16:46.835619Z","iopub.status.idle":"2025-10-11T16:16:47.875593Z","shell.execute_reply.started":"2025-10-11T16:16:46.835596Z","shell.execute_reply":"2025-10-11T16:16:47.874976Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load files\ntrain = pd.read_csv(\"/kaggle/input/ashrae-energy-prediction/train.csv\")\nbuilding = pd.read_csv(\"/kaggle/input/ashrae-energy-prediction/building_metadata.csv\")\nweather = pd.read_csv(\"/kaggle/input/ashrae-energy-prediction/weather_train.csv\")\n\nprint(train.shape)\nprint(building.shape)\nprint(weather.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:28:40.065291Z","iopub.execute_input":"2025-10-11T16:28:40.065958Z","iopub.status.idle":"2025-10-11T16:28:47.699062Z","shell.execute_reply.started":"2025-10-11T16:28:40.065937Z","shell.execute_reply":"2025-10-11T16:28:47.698377Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:28:51.360561Z","iopub.execute_input":"2025-10-11T16:28:51.361249Z","iopub.status.idle":"2025-10-11T16:28:51.368763Z","shell.execute_reply.started":"2025-10-11T16:28:51.361228Z","shell.execute_reply":"2025-10-11T16:28:51.368119Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ntrain.info()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:28:54.922596Z","iopub.execute_input":"2025-10-11T16:28:54.922828Z","iopub.status.idle":"2025-10-11T16:28:54.947684Z","shell.execute_reply.started":"2025-10-11T16:28:54.922814Z","shell.execute_reply":"2025-10-11T16:28:54.947044Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:28:59.513551Z","iopub.execute_input":"2025-10-11T16:28:59.513803Z","iopub.status.idle":"2025-10-11T16:29:01.167013Z","shell.execute_reply.started":"2025-10-11T16:28:59.513784Z","shell.execute_reply":"2025-10-11T16:29:01.166349Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:28:06.505746Z","iopub.execute_input":"2025-10-11T16:28:06.506313Z","iopub.status.idle":"2025-10-11T16:28:07.456061Z","shell.execute_reply.started":"2025-10-11T16:28:06.50629Z","shell.execute_reply":"2025-10-11T16:28:07.45534Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"building.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:29:07.485638Z","iopub.execute_input":"2025-10-11T16:29:07.485916Z","iopub.status.idle":"2025-10-11T16:29:07.492719Z","shell.execute_reply.started":"2025-10-11T16:29:07.485896Z","shell.execute_reply":"2025-10-11T16:29:07.492032Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\nweather.isnull().sum()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:29:22.856401Z","iopub.execute_input":"2025-10-11T16:29:22.857216Z","iopub.status.idle":"2025-10-11T16:29:22.87512Z","shell.execute_reply.started":"2025-10-11T16:29:22.857182Z","shell.execute_reply":"2025-10-11T16:29:22.874344Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"weather = weather.groupby(\"site_id\").apply(lambda x: x.ffill().bfill()).reset_index(drop=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:29:30.000596Z","iopub.execute_input":"2025-10-11T16:29:30.001245Z","iopub.status.idle":"2025-10-11T16:29:30.086681Z","shell.execute_reply.started":"2025-10-11T16:29:30.001223Z","shell.execute_reply":"2025-10-11T16:29:30.085878Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"building[\"year_built\"].fillna(building[\"year_built\"].median(), inplace=True)\nbuilding[\"floor_count\"].fillna(building[\"floor_count\"].median(), inplace=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:29:43.81275Z","iopub.execute_input":"2025-10-11T16:29:43.813247Z","iopub.status.idle":"2025-10-11T16:29:43.819236Z","shell.execute_reply.started":"2025-10-11T16:29:43.813223Z","shell.execute_reply":"2025-10-11T16:29:43.818428Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(weather.columns)\nprint(weather.index.names)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:29:47.565489Z","iopub.execute_input":"2025-10-11T16:29:47.566047Z","iopub.status.idle":"2025-10-11T16:29:47.57042Z","shell.execute_reply.started":"2025-10-11T16:29:47.566023Z","shell.execute_reply":"2025-10-11T16:29:47.569757Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Merge train + building_meta\ndf = train.merge(building, on=\"building_id\", how=\"left\")\n\n# Merge with weather\ndf = df.merge(weather, on=[\"site_id\", \"timestamp\"], how=\"left\")\n\nprint(df.shape)\ndf.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:29:54.151039Z","iopub.execute_input":"2025-10-11T16:29:54.151606Z","iopub.status.idle":"2025-10-11T16:30:02.647773Z","shell.execute_reply.started":"2025-10-11T16:29:54.151586Z","shell.execute_reply":"2025-10-11T16:30:02.647205Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Convert timestamp to datetime\ndf[\"timestamp\"] = pd.to_datetime(df[\"timestamp\"])\n\n# Fill missing weather data (site-wise forward fill)\ndf = df.groupby(\"site_id\").apply(lambda x: x.ffill().bfill()).reset_index(drop=True)\n\n# Drop rows with missing meter_reading just in case\ndf = df.dropna(subset=[\"meter_reading\"])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:30:13.502677Z","iopub.execute_input":"2025-10-11T16:30:13.503316Z","iopub.status.idle":"2025-10-11T16:30:38.67486Z","shell.execute_reply.started":"2025-10-11T16:30:13.503289Z","shell.execute_reply":"2025-10-11T16:30:38.674265Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Fill numeric columns with median\nnum_cols = df.select_dtypes(include=np.number).columns\ndf[num_cols] = df[num_cols].fillna(df[num_cols].median())\n\n# Fill categorical columns with mode\ncat_cols = df.select_dtypes(include='object').columns\ndf[cat_cols] = df[cat_cols].fillna(df[cat_cols].mode().iloc[0])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:30:59.133528Z","iopub.execute_input":"2025-10-11T16:30:59.133762Z","iopub.status.idle":"2025-10-11T16:31:15.62506Z","shell.execute_reply.started":"2025-10-11T16:30:59.133746Z","shell.execute_reply":"2025-10-11T16:31:15.624493Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[\"hour\"] = df[\"timestamp\"].dt.hour\ndf[\"day\"] = df[\"timestamp\"].dt.day\ndf[\"dayofweek\"] = df[\"timestamp\"].dt.dayofweek\ndf[\"month\"] = df[\"timestamp\"].dt.month\ndf[\"year\"] = df[\"timestamp\"].dt.year\n\ndf[\"age\"] = df[\"year\"] - df[\"year_built\"]\ndf[\"log_square_feet\"] = np.log1p(df[\"square_feet\"])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:32:54.978963Z","iopub.execute_input":"2025-10-11T16:32:54.979259Z","iopub.status.idle":"2025-10-11T16:32:57.546701Z","shell.execute_reply.started":"2025-10-11T16:32:54.979242Z","shell.execute_reply":"2025-10-11T16:32:57.546159Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.histplot(np.log1p(df[\"meter_reading\"]), bins=50, kde=True)\nplt.title(\"Log-Transformed Meter Reading Distribution\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T16:33:02.131609Z","iopub.execute_input":"2025-10-11T16:33:02.13187Z","iopub.status.idle":"2025-10-11T16:34:18.781977Z","shell.execute_reply.started":"2025-10-11T16:33:02.131852Z","shell.execute_reply":"2025-10-11T16:34:18.780975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.boxplot(x=\"meter\", y=np.log1p(df[\"meter_reading\"]), data=df)\nplt.title(\"Meter Reading by Meter Type\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T02:01:53.640316Z","iopub.execute_input":"2025-10-10T02:01:53.641063Z","iopub.status.idle":"2025-10-10T02:02:02.34792Z","shell.execute_reply.started":"2025-10-10T02:01:53.641041Z","shell.execute_reply":"2025-10-10T02:02:02.347256Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"corr_cols = [\"air_temperature\", \"dew_temperature\", \"wind_speed\", \"cloud_coverage\", \"meter_reading\"]\nsns.heatmap(df[corr_cols].corr(), annot=True, cmap=\"coolwarm\")\nplt.title(\"Correlation Heatmap\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T02:02:27.743009Z","iopub.execute_input":"2025-10-10T02:02:27.743663Z","iopub.status.idle":"2025-10-10T02:02:30.432528Z","shell.execute_reply.started":"2025-10-10T02:02:27.743641Z","shell.execute_reply":"2025-10-10T02:02:30.431777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_building = df[df[\"building_id\"] == 0]\nsample_building = sample_building.sort_values(\"timestamp\")\n\nplt.figure(figsize=(12,4))\nplt.plot(sample_building[\"timestamp\"], sample_building[\"meter_reading\"])\nplt.title(\"Energy Consumption Over Time (Building 0)\")\nplt.xlabel(\"Time\")\nplt.ylabel(\"Meter Reading\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T02:03:07.584427Z","iopub.execute_input":"2025-10-10T02:03:07.584967Z","iopub.status.idle":"2025-10-10T02:03:07.878352Z","shell.execute_reply.started":"2025-10-10T02:03:07.584945Z","shell.execute_reply":"2025-10-10T02:03:07.877662Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Log-transform target\ndf[\"target\"] = np.log1p(df[\"meter_reading\"])\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T17:07:36.962894Z","iopub.execute_input":"2025-10-11T17:07:36.963604Z","iopub.status.idle":"2025-10-11T17:07:37.055149Z","shell.execute_reply.started":"2025-10-11T17:07:36.963581Z","shell.execute_reply":"2025-10-11T17:07:37.054468Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T17:07:43.269769Z","iopub.execute_input":"2025-10-11T17:07:43.270071Z","iopub.status.idle":"2025-10-11T17:07:43.275637Z","shell.execute_reply.started":"2025-10-11T17:07:43.27005Z","shell.execute_reply":"2025-10-11T17:07:43.274885Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T17:07:54.424711Z","iopub.execute_input":"2025-10-11T17:07:54.424968Z","iopub.status.idle":"2025-10-11T17:07:56.245611Z","shell.execute_reply.started":"2025-10-11T17:07:54.424948Z","shell.execute_reply":"2025-10-11T17:07:56.244839Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"primary_cols = [col for col in df.columns if col.startswith(\"primary_use_\")]\nprint(primary_cols)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T17:08:02.267524Z","iopub.execute_input":"2025-10-11T17:08:02.267871Z","iopub.status.idle":"2025-10-11T17:08:02.272572Z","shell.execute_reply.started":"2025-10-11T17:08:02.267847Z","shell.execute_reply":"2025-10-11T17:08:02.271747Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Convert one-hot columns back to a single categorical column\ndf[\"primary_use\"] = df[primary_cols].idxmax(axis=1)\n\n# Remove the \"primary_use_\" prefix for readability\ndf[\"primary_use\"] = df[\"primary_use\"].str.replace(\"primary_use_\", \"\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T02:12:01.823125Z","iopub.execute_input":"2025-10-10T02:12:01.823435Z","iopub.status.idle":"2025-10-10T02:12:11.096024Z","shell.execute_reply.started":"2025-10-10T02:12:01.823391Z","shell.execute_reply":"2025-10-10T02:12:11.09545Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nplt.figure(figsize=(12,6))\nsns.barplot(\n    x=\"primary_use\",\n    y=np.log1p(df[\"meter_reading\"]),  # log scale to smooth outliers\n    data=df,\n    estimator=np.mean,\n    order=df.groupby(\"primary_use\")[\"meter_reading\"].mean().sort_values(ascending=False).index\n)\nplt.xticks(rotation=60)\nplt.title(\"Average Log(Meter Reading) by Primary Use\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T02:12:30.388969Z","iopub.execute_input":"2025-10-10T02:12:30.389224Z","iopub.status.idle":"2025-10-10T02:18:37.427263Z","shell.execute_reply.started":"2025-10-10T02:12:30.389206Z","shell.execute_reply":"2025-10-10T02:18:37.42644Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.linear_model import LinearRegression\nfrom sklearn.metrics import mean_squared_error, mean_squared_log_error, r2_score\n\n#\n\n# ---------------------------------------------\n# Step 2: Define features and target\n# ---------------------------------------------\n# Target variable\ny = df[\"target\"]\n\n# Drop columns not used as input features\nX = df.drop(columns=[\n    \n    'timestamp', 'meter_reading', 'square_feet', 'year_built',\n    'wind_direction', 'day', 'year', 'target',\n    \n\n\n])\n\n# ---------------------------------------------\n# Step 3: Split into train and validation sets\n# ---------------------------------------------\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)\n\n# ---------------------------------------------\n# Step 4: Scale numeric features\n# ---------------------------------------------\nscaler = StandardScaler()\nX_train_scaled = scaler.fit_transform(X_train)\nX_val_scaled = scaler.transform(X_val)\n\n# ---------------------------------------------\n# Step 5: Train Linear Regression model\n# ---------------------------------------------\nmodel = LinearRegression()\nmodel.fit(X_train_scaled, y_train)\n\n# ---------------------------------------------\n# Step 6: Predict and evaluate\n# ---------------------------------------------\ny_pred = model.predict(X_val_scaled)\ny_pred = np.where(y_pred < 0, 0, y_pred)  # avoid negative predictions\n\nrmse = np.sqrt(mean_squared_error(y_val, y_pred))\nrmsle = np.sqrt(mean_squared_log_error(y_val.clip(0, None), y_pred.clip(0, None)))\nr2 = r2_score(y_val, y_pred)\n\nprint(\"\\n✅ Evaluation Results:\")\nprint(\"RMSE :\", rmse)\nprint(\"RMSLE:\", rmsle)\nprint(\"R² Score:\", r2)\n\n# ---------------------------------------------\n# Step 7: Optional — Feature Importance\n# ---------------------------------------------\nfeature_importance = pd.DataFrame({\n    \"Feature\": X.columns,\n    \"Coefficient\": model.coef_\n}).sort_values(by=\"Coefficient\", key=abs, ascending=False)\n\nprint(\"\\nTop 10 influential features:\")\nprint(feature_importance.head(10))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-11T17:17:41.665853Z","iopub.execute_input":"2025-10-11T17:17:41.666157Z","iopub.status.idle":"2025-10-11T17:17:45.539407Z","shell.execute_reply.started":"2025-10-11T17:17:41.666131Z","shell.execute_reply":"2025-10-11T17:17:45.53837Z"}},"outputs":[],"execution_count":null}]}