================================================================================
  Experiment 16: Linear Regression Temperature Prediction (Beijing PRSA)
================================================================================

FULL QUESTION:
Using the provided historical IoT environmental sensor dataset, develop a Linear Regression model to predict temperature using PM2.5, PM10, pressure, dew point, and wind speed. Train and evaluate the model, and predict the temperature for a new set of sensor readings.

SHORT QUESTION:
Multiple Linear Regression predicting temperature from PM2.5, PM10, PRES, DEWP, and WSPM with test evaluation (R2, MAE, MSE, RMSE).

================================================================================
README & SETUP INSTRUCTIONS:
================================================================================
# Experiment 16: Linear Regression Temperature Prediction

## Objective
Train a Multiple Linear Regression model predicting Temperature (`TEMP`) using `PM2.5`, `PM10`, Atmospheric Pressure (`PRES`), Dew Point (`DEWP`), and Wind Speed (`WSPM`).

## Dataset
UCI Beijing Multi-Site Air Quality dataset (`PRSA_Data_Aotizhongxin_20130301-20170228.csv`).

## Requirements
```bash
pip install pandas scikit-learn streamlit
```

## How to Run
- **CLI Mode:**
  ```bash
  python temperature_cli.py
  ```
- **Streamlit Web Dashboard:**
  ```bash
  streamlit run temperature_app.py
  ```

================================================================================
SOURCE CODE FILES:
================================================================================

1. temperature_cli.py
--------------------------------------------------------------------------------
"""
================================================================================
IOT EXPERIMENT 16: Linear Regression Temperature Predictor (CLI Pipeline)
================================================================================
Using the provided historical IoT environmental sensor dataset, develop a
Linear Regression model to predict temperature using PM2.5, PM10, pressure,
dew point, and wind speed. Train and evaluate the model, and predict the
temperature for a new set of sensor readings.
================================================================================
"""

# Short Description: Trains a multi-variable Linear Regression model on historical Beijing environmental sensor data to predict temperature from pollutant and meteorological readings.

"""
README / BEFORE RUNNING:
- Prerequisites: Python 3.x, pandas, numpy, scikit-learn (pip install pandas numpy scikit-learn).
- Dataset: Uses 'PRSA_Data_Aotizhongxin_20130301-20170228.csv' bundled in the directory.
- How to Run: python temperature_cli.py
- Expected Behavior: Preprocesses sensor data, fits regression model, displays R2 score, MAE, RMSE, feature coefficients, and test predictions.
"""

import os
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
data_path = os.path.join(BASE_DIR, "PRSA_Data_Aotizhongxin_20130301-20170228.csv") if os.path.exists(os.path.join(BASE_DIR, "PRSA_Data_Aotizhongxin_20130301-20170228.csv")) else "PRSA_Data_Aotizhongxin_20130301-20170228.csv"
data = pd.read_csv(data_path)

features = ["PM2.5", "PM10", "PRES", "DEWP", "WSPM"]
target = "TEMP"

required_columns = features + [target]
missing_columns = [col for col in required_columns if col not in data.columns]
if missing_columns:
    print("Missing columns:", missing_columns)
    exit()

data = data[features + [target]].dropna()

X = data[features]
y = data[target]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.20, random_state=42
)

model = LinearRegression()
model.fit(X_train, y_train)

y_pred = model.predict(X_test)

mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = mse ** 0.5
r2 = r2_score(y_test, y_pred)

print("\nModel Evaluation:")
print("MAE  : {:.4f}".format(mae))
print("MSE  : {:.4f}".format(mse))
print("RMSE : {:.4f}".format(rmse))
print("R2   : {:.4f}".format(r2))

print("\nCoefficients:")
for feat, coef in zip(features, model.coef_):
    print("{:6s}: {:.6f}".format(feat, coef))
print("Intercept : {:.6f}".format(model.intercept_))

def prompt_float(prompt_text: str, default_val: float) -> float:
    inp = input(f"{prompt_text} [default {default_val}]: ").strip()
    return float(inp) if inp else default_val

print("\nEnter New Sensor Readings:")
pm25 = prompt_float("PM2.5 (ug/m3)    ", 45.0)
pm10 = prompt_float("PM10 (ug/m3)     ", 80.0)
pressure = prompt_float("Pressure (hPa)   ", 1012.0)
dewpoint = prompt_float("Dew Point (deg C)", 5.0)
windspeed = prompt_float("Wind Speed (m/s) ", 2.1)

new_data = pd.DataFrame({
    "PM2.5": [pm25],
    "PM10": [pm10],
    "PRES": [pressure],
    "DEWP": [dewpoint],
    "WSPM": [windspeed]
})

predicted_temperature = model.predict(new_data)
print("\nPredicted Temperature: {:.2f} deg C".format(predicted_temperature[0]))
--------------------------------------------------------------------------------

2. temperature_app.py
--------------------------------------------------------------------------------
"""
================================================================================
IOT EXPERIMENT 16: Linear Regression Temperature Predictor (Web App)
================================================================================
Using the provided historical IoT environmental sensor dataset, develop a
Linear Regression model to predict temperature using PM2.5, PM10, pressure,
dew point, and wind speed. Train and evaluate the model, and predict the
temperature for a new set of sensor readings.
================================================================================
"""

# Short Description: Interactive web dashboard predicting ambient temperature from user-supplied environmental sensor readings using a trained Linear Regression model.

"""
README / BEFORE RUNNING:
- Prerequisites: Python 3.x, flask, pandas, scikit-learn (pip install flask pandas scikit-learn).
- How to Run: python temperature_app.py (open http://localhost:5000 in your browser).
- Expected Behavior: Trains model on historical data and provides interactive UI to enter PM2.5, PM10, pressure, dew point, and wind speed to predict temperature.
"""

import os
import streamlit as st
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

st.set_page_config(page_title="Beijing Temperature Prediction", layout="wide")
st.title("Beijing Temperature Prediction")
st.write("Linear Regression using Environmental Sensor Data")

features = ["PM2.5", "PM10", "PRES", "DEWP", "WSPM"]
target = "TEMP"

@st.cache_resource
def load_and_train():
    base_dir = os.path.dirname(os.path.abspath(__file__))
    data_path = os.path.join(base_dir, "PRSA_Data_Aotizhongxin_20130301-20170228.csv") if os.path.exists(os.path.join(base_dir, "PRSA_Data_Aotizhongxin_20130301-20170228.csv")) else "PRSA_Data_Aotizhongxin_20130301-20170228.csv"
    data = pd.read_csv(data_path)
    data = data[features + [target]].dropna()

    X = data[features]
    y = data[target]

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.20, random_state=42
    )

    model = LinearRegression()
    model.fit(X_train, y_train)

    y_pred = model.predict(X_test)
    mae = mean_absolute_error(y_test, y_pred)
    mse = mean_squared_error(y_test, y_pred)
    rmse = mse ** 0.5
    r2 = r2_score(y_test, y_pred)

    return model, len(data), mae, mse, rmse, r2

try:
    model, total_records, mae, mse, rmse, r2 = load_and_train()
except Exception as e:
    st.error(f"Error loading dataset: {e}")
    st.stop()

col1, col2, col3, col4 = st.columns(4)
col1.metric("MAE", f"{mae:.4f}")
col2.metric("MSE", f"{mse:.4f}")
col3.metric("RMSE", f"{rmse:.4f}")
col4.metric("R2 Score", f"{r2:.4f}")

st.subheader("Enter Sensor Readings")
c1, c2 = st.columns(2)
with c1:
    pm25 = st.number_input("PM2.5 (ug/m3)", min_value=0.0, value=80.0)
    pm10 = st.number_input("PM10 (ug/m3)", min_value=0.0, value=120.0)
    pressure = st.number_input("Pressure (hPa)", value=1012.0)
with c2:
    dewpoint = st.number_input("Dew Point (deg C)", value=5.0)
    windspeed = st.number_input("Wind Speed (m/s)", min_value=0.0, value=2.5)

if st.button("Predict Temperature"):
    new_data = pd.DataFrame({
        "PM2.5": [pm25],
        "PM10": [pm10],
        "PRES": [pressure],
        "DEWP": [dewpoint],
        "WSPM": [windspeed]
    })
    prediction = model.predict(new_data)
    st.success(f"Predicted Temperature: {prediction[0]:.2f} °C")
--------------------------------------------------------------------------------
