17.Develop a Random Forest model to classify air quality into Good, Satisfactory, Moderate, Poor, Very Poor, or Severe using PM2.5, PM10, NO2, CO, SO2, and O3 data. Preprocess the dataset, train and evaluate the model, and predict the air quality category for a new set of pollutant readings.

Official Kaggle dataset: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india        
File Name: city_day.csv


pip install pandas numpy scikit-learn matplotlib seaborn

air_quality.py:


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.metrics import (
    accuracy_score,
    classification_report,
    confusion_matrix,
    ConfusionMatrixDisplay
)

# Load dataset
df = pd.read_csv("city_day.csv")

print("First five records:")
print(df.head())

# Select input features and target
features = ["PM2.5", "PM10", "NO2", "CO", "SO2", "O3"]
target = "AQI_Bucket"

# Check required columns
required_columns = features + [target]

missing_columns = [
    col for col in required_columns if col not in df.columns
]

if missing_columns:
    raise ValueError(f"Missing columns: {missing_columns}")

# Convert input features to numeric
for column in features:
    df[column] = pd.to_numeric(df[column], errors="coerce")

# Remove records without target labels
df = df.dropna(subset=[target])

# Prepare input and output
X = df[features]
y = df[target].astype(str)

print("\nDataset shape:", df.shape)

# Display class distribution
print("\nAir Quality Class Distribution:")
print(y.value_counts())

# Split dataset
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)

# Create Random Forest pipeline
model = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("classifier", RandomForestClassifier(
        n_estimators=100,
        random_state=42,
        class_weight="balanced",
        n_jobs=-1
    ))
])

# Train model
model.fit(X_train, y_train)

# Make predictions
y_pred = model.predict(X_test)

# Evaluate model
accuracy = accuracy_score(y_test, y_pred)

print("\nRANDOM FOREST CLASSIFICATION RESULTS")
print("------------------------------------")
print("Accuracy:", round(accuracy * 100, 2), "%")

print("\nClassification Report:")
print(classification_report(
    y_test,
    y_pred,
    zero_division=0
))

# Confusion matrix
labels = sorted(y.unique())

cm = confusion_matrix(
    y_test,
    y_pred,
    labels=labels
)

print("Confusion Matrix:")
print(cm)

# Plot confusion matrix
plt.figure(figsize=(9, 7))

sns.heatmap(
    cm,
    annot=True,
    fmt="d",
    cmap="Blues",
    xticklabels=labels,
    yticklabels=labels
)

plt.xlabel("Predicted Class")
plt.ylabel("Actual Class")
plt.title("Random Forest Confusion Matrix")
plt.tight_layout()
plt.show()

# Feature importance
classifier = model.named_steps["classifier"]

importance = pd.DataFrame({
    "Feature": features,
    "Importance": classifier.feature_importances_
})

importance = importance.sort_values(
    by="Importance",
    ascending=False
)

print("\nFeature Importance:")
print(importance)

# Plot feature importance
plt.figure(figsize=(8, 5))

sns.barplot(
    data=importance,
    x="Importance",
    y="Feature"
)

plt.title("Air Quality Feature Importance")
plt.tight_layout()
plt.show()

# Predict air quality for new readings
sample = pd.DataFrame(
    [[35.0, 60.0, 20.0, 0.8, 10.0, 30.0]],
    columns=features
)

prediction = model.predict(sample)

print("\nNew Air Quality Prediction:")
print("Predicted Category:", prediction[0])
