সরাসরি পর্বে যান
পর্ব ৪৫ · ৭৭-এর মধ্যে · মডিউল ৯

Bayesian linear regression — posterior আর predictive অনিশ্চয়তা

Bayesian Linear Regression — Gaussian Priors, the Posterior by Completing the Square, the Ridge Connection, Sequential Updating, the Posterior Predictive, Evidence Maximisation and ARD

Taught in Bangla, this lesson derives the Gaussian posterior by completing the square, shows the posterior mean equals ridge, and splits predictive variance into noise and epistemic parts. In-browser runs compare it with statsmodels intervals, learn α and β by evidence maximisation against BayesianRidge, and test ARDRegression on irrelevant features.

এই পর্বে যা শিখবেন

  • Gaussian prior আর Gaussian likelihood থেকে posterior-এর গড় আর covariance completing the square দিয়ে বের করা, আর হাতে এক মাত্রায় হিসাব
  • একটি একটি বিন্দু এলে posterior কীভাবে সরু হয়, আর posterior mean কেন ridge-এর সমাধান
  • Posterior predictive বণ্টন: epistemic আর aleatoric variance, plug-in অনুমান আর OLS prediction interval-এর সঙ্গে তুলনা
  • Basis function, evidence (marginal likelihood) নিজে লিখে α, β শেখা আর ডিগ্রি বাছা, scikit-learn-এর BayesianRidge-এর সঙ্গে মিলিয়ে
  • ARD দিয়ে অপ্রাসঙ্গিক feature চেনা, আর Bayesian logistic regression-এর Laplace approximation-এর ধারণা

AI-এর ভিত্তি কোর্সের পর্ব ৫০-এ prior, likelihood, evidence আর posterior দেখেছেন, Beta–Binomial দিয়ে একটি সংখ্যার posterior আর credible interval-ও। এই কোর্সের পর্ব ১৮-এ MAP মানে prior যোগ করা MLE, পর্ব ১৭-এ ridge মানে Gaussian prior-এর MAP, আর পর্ব ১৯-এ বহুমাত্রিক Gaussian. কিন্তু MAP শেষ পর্যন্ত একটি বিন্দু। এই পর্বের প্রশ্ন: বাজারঘর ক্রেতাকে বলবে “আপনার পার্সেল ৪৫ থেকে ৬০ মিনিটে আসবে”; সেই পরিসর কত চওড়া হওয়া উচিত, আর ডেটা যেখানে কম সেখানে model কি নিজের অজ্ঞতা স্বীকার করবে? চালানো যায় এমন চারটি ব্লক পাতাতেই চলে (ব্রাউজারের Python, NumPy, SciPy, scikit-learn 1.8.0, statsmodels); প্রথমবার scikit-learn নামতে প্রায় ১০ সেকেন্ড লাগে।

১ · একটি রেখা বনাম রেখার বণ্টন — model আর prior

নতুন একজন রাইডার কাজে যোগ দিলেন। প্রথম দিন সুপারভাইজার তাঁর গতি সম্পর্কে শুধু একটি মোটামুটি ধারণা রাখেন: “ঢাকার রাস্তায় কিলোমিটারে ২ থেকে ১০ মিনিট, এর বাইরে খুব কম”। প্রথম ডেলিভারির পর ধারণা একটু বদলায়, পাঁচটির পর অনেকটা, বিশটির পর তিনি প্রায় নিশ্চিত। আর কেউ যদি জিজ্ঞেস করে “২৫ কিলোমিটার দূরে সাভারে কত লাগবে?”, অভিজ্ঞ সুপারভাইজার বলবেন “এত দূরে ও কখনো যায়নি, তাই আমার অনুমান ঢিলেঢালা”। Bayesian linear regression ঠিক এই আচরণ সংখ্যায় লেখে।

Model. প্রতিটি অর্ডারের input x (যেমন দূরত্ব) থেকে কয়েকটি feature বানাই, φ(x) = (1, x) বা (1, x, x²)। এগুলোকে basis function বলে (পর্ব ২৩)। তারপর ধরে নিই

y = wᵀφ(x) + ε,   ε ~ N(0, β⁻¹)

এখানে w হলো M-টি weight-এর vector, ε হলো noise. β হলো noise-এর precision, অর্থাৎ variance-এর উল্টো: β = 1/σ². σ = ৬ মিনিট হলে β = 1/36. N-টি অর্ডারের feature-গুলো সারি হিসেবে সাজালে পাই N × M design matrix Φ. Noise স্বাধীন ধরলে likelihood হলো p(y | w) = N(y | Φw, β⁻¹I), যার log হলো −(β/2)‖y − Φw‖² + ধ্রুবক। এটুকু সাধারণ least squares-এর গল্প।

Prior. নতুন অংশ: w-কেও একটি random variable ধরি, ডেটা দেখার আগে

w ~ N(0, α⁻¹I)

α হলো weight-এর prior precision. α = 1/400 মানে প্রতিটি weight-এর prior standard deviation ২০: “ইন্টারসেপ্ট বা প্রতি কিমির মিনিট সম্ভবত −৪০ থেকে +৪০-এর মধ্যে”, খুব ঢিলেঢালা একটি বিশ্বাস। α বড় হলে prior weight-কে শূন্যের দিকে কড়া টানে। α আর β, দুটোই weight নয়, weight-এর বণ্টন নিয়ন্ত্রণ করে; তাই এদের hyperparameter বলে।

লক্ষ্য. Bayes-এর নিয়মে posterior p(w | y) ∝ p(y | w) p(w). MLE বা MAP এই বণ্টনের একটি বিন্দু (চূড়া) নেয়; Bayesian পদ্ধতি পুরো বণ্টন রাখে, আর নতুন অর্ডারের অনুমান করার সময় সব সম্ভাব্য w-এর ওপর গড় করে। সেই গড় থেকেই আসে “৪৫ থেকে ৬০ মিনিট” ধরনের পরিসর।

দুই precision, দুই প্রশ্ন

β বলে “একই দূরত্বের দুটি অর্ডারের সময় কত ছড়ায়” (রাস্তার জ্যাম, লিফট, ক্রেতা ফোন ধরছেন না): এটি ডেটার নিজস্ব এলোমেলোভাব। α বলে “ডেটা দেখার আগে weight সম্পর্কে কত নিশ্চিত”। প্রথমটি বেশি ডেটায় কমে না, দ্বিতীয়টির প্রভাব বেশি ডেটায় মিলিয়ে যায়। এই দুই ভাগই পরে predictive অনিশ্চয়তার দুই অংশ হবে।

২ · Completing the square — posterior-এর গড় আর covariance

Prior আর likelihood দুটোই w-এর দ্বিঘাত রাশির exponential. গুণ করলে log-এ যোগ হয়:

log p(w | y) = −(β/2)‖y − Φw‖² − (α/2)wᵀw + ধ্রুবক

প্রথম পদ খুলে লিখি: ‖y − Φw‖² = yᵀy − 2wᵀΦᵀy + wᵀΦᵀΦw. w-এর ওপর নির্ভর করে এমন পদগুলো সাজালে

log p(w | y) = −½ wᵀ(αI + βΦᵀΦ)w + wᵀ(βΦᵀy) + ধ্রুবক

এবার একটি Gaussian N(m, S)-এর log density খুলে দেখুন: −½(w − m)ᵀS⁻¹(w − m) = −½wᵀS⁻¹w + wᵀS⁻¹m + ধ্রুবক। দুটি রাশি পাশাপাশি রেখে দ্বিঘাত পদ আর একঘাত পদ মেলালেই উত্তর। এই কৌশলের নাম completing the square, স্কুলের ax² + bx-কে a(x + b/2a)²-এ আনার বহুমাত্রিক রূপ।

Posterior (Gaussian prior + Gaussian noise)

SN⁻¹ = αI + βΦᵀΦ,    mN = β SN Φᵀy

SN⁻¹ হলো posterior-এর precision matrix: prior-এর precision আর ডেটার precision সরাসরি যোগ হয়। mN হলো posterior mean, আর Gaussian বলে এটিই চূড়া, অর্থাৎ MAP অনুমানও।

Prior আর posterior একই পরিবারের (দুটিই Gaussian) বলে Gaussian prior এখানে conjugate prior. ফলে নতুন ডেটা এলে আজকের posterior-কে কালকের prior ধরে একই সূত্র আবার খাটানো যায়: Snew⁻¹ = Sold⁻¹ + βφφᵀ. একবারে সব ডেটা দিলে আর একটি একটি করে দিলে শেষ ফল হুবহু এক। এটিই Bayesian updating. সংখ্যার দিক থেকে SN⁻¹ সবসময় symmetric positive definite (α > 0 থাকায়), তাই inverse না নিয়ে Cholesky দিয়ে সমাধান করাই নিরাপদ (পর্ব ১০)।

এক মাত্রায় (একটিই weight, ইন্টারসেপ্ট নেই, y = wx + ε) সূত্র দুটি এত ছোট যে খাতায় করা যায়: precision = α + βΣx², আর গড় = βΣxy ÷ precision. নিচের stepper তিনটি বিন্দু একে একে যোগ করে।

precision = α + βΣx², m = βΣxy / precisiony = w·x + ε

            
  1. শুরু prior দিয়ে। ডেটা দেখার আগে w-এর গড় ০, variance ১ (α = ১)। ডেটা তিনটি বিন্দু, noise-এর variance ১ (β = ১)।
  2. প্রথম বিন্দু। Precision ১ থেকে ২ হলো, গড় = ২/২ = ১.০০০. বিন্দুটি একাই বলে w = ২, prior বলে ০; দুজনের ওজন সমান (দুজনেরই precision ১), তাই ঠিক মাঝখানে। Variance অর্ধেক হয়ে ০.৫০০.
  3. দ্বিতীয় বিন্দু। x = ২ বলে precision যোগ হলো x² = ৪, প্রথম বিন্দুর চার গুণ: দূরের বিন্দু ঢাল সম্পর্কে বেশি তথ্য দেয়। গড় ৮/৬ = ১.৩৩৩, sd ০.৪০৮.
  4. তৃতীয় বিন্দু। Precision ১৫, গড় ২৯/১৫ = ১.৯৩৩, sd ০.২৫৮. ৯৫% credible interval [১.৪২৭, ২.৪৩৯]: model আর prior মেনে নিলে w এই পরিসরে থাকার সম্ভাবনা ৯৫%.
  5. OLS আর ridge-এর সঙ্গে মিল। Prior ছাড়া least squares দেয় ২৯/১৪ = ২.০৭১. Posterior mean ১.৯৩৩ ঠিক ridge-এর উত্তর, λ = α/β = ১ নিলে। Prior-এর টান মাত্র এক একক precision, ডেটার ১৪-এর পাশে ছোট।
  6. নতুন অর্ডারে অনুমান। x = ৪-এ গড় ৭.৭৩৩. Variance দুই অংশের যোগ: noise ১/β = ১.০০০ আর weight-এর অনিশ্চয়তা x² × ১/১৫ = ১.০৬৭. x যত বড়, দ্বিতীয় অংশ তত বড়; অংশ ৫-এ এটিই বিস্তারিত।

৩ · একটি একটি করে অর্ডার — posterior কীভাবে সরু হয়

এবার বাজারঘরের ২০টি কাল্পনিক অর্ডার (seed দিয়ে বানানো): দূরত্ব ১ থেকে ১০ কিমি, আসল সম্পর্ক সময় = ২০ + ৫ × দূরত্ব, সঙ্গে σ = ৬ মিনিটের noise. আপাতত ধরে নিচ্ছি β = 1/36 জানা (অভিজ্ঞতা থেকে), আর α = 1/400. নিচের ব্লক ১, ২, ৫ আর ২০টি অর্ডার দেখার পর posterior হিসাব করে। ওপরের সারিতে weight-এর জগতে (w0 = ইন্টারসেপ্ট, w1 = প্রতি কিমিতে মিনিট) posterior-এর contour, লাল + আসল (২০, ৫)। নিচের সারিতে posterior থেকে আঁকা ছয়টি রেখা আর এ পর্যন্ত দেখা অর্ডার। Inverse-এর জন্য scipy.linalg, কারণ ব্রাউজারের NumPy অনেক linear algebra ব্যর্থতা নীরবে NaN দিয়ে ঢেকে দেয়।

import numpy as np
import scipy.linalg as sla
import matplotlib.pyplot as plt

rng = np.random.default_rng(45)
x = rng.uniform(1, 10, 20)                      # দূরত্ব (km)
y = 20 + 5 * x + rng.normal(0, 6, 20)          # ডেলিভারি সময় (মিনিট)
alpha, beta = 1 / 20**2, 1 / 6**2              # prior precision, noise precision

def posterior(xs, ys):
    Phi = np.column_stack([np.ones_like(xs), xs])
    A = alpha * np.eye(2) + beta * Phi.T @ Phi  # posterior precision
    S = sla.inv(A)                              # posterior covariance
    m = beta * S @ Phi.T @ ys                   # posterior mean
    return m, S

W0, W1 = np.meshgrid(np.linspace(-20, 60, 160), np.linspace(-4, 14, 160))
grid = np.dstack([W0, W1])
fig, ax = plt.subplots(2, 4, figsize=(11, 5.2))
for j, n in enumerate([1, 2, 5, 20]):
    m, S = posterior(x[:n], y[:n])
    sd = np.sqrt(np.diag(S)); r = S[0, 1] / (sd[0] * sd[1])
    print(f"n={n:2d}  mean=({m[0]:6.2f}, {m[1]:5.2f})  sd=({sd[0]:5.2f}, {sd[1]:4.2f})  corr={r:+.2f}")
    d = grid - m
    q = np.einsum("...i,ij,...j->...", d, sla.inv(S), d)
    ax[0, j].contour(W0, W1, np.exp(-q / 2), levels=[0.05, 0.3, 0.7])
    ax[0, j].plot(20, 5, "r+", ms=10)
    ax[0, j].set_title(f"posterior, n = {n}"); ax[0, j].set_xlabel("w0 (intercept)")
    for w in rng.multivariate_normal(m, S, 6):
        ax[1, j].plot([0, 10], [w[0], w[0] + 10 * w[1]], color="tab:blue", alpha=0.5)
    ax[1, j].plot(x[:n], y[:n], "ko", ms=4); ax[1, j].set_ylim(0, 90)
    ax[1, j].set_xlabel("distance (km)")
ax[0, 0].set_ylabel("w1 (min per km)"); ax[1, 0].set_ylabel("delivery time (min)")
fig.subplots_adjust(hspace=0.45, wspace=0.3)
plt.show()

আসল আউটপুট (ব্রাউজারের Python, NumPy আর SciPy):

n= 1  mean=(  1.26,  7.79)  sd=(19.74, 3.34)  corr=-0.96
n= 2  mean=(  3.97,  7.91)  sd=(19.49, 3.34)  corr=-0.98
n= 5  mean=( 13.90,  5.44)  sd=(12.56, 1.86)  corr=-0.98
n=20  mean=( 15.77,  5.23)  sd=( 5.07, 0.72)  corr=-0.96

একটি অর্ডারের পর posterior একটি লম্বা সরু ফিতা: একটি বিন্দু দিয়ে অসংখ্য রেখা যায়, তাই data বলে শুধু “w0 + ৬.২ × w1 প্রায় ৪৯”, আলাদা করে কিছু নয়। নিচের ছবিতে সব নমুনা-রেখা সেই বিন্দু দিয়ে ঘোরে। ইন্টারসেপ্টের sd তখনও প্রায় prior-এর ২০. দ্বিতীয় অর্ডারটি প্রথমটির কাছে (৫.৮ কিমি), তাই প্রায় কিছুই বদলায়নি: কোথায় ডেটা, তা কতটা ডেটার মতোই গুরুত্বপূর্ণ। পাঁচটির পর উপবৃত্ত ছোট আর আসল বিন্দুর কাছে; বিশটির পর ঢালের sd ০.৭২, গড় ৫.২৩ (আসল ৫)। Correlation সবসময় প্রায় −০.৯৭: ডেটা ১ থেকে ১০ কিমিতে, ইন্টারসেপ্ট x = ০-তে, তাই ঢাল একটু বাড়লে ইন্টারসেপ্ট কমিয়ে একই ডেটা ব্যাখ্যা করা যায়। x-কে কেন্দ্রে আনলে (x − x̄) এই correlation প্রায় চলে যেত।

Weight-এর জগতে posterior, আর ডেটার জগতে তার ছায়া

Prior × likelihood = posterior in weight space; the predictive band in data space

Prior, likelihood and posterior in weight space, and the posterior predictive band in data space weight-এর জগৎ (w0, w1) w0 w1 prior N(0, α⁻¹I) likelihood posterior N(m_N, S_N) ডেটার জগৎ (দূরত্ব → সময়) posterior predictive (epistemic + noise) plug-in ±1.96σ (শুধু noise) distance t ডেটা সরু চওড়া চওড়া
ছবি ৪৫.১ — ওপরে: prior (ড্যাশ বৃত্ত) সব দিকে সমান ঢিলেঢালা; likelihood (কমলা ফিতা) এক দিকে কড়া, আরেক দিকে ঢিলে, কারণ ডেটা ইন্টারসেপ্ট আর ঢালের একটি মিশ্রণ ভালো জানে; দুটির গুণফল posterior (নীল উপবৃত্ত), যার precision দুটির precision-এর যোগ। নিচে: posterior predictive পট্টি ডেটার মাঝখানে সবচেয়ে সরু আর দুই দিকে চওড়া; plug-in পট্টি (শুধু noise) সব জায়গায় সমান, তাই ডেটা থেকে দূরে অতিরিক্ত আত্মবিশ্বাসী।

৪ · Posterior mean মানেই ridge — আর predictive বণ্টন

mN = β(αI + βΦᵀΦ)⁻¹Φᵀy. বন্ধনীর ভেতর থেকে β বের করে আনলে β কেটে যায়:

mN = (ΦᵀΦ + λI)⁻¹Φᵀy,   λ = α/β

এটি হুবহু ridge regression-এর সমাধান (পর্ব ১৭-এ λ = σ²/τ² হিসেবে দেখেছেন; τ² = 1/α prior-এর variance, σ² = 1/β)। অর্থাৎ ridge-এর penalty ইচ্ছেমতো একটি সংখ্যা নয়: “noise-এর variance ভাগ prior-এর variance”. Noise বেশি হলে ডেটা কম বিশ্বাসযোগ্য, তাই prior-এর টান বেশি। একটি সূক্ষ্ম পার্থক্য: এখানে prior ইন্টারসেপ্টেও বসেছে, তাই তুলনা করতে হবে fit_intercept=False দিয়ে, ১-এর কলামটি Φ-এর ভেতরে রেখে। সাধারণ ridge ইন্টারসেপ্টকে শাস্তি দেয় না।

নতুন অর্ডারের অনুমান. নতুন দূরত্ব x*-এর feature φ* = φ(x*)। সময় y* = wᵀφ* + ε, যেখানে w আসে posterior থেকে আর ε নতুন noise. Gaussian-এর রৈখিক রূপান্তর আবার Gaussian, তাই সব w-এর ওপর integral করে পাই posterior predictive distribution:

p(y* | x*, ডেটা) = N( mNᵀφ*,  1/β + φ*ᵀSNφ* )

Variance-এর প্রথম অংশ 1/β হলো aleatoric uncertainty: ডেটার নিজের এলোমেলোভাব, w পুরো জানা থাকলেও থাকত। দ্বিতীয় অংশ φ*ᵀSNφ* হলো epistemic uncertainty: আমরা w ঠিক জানি না বলে যে অনিশ্চয়তা, বেশি ডেটায় কমে। “Plug-in” অনুমান শুধু w = mN বসিয়ে দেয় আর variance ধরে 1/β, দ্বিতীয় অংশ বাদ। নিচের ব্লক আগে ridge-এর সঙ্গে মিল যাচাই করে, তারপর ০ থেকে ২৫ কিমি পর্যন্ত predictive পরিসর হিসাব করে আর statsmodels-এর OLS prediction interval-এর পাশে রাখে (পর্ব ২৩)।

import numpy as np
import scipy.linalg as sla
from sklearn.linear_model import Ridge
import statsmodels.api as sm

rng = np.random.default_rng(45)
x = rng.uniform(1, 10, 20)
y = 20 + 5 * x + rng.normal(0, 6, 20)
alpha, beta = 1 / 20**2, 1 / 6**2
Phi = np.column_stack([np.ones_like(x), x])
S = sla.inv(alpha * np.eye(2) + beta * Phi.T @ Phi)
m = beta * S @ Phi.T @ y

lam = alpha / beta                              # 36/400 = 0.09
ridge = Ridge(alpha=lam, fit_intercept=False).fit(Phi, y)
print("posterior mean :", m.round(4))
print("ridge (λ=α/β)  :", ridge.coef_.round(4), " λ =", round(lam, 4))
print("সর্বোচ্চ পার্থক্য:", f"{np.abs(m - ridge.coef_).max():.1e}")

ols = sm.OLS(y, Phi).fit()
print("OLS-এর অনুমিত σ:", round(np.sqrt(ols.scale), 2), "(আসল 6)")
xt = np.array([0.0, 2.0, 6.0, 10.0, 15.0, 25.0])
Pt = np.column_stack([np.ones_like(xt), xt])
mean = Pt @ m
epi = np.einsum("ij,jk,ik->i", Pt, S, Pt)      # φᵀ S φ : weight-এর অনিশ্চয়তা
tot = 1 / beta + epi                            # + noise variance
pi = ols.get_prediction(Pt).summary_frame(alpha=0.05)
print("\n  km   mean  sd_epi  sd_tot  Bayes 95%        OLS 95% PI")
for i, v in enumerate(xt):
    lo, hi = mean[i] - 1.96 * np.sqrt(tot[i]), mean[i] + 1.96 * np.sqrt(tot[i])
    print(f"{v:4.0f} {mean[i]:6.1f} {np.sqrt(epi[i]):6.2f} {np.sqrt(tot[i]):6.2f}"
          f"  [{lo:5.1f}, {hi:5.1f}]  [{pi.obs_ci_lower[i]:5.1f}, {pi.obs_ci_upper[i]:5.1f}]")
print("plug-in (শুধু noise): ±", round(1.96 * 6, 1), "সব দূরত্বে একই")

আসল আউটপুট (ব্রাউজারের Python, scikit-learn 1.8.0, statsmodels):

posterior mean : [15.7713  5.2304]
ridge (λ=α/β)  : [15.7713  5.2304]  λ = 0.09
সর্বোচ্চ পার্থক্য: 6.9e-14
OLS-এর অনুমিত σ: 5.22 (আসল 6)

  km   mean  sd_epi  sd_tot  Bayes 95%        OLS 95% PI
   0   15.8   5.07   7.86  [  0.4,  31.2]  [  2.2,  31.4]
   2   26.2   3.70   7.05  [ 12.4,  40.1]  [ 14.0,  40.0]
   6   47.2   1.46   6.17  [ 35.1,  59.3]  [ 36.0,  58.6]
  10   68.1   2.67   6.57  [ 55.2,  80.9]  [ 55.7,  79.7]
  15   94.2   6.06   8.53  [ 77.5, 110.9]  [ 77.3, 108.9]
  25  146.5  13.18  14.49  [118.1, 174.9]  [116.9, 171.2]
plug-in (শুধু noise): ± 11.8 সব দূরত্বে একই

Posterior mean আর ridge-এর পার্থক্য ৬.৯ × ১০−১৪, শুধু floating-point-এর গোলমাল: একই জিনিস। Predictive পরিসর ডেটার মাঝখানে (৬ কিমি, ডেটার গড় ৬.৮) সবচেয়ে সরু: epistemic sd মাত্র ১.৪৬, মোট sd ৬.১৭ প্রায় পুরোটাই noise. ২৫ কিমিতে, যেখানে কোনো অর্ডারই নেই, epistemic sd ১৩.১৮, noise-এর দ্বিগুণের বেশি; পরিসর প্রায় ৫৭ মিনিট চওড়া। Plug-in পরিসর সব জায়গায় ±১১.৮, তাই ২৫ কিমিতে সে নিজের অজ্ঞতা লুকায়। OLS prediction interval আকারে প্রায় একই, কারণ তার সূত্রেও একটি “x̄ থেকে দূরত্ব” অংশ আছে। পার্থক্যের উৎস দুটি: OLS σ ডেটা থেকে অনুমান করেছে (৫.২২, আর t-বণ্টন নেয়), আমরা σ = ৬ জানা ধরেছি; আর আমাদের prior ইন্টারসেপ্টকে সামান্য টানে। Prior ঢিলে আর σ একই হলে দুটি পরিসর সংখ্যায় মিলে যায়, যদিও অর্থ আলাদা (ভাবনার প্রশ্ন ১)। শেষ সতর্কতা: ২৫ কিমিতে আসল সম্পর্ক সরলরেখা থাকবে কি না, তা model জানে না; epistemic অংশ শুধু এই model-এর ভেতরের অনিশ্চয়তা মাপে।

৫ · Predictive variance ভেঙে দেখা — কোন অংশ কখন বড়

φ = (1, x) হলে φᵀSφ = S00 + 2x S01 + x² S11, x-এর একটি দ্বিঘাত রাশি, যার সর্বনিম্ন বিন্দু ডেটার গড়ের কাছে। তাই পট্টির আকার ঘণ্টাঘড়ির মতো। নিচের stepper ব্লকের SN দিয়ে ৬ কিমি আর ২৫ কিমিতে হিসাবটি খুলে দেখায়।

σ²(x) = 1/β + φᵀSNφ২০টি অর্ডার · β = 1/36

            
  1. SN পড়া। কর্ণের সংখ্যা দুটি ইন্টারসেপ্ট (২৫.৭৫১) আর ঢালের (০.৫১৯) variance. কর্ণের বাইরের −৩.৫২৬ ঋণাত্মক: ঢাল বাড়লে ইন্টারসেপ্ট কমে, ব্লক ১-এর −০.৯৭ correlation.
  2. ৬ কিমিতে epistemic অংশ। তিনটি পদ ২৫.৭৫১ − ৪২.৩১৭ + ১৮.৬৮৫ = ২.১১৯. ঋণাত্মক মাঝের পদ বড় দুটি পদকে প্রায় কাটে, কারণ ডেটার কেন্দ্রের কাছে ইন্টারসেপ্ট আর ঢালের ভুল একে অপরকে পুষিয়ে দেয়। sd ১.৪৫৬.
  3. ৬ কিমিতে মোট। Noise ৩৬ আর epistemic ২.১১৯ মিলে ৩৮.১১৯, sd ৬.১৭৪. Epistemic ভাগ মাত্র ৫.৬%: ডেটার মাঝখানে অনিশ্চয়তার প্রায় পুরোটাই রাস্তার এলোমেলোভাব।
  4. ২৫ কিমিতে epistemic অংশ। এবার x² × S11 = ৩২৪.৩৯৪ এত বড় যে মাঝের −১৭৬.৩২০ আর কাটতে পারে না: φᵀSφ = ১৭৩.৮২৫, sd ১৩.১৮৪. ঢালের সামান্য অনিশ্চয়তা (sd ০.৭২) ২৫ গুণ হয়ে বড় হয়েছে।
  5. ২৫ কিমিতে মোট। ৩৬ + ১৭৩.৮২৫ = ২০৯.৮২৫, sd ১৪.৪৮৫, আর epistemic ভাগ ৮২.৮%. ৯৫% পরিসর ±২৮.৪ মিনিট। এখানে ক্রেতাকে প্রতিশ্রুতি দেওয়ার আগে নতুন ডেটা দরকার, model নয়।
  6. ডেটা বাড়ালে কী হয়। একই ধাঁচের ৮০টি অর্ডারে SN প্রায় চার ভাগের এক ভাগ (prior-এর অংশ নগণ্য বলে)। ৬ কিমিতে sd ৬.১৭ থেকে মাত্র ৬.০৪-এ নামে, ২৫ কিমিতে ১৪.৪৯ থেকে ৮.৯১-এ। Noise-এর ৩৬ কখনো কমে না: aleatoric অনিশ্চয়তা কমাতে ডেটা নয়, নতুন feature (যেমন সময়, আবহাওয়া) লাগে।

Frequentist interval-এর সঙ্গে সম্পর্ক. OLS-এর prediction interval-এর সূত্রও s²(1 + φ*ᵀ(ΦᵀΦ)⁻¹φ*), একই দুই অংশ। Prior খুব ঢিলে (α → ০) আর σ অজানা ধরে তার ওপরও একটি “তথ্যহীন” prior দিলে Bayesian predictive হুবহু Student-t prediction interval-এ নেমে আসে। তাই পার্থক্য সংখ্যায় নয়, বাক্যে: frequentist বলে “এই পদ্ধতিতে বানানো পরিসর বারবার ব্যবহার করলে ৯৫% বার নতুন অর্ডার ধরবে”; Bayesian বলে “এই model আর prior মেনে নিলে, এই অর্ডারটি এই পরিসরে থাকার সম্ভাবনা ৯৫%”. Prior কড়া হলে বা ডেটা কম হলে সংখ্যাও আলাদা হয়, আর তখনই prior-এর পছন্দ যাচাই করা জরুরি। দুই ক্ষেত্রেই আসল পরীক্ষা একই: আলাদা রাখা অর্ডারে পরিসরটি সত্যিই প্রায় ৯৫% বার ধরে কি না (coverage), যেমন পর্ব ২৬-এ সম্ভাবনার calibration দেখেছেন।

৬ · Basis function আর evidence — α, β ডেটা থেকে, ডিগ্রিও

এতক্ষণ α আর β হাতে দিয়েছি। বাস্তবে এগুলো জানা থাকে না। একটি পথ cross-validation (AI-এর ভিত্তি কোর্সের পর্ব ৬৬)। Bayesian পথ আরেকটি প্রশ্ন করে: এই α, β আর এই basis নিয়ে, দেখা ডেটা আসার সম্ভাবনা কত? উত্তর w-এর ওপর integral করে পাওয়া evidence বা marginal likelihood, p(y | α, β) = ∫ p(y | w, β) p(w | α) dw. Gaussian বলে integral বন্ধ রূপে আসে:

ln p(y | α, β) = (M/2)ln α + (N/2)ln β − E(mN) − ½ ln|SN⁻¹| − (N/2)ln 2π

যেখানে E(m) = (β/2)‖y − Φm‖² + (α/2)mᵀm, ঠিক ridge-এর লক্ষ্য-ফাংশন, আর |SN⁻¹| হলো posterior precision matrix-এর determinant. Evidence সর্বোচ্চ করে α, β বাছাকে বলে empirical Bayes বা type-II maximum likelihood: weight-এর ওপর integral, hyperparameter-এর ওপর optimization. ডেরিভেটিভ শূন্য ধরলে MacKay-র (১৯৯২) fixed-point নিয়ম আসে। βΦᵀΦ-এর eigenvalue λi হলে

γ = Σi λi/(α + λi),   α ← γ / mNᵀmN,   1/β ← ‖y − ΦmN‖² / (N − γ)

γ হলো effective number of parameters: যে weight-এর দিকে ডেটা prior-এর চেয়ে বেশি কথা বলে (λi ≫ α), সেটি প্রায় ১ গোনে, বাকিগুলো প্রায় ০ (পর্ব ১৭-এর effective degrees of freedom-এর সঙ্গে মিলিয়ে দেখুন)। দ্বিতীয় সূত্রটি noise variance-এর অনুমান, শুধু N-এর বদলে N − γ দিয়ে ভাগ, যেমন OLS-এ N − M দিয়ে।

নিচের ব্লকে নতুন ৩০টি অর্ডার, যেখানে আসল সম্পর্ক বাঁকা: সময় = ১২ + ৭x − ০.৩x² (দূরে গেলে রাইডার হাইওয়ে পান, প্রতি কিমির সময় কমে)। ডিগ্রি ০ থেকে ৭ পর্যন্ত polynomial basis (polynomial features), x-কে আগে প্রায় [−১, ১]-এ এনে। প্রতিটি ডিগ্রিতে নিজে লেখা fixed-point দিয়ে α, β আর evidence, পাশে scikit-learn-এর BayesianRidge একই কাজ করে। RBF basis (radial basis function) দিলেও একই কোড চলে, শুধু Φ বদলায়।

নামের ফাঁদ: scikit-learn-এর BayesianRidge-এ alpha_ হলো noise precision (আমাদের β), আর lambda_ হলো weight precision (আমাদের α), Bishop-এর বইয়ের ঠিক উল্টো নাম। fit_intercept=True (default) দিলে ইন্টারসেপ্ট prior ছাড়া আলাদা অনুমান হয়; এখানে ১-এর কলাম Φ-এ রেখে fit_intercept=False দেওয়া হয়েছে যাতে দুই হিসাব হুবহু এক model.

import numpy as np
import scipy.linalg as sla
from sklearn.linear_model import BayesianRidge

rng = np.random.default_rng(7)
x = rng.uniform(0.5, 12, 30)                    # দূরত্ব (km)
y = 12 + 7 * x - 0.3 * x**2 + rng.normal(0, 4, 30)
u = (x - 6) / 6                                 # প্রায় [-1, 1]-এ আনা
N = len(y)

def evidence(Phi, a=1.0, b=1.0):
    ev = np.linalg.eigvalsh(Phi.T @ Phi)        # ΦᵀΦ-এর eigenvalue
    for _ in range(500):                        # MacKay-র fixed-point
        A = a * np.eye(Phi.shape[1]) + b * Phi.T @ Phi
        m = b * sla.solve(A, Phi.T @ y, assume_a="pos")
        gamma = np.sum(b * ev / (a + b * ev))   # কার্যকর parameter-সংখ্যা
        sse = np.sum((y - Phi @ m) ** 2)
        a, b = gamma / (m @ m), (N - gamma) / sse
    A = a * np.eye(Phi.shape[1]) + b * Phi.T @ Phi
    m = b * sla.solve(A, Phi.T @ y, assume_a="pos")
    sse = np.sum((y - Phi @ m) ** 2)
    logev = (Phi.shape[1] * np.log(a) + N * np.log(b) - b * sse - a * m @ m
             - np.linalg.slogdet(A)[1] - N * np.log(2 * np.pi)) / 2
    return logev, a, b, np.sqrt(sse / N), gamma

print("deg   logev     α      β     rmse   γ  │ sk_score  sk_λ    sk_α")
for d in range(0, 8):
    Phi = np.vander(u, d + 1, increasing=True)  # 1, u, u², …
    le, a, b, rmse, g = evidence(Phi)
    br = BayesianRidge(fit_intercept=False, compute_score=True, tol=1e-10,
                       max_iter=1000).fit(Phi, y)
    print(f"{d:3d} {le:8.2f} {a:.4f} {b:.4f} {rmse:5.2f} {g:4.1f} │"
          f" {br.scores_[-1]:8.2f} {br.lambda_:.4f} {br.alpha_:.4f}")

আসল আউটপুট (ব্রাউজারের Python, scikit-learn 1.8.0):

deg   logev     α      β     rmse   γ  │ sk_score  sk_λ    sk_α
  0  -120.31 0.0006 0.0068 11.90  1.0 │  -120.31 0.0006 0.0068
  1   -93.53 0.0010 0.0525  4.22  2.0 │   -93.53 0.0010 0.0525
  2   -90.56 0.0013 0.0764  3.43  3.0 │   -90.56 0.0013 0.0764
  3   -91.46 0.0018 0.0783  3.33  3.9 │   -91.46 0.0018 0.0783
  4   -91.73 0.0018 0.0833  3.18  4.8 │   -91.73 0.0018 0.0833
  5   -92.33 0.0020 0.0822  3.18  5.1 │   -92.33 0.0020 0.0822
  6   -92.70 0.0021 0.0821  3.17  5.2 │   -92.70 0.0021 0.0821
  7   -93.10 0.0022 0.0813  3.17  5.4 │   -93.10 0.0022 0.0813

তিনটি জিনিস দেখুন। প্রথমত, নিজে লেখা হিসাব আর BayesianRidge প্রতিটি সারিতে মেলে: sk_λ আমাদের α, sk_α আমাদের β (scikit-learn-এর score-এ α, β-র ওপর খুব দুর্বল Gamma hyperprior-এর ছোট পদ থাকে, যা এখানে দশমিকের দুই ঘরে দেখা যায় না)। দ্বিতীয়ত, training rmse ডিগ্রি বাড়লে কমতেই থাকে (১১.৯০ থেকে ৩.১৭), কিন্তু log evidence ডিগ্রি ২-এ সর্বোচ্চ (−৯০.৫৬), যা আসল ডিগ্রি; ডিগ্রি ৭ পিছিয়ে যায় (−৯৩.১০)। Evidence-এর পার্থক্য ২.৫৪ মানে ডিগ্রি ২-এর পক্ষে Bayes factor e২.৫৪ ≈ ১২.৭. তৃতীয়ত, γ ডিগ্রি ৫ থেকে প্রায় থেমে যায় (৫.১, ৫.২, ৫.৪), যদিও parameter ৮টি পর্যন্ত বাড়ে: বাড়তি weight-গুলোকে prior প্রায় চেপে রাখে। আর β ≈ ০.০৮ মানে noise sd ≈ ৩.৬, আসল ৪-এর কাছে। একটি সতর্কতা: এটি ৩০টি বিন্দুর একটি seed মাত্র।

Seed বদলালে কী হয় (সত্যিকারের run). একই generator seed ০ থেকে ৯-এ ডেস্কটপে চালানো হয়েছে (লেখার সময়ে Python 3.14.4, NumPy 2.5.4, scikit-learn 1.8.0; একটি local run, সাধারণ ফল নয়); প্রতিটি সারিতে evidence যে ডিগ্রি বেছেছে আর সেরা দুটি log evidence:

$ python seeds.py
seed 0: best degree 7 | top-2 log evidence -92.33 -92.38
seed 1: best degree 2 | top-2 log evidence -91.21 -92.69
seed 2: best degree 2 | top-2 log evidence -93.04 -93.75
seed 3: best degree 2 | top-2 log evidence -94.05 -95.37
seed 4: best degree 2 | top-2 log evidence -88.55 -89.92
seed 5: best degree 2 | top-2 log evidence -94.89 -96.35
seed 6: best degree 4 | top-2 log evidence -89.20 -89.68
seed 7: best degree 2 | top-2 log evidence -90.56 -91.46
seed 8: best degree 3 | top-2 log evidence -98.81 -99.18
seed 9: best degree 2 | top-2 log evidence -88.47 -89.15

দশটির সাতটিতে আসল ডিগ্রি ২ জিতেছে। বাকি তিনটিতে (seed ০, ৬, ৮) জিতেছে ৭, ৪ আর ৩, কিন্তু প্রথম আর দ্বিতীয়ের ব্যবধান মাত্র ০.০৫, ০.৪৮ আর ০.৩৭ log একক, অর্থাৎ Bayes factor ২-এর কম। Evidence যখন জোর দিয়ে কিছু বলে না, তখন সরল model নেওয়া, বা কয়েকটি ডিগ্রির অনুমান evidence-এর ওজনে মেলানো (Bayesian model averaging), নিরাপদ পথ।

Evidence কেন বেশি নমনীয় model-কে শাস্তি দেয়, যখন training ভুল তার পক্ষে? log evidence-কে দুই ভাগে লেখা যায়: fit পদ (N/2)ln β − (β/2)‖y − ΦmN‖² − (N/2)ln 2π, আর বাকিটা, (M/2)ln α − (α/2)mNᵀmN − ½ln|SN⁻¹|. দ্বিতীয়টিকে বলে Occam factor-এর log: মোটামুটি “posterior-এর আয়তন ভাগ prior-এর আয়তন”-এর log, প্রতিটি নতুন weight-এর জন্য ঋণাত্মক একটি দাম।

ln p(y) = fit পদ + Occam পদN = 30 · ব্লক ৩-এর ডেটা

            
  1. দুই ভাগে ভাঙা। Fit পদ ডেটা কত ভালো মেলে তা মাপে, Occam পদ prior-এর জায়গার কতখানি ডেটা বাতিল করল তা। নমনীয় model-এর prior অনেক রকম ডেটা “সম্ভব” বলে, তাই প্রতিটি নির্দিষ্ট ডেটাসেটে তার সম্ভাবনা পাতলা ছড়ানো।
  2. ডিগ্রি ১. SSE ৫৩৩.০২, সরলরেখা বাঁক ধরতে পারে না; fit −৮৫.৭৬৩. দুটি weight-এর Occam দাম −৭.৭৬৫. মোট −৯৩.৫২৯.
  3. ডিগ্রি ২. বাঁক ধরায় SSE ৩৫৩.৭০-এ নামে, fit ৬.১০৬ একক বাড়ে। তৃতীয় weight-এর জন্য Occam দাম আরও ৩.১৪১. লাভ দামের চেয়ে বেশি, মোট −৯০.৫৬৩, সবার সেরা।
  4. ডিগ্রি ৩. Fit আর মাত্র ০.৮৫১ বাড়ে (noise-এর পেছনে ছোটা), অথচ নতুন weight-এর দাম ১.৭৫১. মোট কমে −৯১.৪৬৩-এ।
  5. ডিগ্রি ৭. SSE সবচেয়ে কম (৩০২.০৩), fit সবচেয়ে ভালো (−৭৭.৪৮৯), কিন্তু Occam দাম −১৫.৬১৫. মোট −৯৩.১০৩, ডিগ্রি ১-এর প্রায় সমান খারাপ। Training ভুল এই দাম কখনো দেখে না।
  6. Bayes factor. Evidence-এর পার্থক্যের exp: ডিগ্রি ২ ডিগ্রি ৭-এর চেয়ে প্রায় ১২.৭ গুণ ভালোভাবে ডেটা ব্যাখ্যা করে, ডিগ্রি ৩-এর চেয়ে মাত্র ২.৪৬ গুণ। Jeffreys-এর প্রচলিত স্কেলে ১০-এর বেশি শক্ত প্রমাণ আর ৩-এর কম প্রায় উল্লেখের অযোগ্য; ২ আর ৩-এর মধ্যে সিদ্ধান্ত অন্য seed-এ উল্টাতে পারে।

৭ · ARD — প্রতিটি weight-এর নিজস্ব prior

BayesianRidge সব weight-কে একই α দেয়। Automatic relevance determination (ARD) প্রতিটি weight wj-কে আলাদা precision αj দেয়: wj ~ N(0, αj⁻¹)। তারপর evidence সর্বোচ্চ করে প্রতিটি αj শেখে, update αj ← γj/mj², যেখানে γj = 1 − αj(SN)jj. কোনো feature ডেটা ব্যাখ্যায় কাজে না লাগলে তার αj অনেক বড় হয়, prior weight-কে শূন্যে চেপে ধরে, আর Occam দাম বাঁচে। scikit-learn-এর ARDRegression-এ αj হলো lambda_[j], আর threshold_lambda (default ১০,০০০) ছাড়ালে weight পুরোপুরি বাদ দেয়। নিচের ৬০টি অর্ডারে তিনটি আসল feature (দূরত্ব, ওজন, বৃষ্টি) আর তিনটি অপ্রাসঙ্গিক (অর্ডার নম্বরের শেষ দুই অঙ্ক, দাম, রেটিং)। সব feature আগে standardize করা, কারণ prior-এর precision feature-এর মাপের ওপর নির্ভর করে।

import numpy as np
import pandas as pd
from sklearn.linear_model import ARDRegression, BayesianRidge, LinearRegression
from sklearn.preprocessing import StandardScaler

rng = np.random.default_rng(11)
n = 60
X = pd.DataFrame({
    "distance_km": rng.uniform(1, 12, n),
    "weight_kg": rng.uniform(0.2, 8, n),
    "rain": rng.integers(0, 2, n).astype(float),
    "order_id_mod": rng.integers(0, 100, n).astype(float),   # অপ্রাসঙ্গিক
    "price_tk": rng.uniform(200, 3000, n),                   # অপ্রাসঙ্গিক
    "rating": rng.integers(1, 6, n).astype(float),           # অপ্রাসঙ্গিক
})
y = (15 + 5 * X.distance_km + 1.5 * X.weight_kg + 8 * X.rain
     + rng.normal(0, 4, n))
Z = StandardScaler().fit_transform(X)            # সব feature এক মাপে

ols = LinearRegression().fit(Z, y)
br = BayesianRidge().fit(Z, y)
ard = ARDRegression().fit(Z, y)
pd.set_option("display.width", 80)
tab = pd.DataFrame({"OLS": ols.coef_, "BayesRidge": br.coef_,
                    "ARD": ard.coef_, "ARD λ_j": ard.lambda_,
                    "ARD sd": np.sqrt(np.diag(ard.sigma_))},
                   index=X.columns)
print(tab.round(3).to_string())
print("ARD noise sd ≈", round(1 / np.sqrt(ard.alpha_), 2),
      "| BayesianRidge-এর একক λ =", round(br.lambda_, 4))

আসল আউটপুট (ব্রাউজারের Python, scikit-learn 1.8.0):

                 OLS  BayesRidge     ARD   ARD λ_j  ARD sd
distance_km   16.556      16.447  16.432     0.004   0.549
weight_kg      3.945       3.912   3.908     0.064   0.548
rain           3.759       3.759   3.750     0.070   0.548
order_id_mod   0.087       0.087   0.000  1270.122   0.028
price_tk      -0.482      -0.457  -0.002   681.149   0.038
rating         0.291       0.290   0.001  1158.056   0.029
ARD noise sd ≈ 4.18 | BayesianRidge-এর একক λ = 0.0199

তিনটি আসল feature-এর λj ছোট (০.০০৪ থেকে ০.০৭০), অর্থাৎ prior প্রায় ঢিলে, আর weight তিন পদ্ধতিতেই প্রায় এক। তিনটি অপ্রাসঙ্গিক feature-এর λj ৬৮১ থেকে ১,২৭০: prior-এর sd ১/√λ মাত্র ০.০৩–০.০৪, তাই weight ০.০০০, −০.০০২, ০.০০১. OLS সেখানে noise থেকে −০.৪৮২-এর মতো weight বসিয়েছে; BayesianRidge-এর একক λ (০.০২) সব weight-কে প্রায় সমানভাবে টানে, তাই অপ্রাসঙ্গিক weight-ও প্রায় অক্ষত (−০.৪৫৭)। λj এখানে ১০,০০০ ছাড়ায়নি, তাই weight পুরো বাদ পড়েনি, শুধু শূন্যের কাছে। Noise sd-র অনুমান ৪.১৮, আসল ৪. সাবধান: ARD বলে “এই model-এ এই feature অনুমানে সাহায্য করে না”, কারণ-কার্য নয়; আর দুটি feature প্রায় একই তথ্য বহন করলে ARD একটিকে ইচ্ছেমতো রেখে অন্যটি ছাঁটতে পারে।

৮ · Gaussian-এর বাইরে — Laplace approximation, সীমা আর পরের পথ

Bayesian logistic regression. ফেরত (return) হবে কি না, এমন হ্যাঁ-না লক্ষ্যে likelihood Bernoulli, আর Gaussian prior-এর সঙ্গে গুণ করলে posterior আর Gaussian থাকে না; বন্ধ সূত্রও নেই। সবচেয়ে পুরোনো সহজ পথ Laplace approximation: (১) MAP বিন্দু w* খুঁজুন (L2-শাস্তিযুক্ত logistic regression, যেমন LogisticRegression(C=1/α)); (২) সেখানে −log posterior-এর Hessian H = αI + Σn σn(1 − σn)φnφnᵀ হিসাব করুন, যেখানে σn হলো অর্ডার n-এর অনুমিত সম্ভাবনা; (৩) posterior ≈ N(w*, H⁻¹)। অর্থাৎ চূড়ার চারপাশে log posterior-কে একটি দ্বিঘাত রাশি দিয়ে বদলানো, পর্ব ১৮-এর Fisher information-এর ভাবনার মতো। তারপর নতুন অর্ডারের সম্ভাবনায় অনিশ্চয়তা আনতে একটি পরিচিত আনুমানিক সূত্র: p ≈ σ(μ / √(1 + πs²/8)), যেখানে μ = w*ᵀφ আর s² = φᵀH⁻¹φ. s² বড় হলে logit শূন্যের দিকে নামে, অর্থাৎ ডেটা থেকে দূরে model কম আত্মবিশ্বাসী সম্ভাবনা দেয়, যা প্রায়ই calibration-এ সাহায্য করে।

সীমাগুলো সৎভাবে.

  • Model ভুল হলে অনিশ্চয়তাও ভুল। Epistemic অংশ “এই basis-এর ভেতরে কোন w” নিয়ে অনিশ্চয়তা; আসল সম্পর্ক বাঁকা হলে সরলরেখার posterior আত্মবিশ্বাসের সঙ্গে ভুল জায়গায় সরু হতে পারে।
  • Noise সব জায়গায় সমান ধরা হয়। ঈদের আগে বা বৃষ্টিতে ছড়ানো বেশি হলে (heteroscedastic noise) একটি β যথেষ্ট নয়; পর্ব ২০ বা পর্ব ২৪-এর মতো পথ লাগে।
  • Prior-এর মাপ feature-এর মাপের ওপর নির্ভর করে। Standardize না করলে “একই α” আসলে একেক feature-এ একেক শক্তির prior.
  • খরচ. SN একটি M × M matrix; M হাজার ছাড়ালে Cholesky O(M³)। N অনেক বড় হলে সমস্যা নেই (ΦᵀΦ একবারই বানাতে হয়)।

পরের পথ. weight-এর বদলে সরাসরি function-এর ওপর prior দিলে, আর basis-এর সংখ্যা অসীম করলে, আসে পর্ব ৪৬ (Gaussian process — kernel দিয়ে অনিশ্চয়তাসহ অনুমান); পর্ব ৩০-এর kernel ridge-এর গড়ের সঙ্গে তখন variance-ও পাওয়া যায়। Posterior বন্ধ সূত্রে না এলে নমুনা নিয়ে কাজ চালানো হয় পর্ব ৪৭ (MCMC — Metropolis-Hastings আর Gibbs sampling)-এ, আর আনুমানিক বণ্টন দিয়ে পর্ব ৪৮ (Variational inference-এর ধারণা — ELBO আর approximation)-এ। Predictive অনিশ্চয়তা কাজে লাগিয়ে পরের পরীক্ষা কোথায় করবেন, তা পর্ব ৪৯ (Bayesian optimization — অল্প চেষ্টায় hyperparameter খোঁজা)-এর বিষয়।

আরও গভীরে: Lindley আর Smith-এর ১৯৭২ সালের প্রবন্ধ (Journal of the Royal Statistical Society B) linear model-এ স্তরে স্তরে prior দেওয়ার কাঠামো দেয়, যা আজকের hierarchical model-এর পূর্বসূরি। David MacKay-এর ১৯৯২ সালের “Bayesian interpolation” (Neural Computation) evidence framework, γ আর Occam factor-এর ব্যাখ্যা দেয়; scikit-learn-এর BayesianRidge এই fixed-point update-ই চালায় (তার docs Bishop-এর Pattern Recognition and Machine Learning, ২০০৬, অধ্যায় ৩ উল্লেখ করে)। ARD-এর ধারণা MacKay আর Neal-এর নব্বইয়ের দশকের neural network-এর কাজ থেকে; Tipping-এর ২০০১ সালের relevance vector machine (JMLR) একে sparse kernel model-এ নেয়, আর scikit-learn-এর ARDRegression সেই ধারার update ব্যবহার করে।

পরীক্ষা ও ইন্টারভিউতে: এই ধরনের প্রশ্ন প্রায়ই আসে।
১. Gaussian prior N(0, α⁻¹I) আর noise precision β-তে posterior লিখুন। → SN⁻¹ = αI + βΦᵀΦ, mN = βSNΦᵀy.
২. Posterior mean কোন পরিচিত অনুমানের সমান? → Ridge, λ = α/β.
৩. এক মাত্রায় α = ১, β = ১, একটি বিন্দু (২, ৪) হলে posterior? → precision ১ + ৪ = ৫, গড় ৮/৫ = ১.৬, variance ০.২.
৪. Predictive variance-এর দুই অংশ কী, কোনটি ডেটা বাড়লে কমে? → 1/β (aleatoric, কমে না) + φᵀSNφ (epistemic, কমে)।
৫. Evidence কেন overfit করা model-কে শাস্তি দেয়? → Occam factor: বাড়তি weight-এর prior আয়তনের বেশিরভাগ ডেটা বাতিল করে, তাই fit-এর লাভ বড় না হলে মোট evidence কমে।

৯ · AI-এর যুগে — Bayesian regression-এর কোড আর দাবি যাচাই

AI assistant Bayesian regression-এর derivation আর কোড দ্রুত লিখে দেয়, আর সেগুলো দেখতে খুব গাণিতিক বলে ভুল ধরা কঠিন। নিচের ভুলগুলো বারবার দেখা যায়।

AI প্রায়ই যা করেকেন ভুলকীভাবে ধরবেন
BayesianRidge-এর alpha_-কে prior precision বলে ব্যাখ্যা করেscikit-learn-এ alpha_ noise precision, lambda_ weight precisionনিজের version-এর docs পড়ুন; 1/√alpha_ residual sd-র কাছে কি না দেখুন
Predictive sd হিসেবে শুধু σ বা শুধু φᵀSφ দেয়দুটির যোগ লাগে; একটি বাদ দিলে পরিসর খুব সরুpredict(X, return_std=True)-এর সঙ্গে নিজের হিসাব মেলান
np.linalg.inv দিয়ে বড় posterior precision উল্টায়অস্থির, আর ব্রাউজারের Python-এ ব্যর্থতা নীরবে NaN হতে পারেscipy.linalg.cho_factor/cho_solve ব্যবহার, ফলাফলে NaN পরীক্ষা
Evidence বা credible interval দিয়ে model বেছে test set-এ সেই একই সংখ্যা “চূড়ান্ত” বলেEvidence model-এর ভেতরের মাপ; coverage আলাদা ডেটায় মাপতে হয়আলাদা রাখা ডেটায় ৯৫% পরিসর কত শতাংশ ধরে, কয়েকটি seed-এ
Derivation-এ prior variance আর precision গুলিয়ে λ = β/α লেখেসঠিক λ = α/β (noise var ÷ prior var)এক মাত্রার ছোট উদাহরণে দুই পথে সংখ্যা মিলিয়ে দেখুন

কোডের সঙ্গে যাচাইয়ের পথও চেয়ে নিন:

আমার কাছে প্রায় ৫০০টি ডেলিভারির ডেটা আছে (দূরত্ব, ওজন, বৃষ্টি, সময়)। NumPy আর scipy.linalg দিয়ে Bayesian linear regression নিজে লিখতে চাই, scikit-learn 1.8-এর BayesianRidge দিয়ে মিলিয়ে। ১. Gaussian prior N(0, α⁻¹I) আর noise precision β ধরে posterior-এর m_N আর S_N-এর derivation ধাপে ধাপে দাও, completing the square দেখিয়ে। ২. Cholesky (cho_factor, cho_solve) দিয়ে কোড দাও, inv ছাড়া। ৩. predictive mean আর sd-কে noise অংশ আর weight অংশে আলাদা করে দেখাও। ৪. BayesianRidge-এর alpha_ আর lambda_ কোনটি কোন precision, docs-এর বাক্য উদ্ধৃত করে বলো, আর fit_intercept-এর প্রভাব ব্যাখ্যা করো। ৫. আলাদা রাখা ডেটায় ৯৫% predictive পরিসরের coverage মাপার কোড দাও। ৬. কোন জায়গায় তোমার উত্তর ভুল হতে পারে বা আমার যাচাই করা দরকার, আলাদা করে বলো।

AI-এর দেওয়া Bayesian regression-এর কোড বা রিপোর্ট হাতে পেলে — যাচাইয়ের চেকলিস্ট

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।

প্র ০১Bayesian predictive পরিসর আর OLS prediction interval সংখ্যায় প্রায় মিললেও অর্থে আলাদা কেন, আর frequentist বনাম Bayesian বিতর্কের ইতিহাস এখানে কী শেখায়?

OLS prediction interval-এর দাবি একটি পদ্ধতি নিয়ে: একই রকম ডেটা বারবার সংগ্রহ করে প্রতিবার এই সূত্রে পরিসর বানালে, দীর্ঘমেয়াদে ৯৫% পরিসর নতুন পর্যবেক্ষণ ধরবে। Parameter সেখানে স্থির কিন্তু অজানা, এলোমেলো হলো ডেটা। Bayesian predictive পরিসরের দাবি এই নির্দিষ্ট অর্ডার নিয়ে: model আর prior মেনে নিলে, দেখা ডেটার ভিত্তিতে, নতুন অর্ডারের সময় এই পরিসরে থাকার সম্ভাবনা ৯৫%. এখানে অজানা w-কেই এলোমেলো ধরা হয়, কারণ সম্ভাবনা মানে বিশ্বাসের মাত্রা।

বিংশ শতকের প্রথমার্ধে Fisher-এর মতো পরিসংখ্যানবিদেরা “বিপরীত সম্ভাবনা” (inverse probability) নিয়ে কড়া সমালোচনা করেন, কারণ prior বিষয়ভিত্তিক মনে হতো; Harold Jeffreys তাঁর Theory of Probability-তে (১৯৩৯) নিয়মমাফিক “তথ্যহীন” prior দিয়ে Bayesian পথকে রক্ষা করেন। পরে দেখা যায়, linear-Gaussian model-এ ঢিলে prior আর σ-এর ওপর Jeffreys prior নিলে Bayesian predictive হুবহু Student-t prediction interval দেয়: দুই শিবির একই সংখ্যায় পৌঁছায়, ভিন্ন যুক্তিতে।

ব্যবহারিক শিক্ষা হলো, ডেটা বেশি আর prior ঢিলে হলে দার্শনিক পার্থক্য সংখ্যায় প্রায় মুছে যায়। পার্থক্য ফিরে আসে যখন ডেটা কম, prior তথ্যপূর্ণ (যেমন আগের শহরের অভিজ্ঞতা), বা যখন আপনি parameter-এর সম্ভাবনা নিয়ে সরাসরি প্রশ্ন করতে চান (“ঢাল ৪-এর বেশি হওয়ার সম্ভাবনা কত?”), যা frequentist কাঠামো সরাসরি দেয় না। আর দুই পক্ষই একই ফাঁদে পড়ে: model ভুল হলে দুই পরিসরই ভুল। তাই দুই পক্ষের চর্চাতেই আলাদা ডেটায় coverage যাচাই একটি সাধারণ নিয়ম।

মূল উপলব্ধি: একই সংখ্যার পেছনে দুটি আলাদা বাক্য থাকে; কোন বাক্য আপনার সিদ্ধান্তের প্রশ্নের সঙ্গে মেলে তা বুঝে বাছুন, আর সংখ্যাটি আলাদা ডেটায় যাচাই করুন।

প্র ০২Evidence যদি “স্বয়ংক্রিয় Occam-এর ক্ষুর” হয়, তবে Lindley-এর paradox কী সতর্কতা দেয়, আর evidence বনাম cross-validation কখন কোনটি?

Evidence একটি model-কে পুরো prior-এর ওপর গড় করে বিচার করে। নমনীয় model তার prior-এ অনেক রকম ডেটাসেটকে সম্ভব বলে, তাই প্রতিটির ভাগে কম সম্ভাবনা পড়ে; ডেটা যদি সরল model-এর “ছোট জায়গায়” পড়ে, সরলটি জেতে। Jefferys আর Berger ১৯৯২ সালে American Scientist-এ এই যুক্তিকে Occam-এর ক্ষুরের গাণিতিক রূপ হিসেবে জনপ্রিয় করেন, আর MacKay একই বছরে neural network আর interpolation-এ তা প্রয়োগ করেন। এই পর্বে ডিগ্রি ৭-এর fit সেরা হলেও evidence ডিগ্রি ২-কে বেছেছে।

কিন্তু এই শক্তির উল্টো দিকও আছে। Dennis Lindley ১৯৫৭ সালে দেখান, একটি parameter-এর prior যত চওড়া করবেন, সেই parameter-সহ model-এর evidence তত কমবে, ডেটা যাই বলুক: prior-এর আয়তন অসীমের দিকে গেলে Occam factor শূন্যের দিকে যায়। ফলে “তথ্যহীন” চওড়া prior দিয়ে model তুলনা করলে সরল model প্রায় সবসময় জেতে, আর improper (যোগফল অসীম) prior-এ evidence সংজ্ঞায়িতই নয়। Posterior prior-এর মাপে তেমন সংবেদনশীল নয়, কিন্তু evidence খুবই সংবেদনশীল।

Cross-validation সরাসরি নতুন ডেটায় অনুমানের মান মাপে, prior-এর মাপের ওপর কম নির্ভর করে, আর model ভুল হলেও অর্থবহ থাকে; কিন্তু খরচ বেশি আর অল্প ডেটায় অনেক ছড়ায়। Evidence একবারের হিসাবে আসে, অনেক hyperparameter-এর gradient দিতে পারে (ARD-এর মতো), কিন্তু শুধু তখনই বিশ্বাসযোগ্য যখন prior যত্ন করে বাছা আর model মোটামুটি ঠিক। অনেক অভিজ্ঞ চর্চাকারী দুটিই দেখেন, আর দুটি অমিল হলে model-এর অনুমান খোঁজেন।

মূল উপলব্ধি: Evidence prior-সহ পুরো model-এর বিচার; prior-কে ইচ্ছেমতো চওড়া করলে বিচারও ইচ্ছেমতো হয়ে যায়।

প্র ০৩Empirical Bayes ডেটা দিয়ে prior ঠিক করে, তারপর সেই prior দিয়ে আবার একই ডেটা বিশ্লেষণ করে। এটি কি “ডেটা দুবার ব্যবহার”, আর কখন নিরাপদ?

খাঁটি Bayesian দৃষ্টিতে prior ডেটা দেখার আগে ঠিক হওয়ার কথা। Empirical Bayes সেই নিয়ম ভাঙে: evidence সর্বোচ্চ করে α আর β ডেটা থেকে বের করে, তারপর তাদের জানা ধরে posterior হিসাব করে। Herbert Robbins ১৯৫০-এর দশকে নামটি দেন। James আর Stein-এর ১৯৬১ সালের ফল দেখায়, তিন বা ততোধিক গড় একসঙ্গে অনুমানে প্রতিটিকে আলাদা অনুমানের চেয়ে সবাইকে একটি সাধারণ মানের দিকে কিছুটা টানা মোট ভুল কমায়; Efron আর Morris সত্তরের দশকে দেখান, এই shrinkage আসলে empirical Bayes. অর্থাৎ ব্যবহারিকভাবে পদ্ধতিটি খুব সফল।

দুর্বলতা হলো hyperparameter-এর অনিশ্চয়তা হারিয়ে যায়। α আর β একটি বিন্দু হিসেবে বসানো হয়, যেন নিশ্চিত জানা, তাই predictive পরিসর একটু সরু হয়। ডেটা বেশি আর hyperparameter অল্প (এখানে দুটি) হলে এই ক্ষতি ছোট, কারণ evidence-এর চূড়া তখন তীক্ষ্ণ। ডেটা অল্প, বা hyperparameter অনেক (ARD-এ প্রতিটি feature-এ একটি) হলে ঝুঁকি বড়: ARD-এর evidence-এ অনেক স্থানীয় চূড়া থাকতে পারে, আর এটি overfit-ও করতে পারে।

বিকল্প পূর্ণ hierarchical model: α আর β-র ওপরও prior দিয়ে সব একসঙ্গে integral করা। তখন বন্ধ সূত্র থাকে না, MCMC লাগে (পর্ব ৪৭, MCMC — Metropolis-Hastings আর Gibbs sampling). scikit-learn-এর Gamma hyperprior (alpha_1, lambda_1 ইত্যাদি, default ১০−৬) এই দিকে একটি ছোট ইঙ্গিত, কিন্তু সে এখনও শুধু চূড়া নেয়, integral নয়।

মূল উপলব্ধি: Empirical Bayes একটি কার্যকর আপস; ডেটা বেশি আর hyperparameter অল্প হলে নিরাপদ, উল্টোটা হলে hyperparameter-এর অনিশ্চয়তাও model-এ আনুন বা আলাদা ডেটায় coverage যাচাই করুন।

প্র ০৪ARD আর lasso দুটিই অপ্রাসঙ্গিক feature ছাঁটে। পার্থক্য কোথায়, আর ARD-এর ফলকে কোন কোন ক্ষেত্রে অবিশ্বাস করবেন?

Lasso (পর্ব ১৭) একটি নির্দিষ্ট Laplace prior-এর MAP: L1 বলের কোণে optimum পড়ে বলে weight ঠিক শূন্য হয়, আর একটিই λ সব feature-এ খাটে, যা cross-validation দিয়ে বাছতে হয়। ARD প্রতিটি weight-কে নিজস্ব Gaussian prior দেয় আর evidence দিয়ে প্রতিটির precision শেখে; কোনো আলাদা tuning ছাড়াই প্রতিটি feature-এর জন্য একটি “প্রাসঙ্গিকতা” সংখ্যা আর weight-এর posterior sd দেয়। Tipping ২০০১ সালে এই ধারণা দিয়ে relevance vector machine বানান, যা SVM-এর চেয়ে অনেক কম basis রেখে তুলনীয় ফল দেয় বলে তিনি দেখান; Wipf আর Nagarajan পরে দেখান, ARD-কে একটি বিশেষ ধরনের পুনঃওজনযুক্ত L1 সমস্যা হিসেবেও দেখা যায়।

অবিশ্বাসের কারণ কয়েকটি। প্রথমত, একসঙ্গে চলা feature: দূরত্ব আর জ্বালানি খরচ প্রায় একই তথ্য দিলে ARD প্রায় ইচ্ছেমতো একটিকে রেখে অন্যটিকে ছাঁটতে পারে, আর seed বা ছোট পরিবর্তনে বাছাই উল্টে যেতে পারে; lasso-রও একই সমস্যা, elastic net তাই এসেছিল। দ্বিতীয়ত, feature-এর মাপ: standardize না করলে prior-এর তুলনা অর্থহীন। তৃতীয়ত, evidence-এর overfit: অনেক hyperparameter-এ ARD কখনো কখনো দরকারি feature-ও ছেঁটে ফেলে। চতুর্থত, প্রাসঙ্গিকতা অনুমানের, কারণ-কার্যের নয়: “বৃষ্টি” feature-এর বড় weight বলে না বৃষ্টি থামালে ডেলিভারি দ্রুত হবে।

চর্চা হিসেবে ARD-এর বাছাই কয়েকটি bootstrap নমুনায় (পর্ব ২১) চালিয়ে দেখুন কোন feature বারবার টেকে, আর lasso-র path-এর সঙ্গে তুলনা করুন।

মূল উপলব্ধি: ARD প্রতিটি feature-এর জন্য prior শেখে, তাই tuning কম; কিন্তু একসঙ্গে চলা feature, মাপ আর evidence-এর overfit-এ তার বাছাই অস্থির হতে পারে, আর তা কারণ-কার্য নয়।

প্র ০৫বাজারঘর ক্রেতাকে ডেলিভারির সময়ের পরিসর দেখাতে চায়। Bayesian linear regression-এর পরিসর সরাসরি দেখানো কি ঠিক, আর বড় model-এর যুগে এই পদ্ধতির জায়গা কোথায়?

সরাসরি দেখানোর আগে তিনটি প্রশ্ন। প্রথমত, noise কি সত্যিই সব জায়গায় সমান? ঈদের আগের সপ্তাহে, বৃষ্টিতে বা রাতে ছড়ানো বেশি হলে একটি β দিয়ে বানানো পরিসর শান্ত দিনে অকারণে চওড়া আর ব্যস্ত দিনে বিপজ্জনকভাবে সরু। দ্বিতীয়ত, model কি ঠিক? সরলরেখা ডেটার বাইরে চললে epistemic অংশ বাড়ে ঠিকই, কিন্তু ভুল আকারের জন্য কোনো সতর্কতা দেয় না। তৃতীয়ত, coverage: আগের মাসের আলাদা রাখা অর্ডারে ৯০% পরিসর সত্যিই প্রায় ৯০% ধরেছে কি না, জেলা আর সময়ভেদে আলাদা করে। ক্রেতার কাছে কম কথা দিয়ে বেশি দেওয়া ভালো, তাই অনেক দল উঁচু quantile-এর দিকে ঝুঁকে প্রতিশ্রুতি দেয়, যেমন পর্ব ২৪-এ দেখেছেন।

Epistemic অংশের একটি চমৎকার ব্যবহার আছে: নতুন এলাকা চালু হলে যেখানে অনিশ্চয়তা বেশি, সেখানে আগে পরীক্ষামূলক ডেলিভারি চালিয়ে ডেটা সংগ্রহ করা। এটিই active learning (পর্ব ৫৪) আর Bayesian optimization-এর (পর্ব ৪৯) মূল ধারণা।

বড় model-এর যুগেও পদ্ধতিটি হারায়নি। একটি জনপ্রিয় কৌশল হলো একটি neural network-কে feature বানানোর কাজে লাগিয়ে শুধু শেষ স্তরে Bayesian linear regression বসানো: Snoek ও সহকর্মীরা ২০১৫ সালের ICML প্রবন্ধে (DNGO) Bayesian optimization-এর জন্য এমন model ব্যবহার করেন, কারণ Gaussian process-এর মতো O(N³) খরচ লাগে না। Neural network-এর পুরো Bayesian চিকিৎসা গবেষণার সক্রিয় বিষয়, আর তার অনিশ্চয়তা কতটা নির্ভরযোগ্য তা নিয়ে গবেষকদের মধ্যে মতভেদ আছে; পরের deep learning কোর্সে এর আলোচনা আসবে।

মূল উপলব্ধি: পরিসরের সূত্র সহজ, কিন্তু ক্রেতার সামনে দেওয়ার আগে noise-এর অনুমান, model-এর আকার আর বাস্তব coverage যাচাই করতে হয়; আর epistemic অনিশ্চয়তা কোথায় নতুন ডেটা দরকার তা বলার জন্য সবচেয়ে কাজের।

অনুশীলন

হিসাবগুলো খাতায় করুন, তারপর উত্তর মেলান। কোড চালানো ঐচ্ছিক।

  1. হাতে posterior: Model y = wx + ε, prior w ~ N(0, 1/α) যেখানে α = ০.৫, noise precision β = ২. ডেটা (x, y) = (১, ৩) আর (২, ৫)। (ক) Posterior-এর precision, গড় আর variance বের করুন। (খ) একই উত্তর ridge দিয়ে কোন λ-তে আসে, যাচাই করুন। (গ) x = ৩-এ predictive গড় আর variance কত, আর variance-এর কত অংশ noise থেকে?

    (ক) Σx² = ১ + ৪ = ৫, Σxy = ৩ + ১০ = ১৩. Precision = α + βΣx² = ০.৫ + ২ × ৫ = ১০.৫. গড় = βΣxy / precision = ২৬ / ১০.৫ ≈ ২.৪৭৬. Variance = ১/১০.৫ ≈ ০.০৯৫২ (sd ≈ ০.৩০৯)। (খ) λ = α/β = ০.২৫; ridge = Σxy/(Σx² + λ) = ১৩/৫.২৫ ≈ ২.৪৭৬, একই। (OLS হতো ১৩/৫ = ২.৬.) (গ) গড় = ৩ × ২.৪৭৬ ≈ ৭.৪২৯. Variance = 1/β + x² × ০.০৯৫২ = ০.৫ + ০.৮৫৭ ≈ ১.৩৫৭. Noise-এর ভাগ ০.৫/১.৩৫৭ ≈ ৩৭%, বাকি ৬৩% weight-এর অনিশ্চয়তা, কারণ মাত্র দুটি বিন্দু আর x = ৩ ডেটার বাইরে।

  2. সমালোচনা ও নকশা: একজন সহকর্মী বাজারঘরের ডেলিভারি সময়ের জন্য BayesianRidge চালালেন। রিপোর্টে লিখলেন: “alpha_ = ০.০৩, অর্থাৎ prior দুর্বল; নতুন উপজেলায় (৩০ কিমি, আগে কোনো অর্ডার নেই) আমরা mNᵀφ ± ২/√alpha_ পরিসর দেখাব, আর ARD যেহেতু ‘রাতের অর্ডার’ feature ছেঁটেছে, রাতের শিফটে রাইডার কমানো যায়।” কী কী সমস্যা, আর আপনি কীভাবে সাজাবেন?

    সমস্যা: (১) scikit-learn-এ alpha_ noise precision, prior নয়; ০.০৩ মানে noise sd ≈ ৫.৮ মিনিট। (২) ±২/√alpha_ শুধু noise অংশ, plug-in পরিসর; ৩০ কিমি ডেটার বাইরে, সেখানে epistemic অংশই বড়, তাই পরিসর খুব সরু হবে। (৩) Model-এর আকার (সরলরেখা) ৩০ কিমিতে খাটবে কি না, ডেটা নেই। (৪) ARD-এর ছাঁটাই মানে “সময় অনুমানে এই feature বাড়তি তথ্য দেয় না”, রাইডারের চাহিদা বা কারণ-কার্য নয়; feature অন্য feature-এর সঙ্গে জড়িত হলেও ছাঁটা পড়তে পারে।

    নতুন নকশা: predict(X, return_std=True) দিয়ে মোট sd (noise + epistemic) নিন; ডেটার বাইরে পরিসরে স্পষ্ট সতর্কতা দিন বা নতুন উপজেলায় প্রথম কয়েক সপ্তাহ পরীক্ষামূলক অর্ডারে ডেটা সংগ্রহ করুন। আলাদা রাখা মাসে coverage মাপুন, এলাকা আর সময় ভেদে। শিফটের সিদ্ধান্ত নিন অর্ডারের সংখ্যার পূর্বাভাস আর আলাদা বিশ্লেষণে, ARD-এর weight দেখে নয়।

  3. আউটপুট অনুমান করুন: চালানোর আগে লিখে ফেলুন নিচের কোড কী ছাপবে (NumPy, scikit-learn 1.8).
    import numpy as np
    from sklearn.linear_model import Ridge
    Phi = np.array([[1., 1.], [1., 2.], [1., 3.]])
    y = np.array([2., 3., 7.])
    a, b = 1.0, 1.0
    m = b * np.linalg.solve(a * np.eye(2) + b * Phi.T @ Phi, Phi.T @ y)
    print(np.round(m, 3))
    print(np.round(Ridge(alpha=a / b, fit_intercept=False).fit(Phi, y).coef_, 3))
    r = Ridge(alpha=1.0).fit(Phi[:, 1:], y)
    print(round(r.intercept_, 3), np.round(r.coef_, 3))
    [0.25  1.833]
    [0.25  1.833]
    0.667 [1.667]

    ΦᵀΦ = [[৩, ৬], [৬, ১৪]], Φᵀy = [১২, ২৯]. Posterior precision A = [[৪, ৬], [৬, ১৫]], det = ২৪, তাই m = A⁻¹Φᵀy = [(১৫ × ১২ − ৬ × ২৯)/২৪, (−৬ × ১২ + ৪ × ২৯)/২৪] = [০.২৫, ১.৮৩৩]. দ্বিতীয় লাইন একই, কারণ ১-এর কলাম Φ-এ আর fit_intercept=False: ইন্টারসেপ্টেও prior. তৃতীয় লাইন আলাদা: default fit_intercept=True ইন্টারসেপ্টকে শাস্তি দেয় না, ডেটা কেন্দ্রে এনে ঢাল = Sxy/(Sxx + λ) = ৫/(২ + ১) ≈ ১.৬৬৭, ইন্টারসেপ্ট = ৪ − ১.৬৬৭ × ২ ≈ ০.৬৬৭. অর্থাৎ “ridge = posterior mean” মেলাতে prior কোথায় বসেছে, তা দুই দিকে এক হতে হবে। আউটপুট ডেস্কটপে scikit-learn 1.8.0-এ চালিয়ে মেলানো।

  4. Evidence-এর fixed-point হাতে: একটি model-এ βΦᵀΦ-এর তিনটি eigenvalue ৪০, ৫ আর ০.১; এখনকার α = ১. বর্তমান posterior mean-এর mNᵀmN = ৪, N = ২০, আর ‖y − ΦmN‖² = ৩৬. (ক) γ বের করুন আর প্রতিটি দিকের অবদান ব্যাখ্যা করুন। (খ) MacKay-র নিয়মে পরের α আর β কত? (গ) দুটি model-এর log evidence −৪২.৩ আর −৪৫.১ হলে Bayes factor কত?

    (ক) γ = ৪০/৪১ + ৫/৬ + ০.১/১.১ ≈ ০.৯৭৬ + ০.৮৩৩ + ০.০৯১ = ১.৯০০. প্রথম দিকে ডেটা prior-এর চেয়ে ৪০ গুণ কড়া, তাই প্রায় পুরো একটি parameter; দ্বিতীয়টিতে ৫ গুণ, ০.৮৩; তৃতীয় দিকে ডেটা প্রায় কিছুই বলে না, prior-ই ঠিক করে, তাই মাত্র ০.০৯. (খ) α = γ / mNᵀmN = ১.৯০০/৪ = ০.৪৭৫. 1/β = ৩৬/(২০ − ১.৯০০) = ৩৬/১৮.১ ≈ ১.৯৮৯, তাই β ≈ ০.৫০৩ (noise sd ≈ ১.৪১)। নতুন α দিয়ে আবার mN আর γ হিসাব করে চক্র চলতে থাকে, যতক্ষণ না সংখ্যা স্থির হয়। (গ) Bayes factor = e−৪২.৩ + ৪৫.১ = e২.৮ ≈ ১৬.৪, প্রথম model-এর পক্ষে।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমডেলিভারি সময়ের জন্য Bayesian linear regression-এর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Basis function বাছাই আর feature standardize করা
  2. Weight-এর Gaussian prior আর Gaussian noise-এর model লেখা
  3. Evidence সর্বোচ্চ করে α আর β অনুমান করা
  4. শেষ α, β দিয়ে posterior-এর mN আর SN হিসাব করা (Cholesky দিয়ে)
  5. নতুন অর্ডারের predictive গড় আর মোট sd (noise + epistemic) বের করা
  6. আলাদা রাখা অর্ডারে পরিসরের coverage যাচাই করা

Prior w ~ N(0, α⁻¹I) আর noise precision β হলে Bayesian linear regression-এর posterior mean কোন ridge সমাধানের সমান?

  • λ = β/α
  • λ = α
  • λ = α/β
  • λ = αβ

এক মাত্রার model y = wx + ε-এ prior w ~ N(0, 1), noise precision β = 1. একটিমাত্র বিন্দু (x = 2, y = 4) দেখার পর w-এর posterior গড় কত?

  • ২.০
  • ১.৬
  • ০.৮
  • ৪.০

Bayesian linear regression-এ ডেটার পরিসর থেকে অনেক দূরের একটি x-এ predictive variance বড় হয় কেন?

  • Noise variance 1/β দূরে বাড়ে
  • Prior দূরের x-এ চওড়া হয়
  • Predictive গড় বড় হয় বলে
  • Epistemic অংশ φᵀSNφ ডেটা থেকে দূরে বাড়ে

scikit-learn 1.8-এর BayesianRidge fit করার পর alpha_ কী বোঝায়?

  • Noise-এর precision
  • Weight-এর prior precision
  • Ridge-এর শাস্তি λ, যা হাতে দিতে হয়
  • শেষ log marginal likelihood

৩০টি বিন্দুতে polynomial-এর ডিগ্রি ১ থেকে ৭ চালানো হলো। Training ভুল ডিগ্রি ৭-এ সবচেয়ে কম, কিন্তু log evidence ডিগ্রি ২-এ সর্বোচ্চ। এর সবচেয়ে ভালো ব্যাখ্যা কোনটি?

  • Evidence-এর হিসাবে ভুল আছে, কারণ ভালো fit সবসময় বেশি evidence দেয়
  • Evidence আলাদা test set-এ মাপা হয়েছে বলে
  • বাড়তি weight-এর Occam দাম fit-এর লাভের চেয়ে বেশি
  • ডিগ্রি বাড়লে β শূন্য হয়ে যায় বলে

ARDRegression চালানোর পর একটি feature-এর lambda_[j] প্রায় ১,০০০, আর বাকিগুলোর ০.০১-এর কাছে (feature standardize করা)। এর সঠিক অর্থ কোনটি?

  • Feature-টির weight সবচেয়ে বড় আর সবচেয়ে গুরুত্বপূর্ণ
  • Feature-টি এই model-এর অনুমানে প্রায় অপ্রাসঙ্গিক, weight প্রায় শূন্য
  • Feature-টি বদলালে লক্ষ্যের ওপর কোনো কারণগত প্রভাব পড়বে না, প্রমাণিত
  • Feature-টির কারণে noise বেড়েছে

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. Prior w ~ N(0, α⁻¹I), noise precision β: posterior SN⁻¹ = αI + βΦᵀΦ, mN = βSNΦᵀy. Precision যোগ হয়, তাই একটি একটি বিন্দুতে হালনাগাদ আর একবারে সব দেওয়ার ফল এক।
  2. Posterior mean = ridge, λ = α/β; মেলাতে prior কোথায় বসেছে (ইন্টারসেপ্টে কি না) দুই দিকে এক রাখুন।
  3. Predictive variance = 1/β (aleatoric, ডেটায় কমে না) + φᵀSNφ (epistemic, ডেটা থেকে দূরে বাড়ে)। Plug-in পরিসর দ্বিতীয়টি বাদ দেয়।
  4. Evidence = fit + Occam; সর্বোচ্চ করে α, β আর basis বাছা যায় (empirical Bayes), কিন্তু evidence prior-এর মাপে সংবেদনশীল। scikit-learn-এ alpha_ = noise precision, lambda_ = weight precision.
  5. ARD প্রতিটি weight-এর precision শেখে আর অপ্রাসঙ্গিক feature শূন্যে চাপে; Laplace approximation দিয়ে logistic regression-ও আনুমানিক Bayesian করা যায়। সব পরিসর আলাদা ডেটায় coverage দিয়ে যাচাই করুন।

পরের পর্বে: এই পর্বে prior বসেছিল কয়েকটি weight-এর ওপর। পর্ব ৪৬ (Gaussian process — kernel দিয়ে অনিশ্চয়তাসহ অনুমান)-এ prior বসবে সরাসরি function-এর ওপর: basis-এর সংখ্যা অসীম, তবু হিসাব হবে শুধু ডেটার বিন্দুগুলোর kernel matrix দিয়ে, আর ডেটা থেকে দূরে অনিশ্চয়তা নিজে থেকেই prior-এ ফিরে যাবে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান