Data Plan Cost Prediction using Bayesian Regression in ML

FREE Online Courses: Your Passport to Excellence - Start Now

Telecom product managers need to estimate a subscriber’s monthly data‐plan charge—before recommending an upgrade or crafting promotional bundles—using early‐contract indicators such as monthly data usage (GB), call minutes, number of lines, contract length, and customer tenure. Pricing tiers introduce nonlinear effects (e.g., usage beyond a cap often triggers overage fees, multline discounts apply), and actual charges vary with plan promotions and add‑ons. A single point estimate ignores this variability. By using Bayesian Regression, we produce both a point forecast of each customer’s expected monthly charge and a credible interval that captures our uncertainty—enabling risk‑aware pricing, churn mitigation, and targeted upsells.

Libraries Required

import pandas as pd                              # data loading & manipulation  
import numpy as np                               # numerical operations  

import matplotlib.pyplot as plt                  # plotting  
import seaborn as sns                            # visualization  

import pymc3 as pm                               # Bayesian modeling  
import arviz as az                               # posterior analysis  

from sklearn.model_selection import train_test_split  
from sklearn.preprocessing import StandardScaler  
from sklearn.metrics import mean_absolute_error  

Dataset

Telco Customer Churn

Step-by-Step Code Implementation

Data Loading & Preprocessing

Data Features:

  • TotalCharges and tenure capture usage history.
  • Contract, PaymentMethod, InternetService, and MultipleLines reflect plan structure.

Encoding & Scaling:

  • We one‐hot encode plan categories.
  • We z‑score numeric inputs so that priors on β apply uniformly.
import pandas as pd

# Load dataset
df = pd.read_csv("data/WA_Fn-UseC_-Telco-Customer-Churn.csv")

# Select predictors and target, drop rows with missing tenure
df = df[['MonthlyCharges','TotalCharges','tenure','Contract','PaymentMethod','InternetService','MultipleLines']].dropna()

# Convert TotalCharges to numeric
df['TotalCharges'] = pd.to_numeric(df['TotalCharges'])

# One‐hot encode categorical plan features
df = pd.get_dummies(df, columns=['Contract','PaymentMethod','InternetService','MultipleLines'], drop_first=True)

# Define X and y
X = df.drop(columns='MonthlyCharges').values
y = df['MonthlyCharges'].values

# Train/test split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# Standardize numeric columns (TotalCharges, tenure)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler().fit(X_train[:, :2])
X_train_s = X_train.copy()
X_train_s[:, :2] = scaler.transform(X_train[:, :2])
X_test_s  = X_test.copy()
X_test_s[:, :2]  = scaler.transform(X_test[:, :2])

Define & Fit Bayesian Regression Model

Model Priors:

  • α ∼ Normal(0, 50) for intercept.
  • β ∼ Normal(0, 10) for each coefficient.
  • σ ∼ HalfNormal(10) for residual noise.

Likelihood: Observed MonthlyCharges ∼ Normal(μ, σ) with μ=α+β·X.

Sampling: 2,000 posterior draws (with 1,000 burn‑in) at target_accept=0.9 ensure stable convergence.

import pymc3 as pm

with pm.Model() as data_plan_model:
    # Priors
    α = pm.Normal("α", mu=0, sigma=50)                              # intercept
    β = pm.Normal("β", mu=0, sigma=10, shape=X_train_s.shape[1])    # coefficients
    σ = pm.HalfNormal("σ", sigma=10)                                # noise scale

    # Linear predictor
    μ = α + pm.math.dot(X_train_s, β)

    # Likelihood
    Y_obs = pm.Normal("Y_obs", mu=μ, sigma=σ, observed=y_train)

    # MCMC sampling
    trace = pm.sample(
        draws=2000, tune=1000,
        target_accept=0.9,
        return_inferencedata=True
    )

Posterior Analysis & Point Predictions

  • Posterior Predictive: We generate predictive distributions, extracting both the posterior mean forecast and its 94% Highest Posterior Density interval for new tenure values.
  • Evaluation: Mean Absolute Error quantifies the average point‐forecast error on held‑out customers.
import arviz as az
from sklearn.metrics import mean_absolute_error

# Summarize posterior distributions
az.summary(trace, round_to=2)

# Posterior predictive sampling
with data_plan_model:
    ppc = pm.sample_posterior_predictive(trace, var_names=["Y_obs"])

# Extract posterior means
α_post = trace.posterior["α"].mean().item()
β_post = trace.posterior["β"].mean(dim=["chain","draw"]).values

# Compute point predictions on test set
y_pred = α_post + X_test_s.dot(β_post)

# Evaluate MAE
mae = mean_absolute_error(y_test, y_pred)
print(f"Test MAE: ${mae:.2f}")

Visualise Predictions & Credible Intervals

Sweeping customer tenure highlights that longer‐tenure users command different expected charges, with credible bands indicating uncertainty due to plan variation and data sparsity.

import numpy as np
import matplotlib.pyplot as plt

# Vary tenure; hold other features at median
tenure_grid = np.linspace(X_train_s[:,1].min(), X_train_s[:,1].max(), 100)
grid = np.median(X_train_s, axis=0)[None,:].repeat(100, axis=0)
grid[:,1] = tenure_grid

with data_plan_model:
    ppc_grid = pm.sample_posterior_predictive(trace,
                                              var_names=["Y_obs"],
                                              samples=1000)

preds     = ppc_grid["Y_obs"]
mean_pred = preds.mean(axis=0)
hpd       = az.hdi(preds, hdi_prob=0.94)

# Back-transform tenure
tenure_orig = scaler.inverse_transform(grid)[:,1]

plt.figure(figsize=(8,5))
plt.plot(tenure_orig, mean_pred, label="Posterior mean")
plt.fill_between(tenure_orig, hpd[:,0], hpd[:,1], alpha=0.3,
                 label="94% credible interval")
plt.scatter(
    scaler.inverse_transform(X_test_s)[:,1],
    y_test, color="k", alpha=0.5, label="Test data"
)
plt.xlabel("Customer Tenure (months)")
plt.ylabel("Monthly Charge (USD)")
plt.title("Bayesian Regression: Charge vs. Tenure")
plt.legend()
plt.tight_layout()
plt.show()

Summary

This Bayesian Regression workflow for Data Plan Cost Prediction provides:

1. Accurate point estimates of monthly charges from customer usage and plan features.

2. Credible intervals quantifying forecast uncertainty—critical for pricing and churn management.

3. Actionable insights: marketing and finance teams can craft targeted plan offers, set contract renewal prices, and anticipate revenue under uncertainty.

Did you like this article? If Yes, please give ProjectGurukul 5 Stars on Google | Facebook

ProjectGurukul Team

The ProjectGurukul Team delivers project-based tutorials on programming, machine learning, and web development. We simplify learning by providing hands-on projects to help you master real-world skills. We also provide free major and minor projects for enginering students.

Leave a Reply

Your email address will not be published. Required fields are marked *