Sumit Kr. Jaiswal.
Back to Projects
Data SciencePythonScikit-learnPandasMatplotlibRandom ForestRegression

AQI Predictive Model Using Machine Learning

Environmental intelligence project to forecast AQI using supervised machine learning.

Role

Machine Learning Engineer

Timeline

2023-08-01 — 2023-11-24

Prediction Accuracy

94%

aqi_prediction.ipynb Python 3 (ipykernel)

Project Presentation Cover

Forecasting Air Quality, one cell at a time

Most AQI dashboards tell you how bad the air is. This project asks how bad it will be: a supervised regression model that predicts the Air Quality Index from pollutant concentrations, built on real CPCB (Central Pollution Control Board) readings for Patiala.

This case study is laid out like the original Jupyter notebook. Code is condensed from the project; the outputs, errors and figures are the real ones from the project deck.

[ ] import pandas as pd
import seaborn as sns
import matplotlib.pyplot as mlt
import numpy as np

from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor

The data

31 days of daily readings for 1–31 October 2023 from the CPCB monitoring station at Model Town, Patiala: PM2.5, PM10, NO₂, NH₃, SO₂, CO, O₃ and the resulting AQI. First attempt at loading it:

[ ] reg = pd.read_excel("C:\Users\jaisw\OneDrive\Documents\regaqi.xlsx")
Cell In[2], line 1 reg = pd.read_excel("C:\Users\jaisw\OneDrive\Documents\regaqi.xlsx") ^ SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

Bug #1. In a normal Python string, \U starts a Unicode escape, so the Windows path C:\Users\… blows up before pandas ever runs. The fix is a raw string (r"...") or forward slashes.

[ ] reg = pd.read_excel(r"C:\Users\jaisw\OneDrive\Documents\regaqi.xlsx")
reg.head()
DATEpm2.5pm10NO2NH3SO2COO3AQI
001-10-20237211629593549116
102-10-20235810029583052100
203-10-20236710728593551107
304-10-20236611730593455117
405-10-202366119295113161119

Exploratory analysis

Before modelling, a correlation heatmap shows which pollutants move with AQI. That's the first hint of which features will matter most.

[ ] sns.heatmap(reg.corr())

<Axes: >

Seaborn correlation heatmap of the pollutant features, from the project deck

Modelling

AQI is a continuous number, so this is a regression problem. Three models were trained and compared, from simple to ensemble:

  • Linear Regression, the baseline. Easy to interpret, but air quality isn't linear.
  • Decision Tree Regressor captures non-linear interactions, but overfits on 31 days of data.
  • Random Forest Regressor averages many trees, which cuts overfitting and generalises best.
[ ] X = reg.drop(columns=["DATE", "AQI"]).values
y = reg["AQI"].values

models = {
  "Linear Regression": LinearRegression(),
  "Decision Tree": DecisionTreeRegressor(),
  "Random Forest": RandomForestRegressor(),
}
for name, model in models.items():
  model.fit(X, y)

Result: Random Forest came out on top with 94% prediction accuracy, a clear jump over the linear baseline.

The model then produced a forecast for the next day, 1 November 2023:

[ ] forecast  # predicted pollutant levels and AQI for 01-11-2023
DATEpm2.5pm10NO2NH3SO2COO3AQI
01-11-2023135.21100.0027.525.8616.1137.5241.13143.10

An AQI of ~143 is in the "moderate" band, edging towards "poor". That's the kind of early warning the project set out to give.

One more bug on the way, when wrapping the plotting code into a script:

[ ] if _name_ == "_main_":
  main()
NameError Traceback (most recent call last) Cell In[9], line 53 51 plot_regression_line(x, y, b) ---> 53 if _name_ == "_main_": 54 main() NameError: name '_name_' is not defined

Bug #2. Python's module guard uses double underscores, __name__ == "__main__". With single underscores, _name_ is just an undefined variable.

Impact

On 24 November 2023 the project was presented to Sh. Harjot Singh Bains, Cabinet Minister for Higher Education, Technical Education & School Education, Government of Punjab.

What's next

  • Live forecasting from real-time sensor feeds and weather APIs
  • LSTM models for proper time-series forecasting
  • SHAP explanations of which pollutant drives each prediction
  • A deployed dashboard with a map of pollution trends