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

Maximum likelihood আর MAP — model fit করার মূলনীতি

Maximum Likelihood and MAP — Log-Likelihood, Closed-Form and Numerical MLE, Fisher Information, Standard Errors and Priors

Taught in Bangla, this lesson derives maximum likelihood estimates for Bernoulli, Poisson, exponential and Gaussian models, shows log-likelihood underflow and the bias of the variance MLE, and connects MLE to cross-entropy and common losses. It fits a gamma model with scipy.optimize, gets standard errors from the Hessian and bootstrap, and treats MAP as penalised MLE, including perfect separation, with in-browser and desktop runs.

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

  • Likelihood আর সম্ভাবনার পার্থক্য, আর log-likelihood কেন ব্যবহার হয়
  • Bernoulli, Poisson, exponential আর Gaussian-এর MLE খাতায় derive করা, আর variance-এর bias সংখ্যায় দেখা
  • MLE, cross-entropy, KL divergence আর squared loss-এর সম্পর্ক
  • Closed form না থাকলে scipy.optimize দিয়ে MLE, আর Fisher information থেকে standard error
  • MAP-কে শাস্তিসহ MLE হিসেবে পড়া, আর কখন MLE overfit করে তা চেনা

AI-এর ভিত্তি কোর্সের পর্ব ৩৬-এ Bernoulli, Poisson আর normal distribution চিনেছেন, পর্ব ৩৮-এর “আরও গভীরে” বাক্সে দেখেছেন cross-entropy কমানো আর likelihood বাড়ানো একই কথা, আর পর্ব ৫০-এ Beta prior দিয়ে ফেরতের হারের MLE আর MAP পাশাপাশি রেখেছেন। এই কোর্সের পর্ব ০২-এ loss function বেছেছেন, আর পর্ব ১৭-এ শাস্তিকে prior হিসেবে পড়েছেন। এই পর্ব সেই টুকরোগুলোকে একটি নীতির নিচে আনে: model fit করা মানে প্রায় সবসময় কোনো likelihood-কে সর্বোচ্চ করা, কখনো একটি prior-সহ। হাতিয়ার আগের মডিউলের: পর্ব ১১-এর gradient আর Hessian. চালানো যায় এমন চারটি ব্লক পাতাতেই চলে (ব্রাউজারের Python, NumPy, SciPy আর matplotlib); প্রথমবার প্যাকেজ নামতে কয়েক সেকেন্ড লাগে।

১ · Likelihood — ডেটা স্থির, parameter বদলায়

ডাক্তারের চেম্বারে রোগী এসেছেন: জ্বর, গায়ে ব্যথা, চোখের পেছনে ব্যথা। উপসর্গগুলো এখন বদলাবে না; সেগুলো স্থির। ডাক্তার মনে মনে প্রতিটি সম্ভাব্য রোগ যাচাই করেন: “ডেঙ্গু হলে এই উপসর্গগুলো দেখার সম্ভাবনা কত? সাধারণ সর্দি-জ্বর হলে কত?” যে রোগ ধরলে দেখা উপসর্গগুলো সবচেয়ে প্রত্যাশিত হয়, সেটিই maximum likelihood-এর উত্তর। অভিজ্ঞ ডাক্তার অবশ্য আরেকটি কথাও ভাবেন: এই মৌসুমে এলাকায় কোন রোগ কত সাধারণ। সেই পূর্বধারণা যোগ করলে আসে MAP, যা এই পর্বের দ্বিতীয় ভাগ।

ধরুন x1, …, xn ডেটা, আর model বলে প্রতিটি xi এসেছে একটি distribution p(x | θ) থেকে, যেখানে θ (থিটা) হলো অজানা parameter. পর্যবেক্ষণগুলো স্বাধীন আর একই distribution থেকে এলে (iid), পুরো ডেটার সম্ভাবনা গুণফল। একে θ-এর function হিসেবে পড়লে তার নাম likelihood:

L(θ) = ∏i=1..n p(xi | θ)     ℓ(θ) = log L(θ) = ∑i=1..n log p(xi | θ)

সূত্রটি সম্ভাবনার মতো দেখায়, কিন্তু পড়ার দিক আলাদা। সম্ভাবনায় θ স্থির আর x বদলায়, তাই সব x-এর ওপর যোগফল ১. Likelihood-এ x স্থির আর θ বদলায়, আর θ-এর ওপর L(θ)-এর যোগফল বা সমাকলন ১ হওয়ার কোনো বাধ্যবাধকতা নেই। তাই “θ = ০.৪ হওয়ার likelihood ০.০৩৫” মানে এই নয় যে θ = ০.৪ হওয়ার সম্ভাবনা ০.০৩৫; সেই দাবির জন্য prior লাগে (অংশ ৭)। Maximum likelihood estimate (MLE) হলো θ̂ = argmaxθ L(θ), অর্থাৎ যে θ দেখা ডেটাকে সবচেয়ে প্রত্যাশিত করে।

Log নেওয়ার তিনটি কারণ। প্রথম, log একটানা বাড়ে (monotone), তাই L আর ℓ-এর সর্বোচ্চ বিন্দু একই θ. দ্বিতীয়, গুণফল যোগফলে বদলায়, আর যোগফলের derivative নেওয়া সহজ। তৃতীয়টি ব্যবহারিক: অনেক ছোট সম্ভাবনার গুণফল দ্রুত float-এর সবচেয়ে ছোট মানের নিচে নেমে চুপচাপ ০ হয়ে যায় (underflow); অংশ ২-এর ব্লকে ২০০০টি সংখ্যার গুণফল ঠিক এভাবেই ০.০ হবে, যেখানে log-এর যোগফল একটি সাধারণ সংখ্যা। Optimizer কমানোর কাজে অভ্যস্ত, তাই বাস্তবে আমরা negative log-likelihood (NLL) −ℓ(θ) কমাই।

সবচেয়ে ছোট উদাহরণ: বাজারঘরের একটি নতুন পণ্যের পাঁচটি অর্ডার, ১ মানে ফেরত এসেছে, ০ মানে আসেনি। Model: প্রতিটি অর্ডার স্বাধীনভাবে θ সম্ভাবনায় ফেরত আসে, অর্থাৎ Bernoulli distribution, p(x | θ) = θx(1 − θ)1−x. নিচের stepper পদে পদে log-likelihood গড়ে।

Model: প্রতিটি অর্ডার θ সম্ভাবনায় ফেরত (1), নইলে 0; log মানে স্বাভাবিক log (ln)
ধাপ
পদ
চলতি ℓ
  1. প্রস্তুতি। একটি θ ধরে নিই, ধরুন ০.৪. তাহলে ফেরতের সম্ভাবনা ০.৪, না-ফেরতের ০.৬. ডেটা স্থির: ১, ০, ০, ১, ০.
  2. প্রথম দুটি পদ। অর্ডার ১ ফেরত, তাই log ০.৪ = −০.৯১৬; অর্ডার ২ ফেরত নয়, তাই log ০.৬ = −০.৫১১. চলতি যোগফল −১.৪২৭.
  3. বাকি তিনটি পদ। ০, ১, ০ থেকে আরও −০.৫১১, −০.৯১৬ আর −০.৫১১. মোট ℓ(০.৪) = −৩.৩৬৫. গুণ নয়, শুধু যোগ।
  4. Log থেকে ফেরা। e−৩.৩৬৫ = ০.০৩৪৫৬, যা সরাসরি গুণফল ০.৪² × ০.৬³-এর সমান। পাঁচটি পদেই সংখ্যাটি ছোট; হাজার পদে float-এর নিচে নেমে যেত।
  5. অন্য θ যাচাই। θ = ০.২-এ ℓ = −৩.৮৮৮, θ = ০.৬-এ −৩.৭৭১. দুটিই −৩.৩৬৫-এর চেয়ে ছোট, অর্থাৎ এই ডেটা θ = ০.৪-এ বেশি প্রত্যাশিত।
  6. সর্বোচ্চ বিন্দু। অংশ ২-এ derive করব যে সর্বোচ্চ ঠিক θ̂ = k/n = ২/৫ = ০.৪-এ। ডেটার ক্রম (১, ০, ০, ১, ০ নাকি ০, ০, ১, ১, ০) ℓ-কে বদলায় না; শুধু k আর n লাগে।

২ · MLE হাতে — Bernoulli, Poisson আর exponential

রেসিপি সবসময় একই: ℓ(θ) লিখুন, θ-এর সাপেক্ষে derivative নিন, শূন্য বসিয়ে সমাধান করুন, তারপর দ্বিতীয় derivative ঋণাত্মক কি না দেখে নিশ্চিত হোন যে বিন্দুটি সর্বোচ্চ। ℓ-এর প্রথম derivative-এর আলাদা নাম আছে, score function; “score = ০” সমীকরণকে বলে likelihood equation.

Bernoulli. n-টি অর্ডারে k-টি ফেরত হলে ℓ(θ) = k log θ + (n − k) log(1 − θ). Derivative: k/θ − (n − k)/(1 − θ). শূন্য বসালে k(1 − θ) = (n − k)θ, অর্থাৎ θ̂ = k/n. দ্বিতীয় derivative −k/θ² − (n − k)/(1 − θ)², যা সবসময় ঋণাত্মক, তাই এটি সর্বোচ্চ। (k = ০ বা k = n হলে সর্বোচ্চ সীমানায়, θ̂ = ০ বা ১; অংশ ৮-এ এর বিপদ দেখব।)

Poisson. একটি জেলায় দিনে কতটি অর্ডার আসে, এমন গণনার জন্য Poisson distribution: p(x | λ) = e−λλx/x!, যেখানে λ (ল্যামডা) গড় হার। নিচের stepper পাঁচ দিনের ডেটায় derivative শূন্য বসানোর প্রতিটি ধাপ দেখায়।

p(x │ λ) = e^(−λ) λ^x / x!n = 5

            
  1. Likelihood. পাঁচ দিন স্বাধীন ধরে পাঁচটি Poisson সম্ভাবনার গুণফল। মোট অর্ডার ৩০.
  2. Log নেওয়া। প্রতিটি পদ xi log λ − λ − log xi!. যোগ করলে ৩০ log λ − ৫λ − C. ধ্রুবক C-তে λ নেই, তাই MLE-এর জন্য তার মান লাগে না।
  3. Derivative. dℓ/dλ = ৩০/λ − ৫. λ = ৫-এ ঢাল +১ (ℓ বাড়ছে), λ = ৭-এ −০.৭১৪ (ℓ কমছে), তাই চূড়া মাঝখানে।
  4. শূন্য বসানো। ৩০/λ = ৫, তাই λ̂ = ৬, যা পাঁচ দিনের গড়। সাধারণভাবে Poisson-এর MLE সবসময় নমুনার গড় x̄.
  5. সর্বোচ্চ কি না। দ্বিতীয় derivative −∑x/λ², λ̂ = ৬-এ −০.৮৩৩. ঋণাত্মক, তাই এটি সত্যিই সর্বোচ্চ; আর ℓ পুরোটাই concave (সব λ > ০-তে দ্বিতীয় derivative ঋণাত্মক), তাই একমাত্র সর্বোচ্চ।
  6. বক্রতা থেকে অনিশ্চয়তা। চূড়ায় বক্রতা ০.৮৩৩ = n/λ̂. এর inverse-এর বর্গমূল √১.২ = ১.০৯৫, যা λ̂-এর standard error. চূড়া যত সরু, অনুমান তত নিশ্চিত; অংশ ৫ এর কারণ দেখাবে।

Exponential. দুটি অর্ডারের মাঝের সময় বা একজন রাইডারের পরের কাজ পাওয়ার অপেক্ষা প্রায়ই exponential distribution দিয়ে ধরা হয়: p(x | λ) = λe−λx, x ≥ ০. ℓ(λ) = n log λ − λ∑xi, derivative n/λ − ∑xi = ০, তাই λ̂ = n/∑xi = 1/x̄. পাঁচটি অপেক্ষা ২, ৫, ৩, ৬ আর ৪ মিনিট হলে x̄ = ৪, আর λ̂ = ০.২৫ প্রতি মিনিটে। লক্ষ করুন, গড় অপেক্ষা 1/λ-এর MLE সরাসরি x̄ = ৪: parameter-কে নতুন রূপে লিখলে (λ থেকে 1/λ) MLE-ও একই রূপান্তরে যায়। এটি MLE-এর invariance ধর্ম, যা অংশ ৫-এ আবার আসবে।

নিচের ব্লক বাজারঘরের দুটি কাল্পনিক ডেটায় (৪০টি অর্ডারের ফেরত, আর এক জেলার ৩০ দিনের অর্ডারের সংখ্যা) likelihood আর log-likelihood-এর বক্ররেখা আঁকে, closed-form MLE লাল দাগে চিহ্নিত করে, grid-এ খোঁজা সর্বোচ্চ বিন্দুর সঙ্গে মেলায়, আর underflow-টি নিজের চোখে দেখায়।

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

rng = np.random.default_rng(42)            # কাল্পনিক বাজারঘর
ret = rng.binomial(1, 0.12, size=40)        # ৪০টি অর্ডার: 1 = ফেরত এসেছে
orders = rng.poisson(6.5, size=30)          # এক জেলায় ৩০ দিনের অর্ডারের সংখ্যা
k, n = ret.sum(), ret.size
th = np.linspace(0.005, 0.4, 400)
L_b = th**k * (1 - th)**(n - k)             # likelihood: θ-এর function
ll_b = k * np.log(th) + (n - k) * np.log(1 - th)
lam = np.linspace(4, 10, 400)
ll_p = stats.poisson.logpmf(orders[:, None], lam).sum(axis=0)

print(f"returns: k = {k} of n = {n}; MLE k/n = {k / n:.4f}; grid argmax = {th[ll_b.argmax()]:.4f}")
print(f"orders : sum = {orders.sum()}, n = {orders.size}; MLE mean = {orders.mean():.4f}; grid argmax = {lam[ll_p.argmax()]:.4f}")
print(f"largest likelihood value (returns): {L_b.max():.3e}")
print(f"Poisson likelihood at the MLE     : {np.exp(ll_p.max()):.3e}")
big = rng.poisson(6.5, size=2000)
print("product of 2000 pmf values:", np.prod(stats.poisson.pmf(big, 6.5)),
      "| sum of logpmf:", round(stats.poisson.logpmf(big, 6.5).sum(), 1))

fig, ax = plt.subplots(2, 2, figsize=(7, 5), layout="constrained")
for a, x, y, m, t in [(ax[0, 0], th, L_b, k / n, "Bernoulli likelihood"),
                      (ax[1, 0], th, ll_b, k / n, "Bernoulli log-likelihood"),
                      (ax[0, 1], lam, np.exp(ll_p - ll_p.max()), orders.mean(), "Poisson likelihood (scaled)"),
                      (ax[1, 1], lam, ll_p, orders.mean(), "Poisson log-likelihood")]:
    a.plot(x, y, lw=2); a.axvline(m, color="tab:red", ls="--", label=f"MLE = {m:.3f}")
    a.set_title(t, fontsize=10); a.legend(fontsize=8)
ax[1, 0].set_xlabel("return rate theta"); ax[1, 1].set_xlabel("orders per day lambda")
plt.show()

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

returns: k = 5 of n = 40; MLE k/n = 0.1250; grid argmax = 0.1248
orders : sum = 188, n = 30; MLE mean = 6.2667; grid argmax = 6.2707
largest likelihood value (returns): 2.850e-07
Poisson likelihood at the MLE     : 9.929e-30
product of 2000 pmf values: 0.0 | sum of logpmf: -4732.3

৪০টি অর্ডারে ৫টি ফেরত, তাই সূত্র বলে θ̂ = ০.১২৫; ৪০০ বিন্দুর grid-এ সবচেয়ে বড় ℓ পাওয়া গেছে ০.১২৪৮-এ, grid-এর ফাঁকের মধ্যে একই উত্তর। ৩০ দিনে মোট ১৮৮টি অর্ডার, গড় ৬.২৬৬৭, আর grid-এর চূড়া ৬.২৭০৭. ডেটা বানানো হয়েছিল আসল হার ০.১২ আর ৬.৫ দিয়ে; MLE সেগুলোর কাছে, কিন্তু হুবহু নয়, কারণ নমুনা ছোট। এবার likelihood-এর মাপ দেখুন: ফেরতের ক্ষেত্রে সর্বোচ্চ মানও ২.৮৫ × ১০−৭, আর Poisson-এ মাত্র ৩০টি দিনেই ৯.৯৩ × ১০−৩০. সংখ্যাগুলো ছোট হওয়া কোনো ভুল নয়; নির্দিষ্ট একটি ডেটাসেট দেখার সম্ভাবনা স্বভাবতই ছোট। ২০০০ দিনের গুণফল ঠিক ০.০, অর্থাৎ underflow: সব θ-এ ০ হলে কোনো θ-কে অন্যটির চেয়ে ভালো বলা যায় না। একই তথ্য log-এর যোগফলে −৪৭৩২.৩, একটি সাধারণ সংখ্যা। ছবির ওপরের সারিতে likelihood (Poisson-এরটি সর্বোচ্চ দিয়ে ভাগ করা, নইলে অক্ষে সংখ্যা পড়া যায় না), নিচের সারিতে log-likelihood: চূড়া একই জায়গায়, কিন্তু log-এর বক্ররেখা মসৃণ উল্টো বাটির মতো, যা optimizer-এর জন্য অনেক সহজ।

৩ · Gaussian — গড়, variance আর n দিয়ে ভাগের bias

ঢাকার ভেতরের ডেলিভারির সময় (ঘণ্টায়) একটি ঘণ্টাকৃতি normal distribution N(μ, σ²) দিয়ে ধরা যাক। দুটি parameter, তাই দুটি আংশিক derivative:

ℓ(μ, σ²) = −(n/2) log(2πσ²) − ∑(xi − μ)² / (2σ²)

μ-এর সাপেক্ষে: ∑(xi − μ)/σ² = ০, তাই μ̂ = x̄. σ²-এর সাপেক্ষে (σ²-কে একটি চলক v ধরে): −n/(2v) + ∑(xi − μ)²/(2v²) = ০, তাই σ̂² = (1/n)∑(xi − x̄)². লক্ষ করুন, μ̂ বের করতে σ² জানতে হয়নি; আর ℓ-এর প্রথম পদ দেখায় কেন σ শূন্যের দিকে যেতে পারে না: log σ² তখন −∞-এর দিকে যায়, আর −(n/2) log σ² পদটি ফুলে উঠলেও দ্বিতীয় পদ আরও দ্রুত −∞ হয়।

AI-এর ভিত্তি কোর্সের পর্ব ৩৭-এ শিখেছেন নমুনা থেকে variance অনুমানে n − 1 দিয়ে ভাগ করা হয় (Bessel’s correction). এখানে দেখা যাচ্ছে MLE ঠিক সেটি করে না: সে n দিয়ে ভাগ করে। কারণ: বিচ্যুতিগুলো মাপা হচ্ছে x̄ থেকে, যা একই ডেটা থেকে এমনভাবে বসানো যে ∑(xi − x̄)² সম্ভাব্য সবচেয়ে ছোট হয়। আসল μ থেকে মাপলে বর্গের যোগফল গড়ে বড় হতো। হিসাব করলে E[σ̂²] = ((n − 1)/n)·σ², অর্থাৎ গড়ে একটু ছোট। একে বলে bias: অনুমানের গড় আর আসল মানের পার্থক্য, এখানে −σ²/n. n বাড়লে bias শূন্যে যায়, তাই অনুমানটি “biased কিন্তু consistent”. নিচের ব্লক ২০,০০০টি ছোট নমুনায় এটি সংখ্যায় দেখায়, আর একটি অপ্রত্যাশিত দিকও: বর্গ-ভুলের মাপে biased অনুমানটিই জেতে।

import numpy as np

rng = np.random.default_rng(7)             # কাল্পনিক: ঢাকার ভেতরে ডেলিভারির সময় (ঘণ্টা)
mu, sigma = 26.0, 6.0                      # আসল গড় আর sd, তাই আসল variance 36
reps = 20000                               # ২০,০০০টি আলাদা ছোট নমুনা

for n in (2, 5, 20, 100):
    x = rng.normal(mu, sigma, size=(reps, n))
    v_mle = x.var(axis=1, ddof=0)          # MLE: n দিয়ে ভাগ
    v_unb = x.var(axis=1, ddof=1)          # unbiased: n − 1 দিয়ে ভাগ
    print(f"n = {n:3d} | mean of mu_hat {x.mean(axis=1).mean():6.2f}"
          f" | E[MLE var] {v_mle.mean():5.2f} (theory {36 * (n - 1) / n:5.2f})"
          f" | E[unbiased] {v_unb.mean():5.2f}")

x = rng.normal(mu, sigma, size=(reps, 5))  # n = 5-এ বর্গ-ভুল (MSE) তুলনা
for name, d in (("MLE      (ddof=0)", 0), ("unbiased (ddof=1)", 1)):
    v = x.var(axis=1, ddof=d)
    print(f"{name}: bias {v.mean() - 36:+6.2f}  sd {v.std():5.2f}"
          f"  MSE {np.mean((v - 36) ** 2):6.1f}")

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

n =   2 | mean of mu_hat  25.95 | E[MLE var] 17.70 (theory 18.00) | E[unbiased] 35.39
n =   5 | mean of mu_hat  26.02 | E[MLE var] 28.84 (theory 28.80) | E[unbiased] 36.05
n =  20 | mean of mu_hat  26.01 | E[MLE var] 34.14 (theory 34.20) | E[unbiased] 35.94
n = 100 | mean of mu_hat  26.00 | E[MLE var] 35.63 (theory 35.64) | E[unbiased] 35.99
MLE      (ddof=0): bias  -7.30  sd 20.48  MSE  472.8
unbiased (ddof=1): bias  -0.13  sd 25.60  MSE  655.5

গড়ের MLE x̄ সব n-এ প্রায় ঠিক ২৬, অর্থাৎ unbiased. Variance-এর MLE-এর গড় কিন্তু তত্ত্বের (n − 1)/n × ৩৬-এর সঙ্গে মেলে: n = ২-এ মাত্র ১৭.৭০ (তত্ত্বে ১৮, আসলের প্রায় অর্ধেক), n = ৫-এ ২৮.৮৪ (তত্ত্বে ২৮.৮০), n = ১০০-এ ৩৫.৬৩. n − 1 দিয়ে ভাগ করা অনুমানের গড় প্রতিবার ৩৬-এর কাছে। এবার শেষ দুই লাইন, n = ৫-এ: MLE-এর bias −৭.৩, কিন্তু ছড়ানো (sd) ২০.৪৮, যেখানে unbiased অনুমানের ২৫.৬০. মোট বর্গ-ভুল (MSE = bias² + variance) MLE-এর ৪৭২.৮, unbiased-এর ৬৫৫.৫. তত্ত্বের মান σ⁴(2n − 1)/n² = ৪৬৬.৬ আর 2σ⁴/(n − 1) = ৬৪৮; ২০,০০০ নমুনার অনুমান তার কাছেই। অর্থাৎ “unbiased” মানে “সবচেয়ে নির্ভুল” নয়: ছোট n-এ সামান্য bias নিয়ে variance কমানো লাভজনক, যা পর্ব ১৭-এর shrinkage-এর একই যুক্তি। ব্যবহারিক সতর্কতা: NumPy-র np.var-এর default ddof=0 (MLE), pandas-এর Series.var-এর default ddof=1. একই ডেটায় দুই library আলাদা সংখ্যা দেবে।

৪ · MLE মানে loss কমানো — cross-entropy, KL আর squared error

গড় NLL লিখুন: −(1/n)∑ log qθ(xi), যেখানে qθ হলো model. ডেটার নিজস্ব বণ্টন p̂ (প্রতিটি দেখা মানে ১/n ওজন) ধরলে এটি ঠিক −∑ p̂(x) log qθ(x), অর্থাৎ p̂ আর qθ-এর cross-entropy H(p̂, qθ). আর H(p̂, q) = H(p̂) + KL(p̂ ‖ q), যেখানে H(p̂) θ-এর ওপর নির্ভর করে না। তাই:

MLE = argminθ H(p̂, qθ) = argminθ KL(p̂ ‖ qθ)

অর্থাৎ MLE ডেটার বণ্টনের সবচেয়ে কাছের model খোঁজে, যেখানে “কাছ” মাপা হয় KL দিয়ে। n বড় হলে p̂ আসল বণ্টন p-এর কাছে যায় (law of large numbers), তাই MLE আসলে KL(p ‖ qθ) কমায়। Model যদি সঠিক হয়, সেই সর্বনিম্ন KL শূন্য, আর আসল θ-তে পৌঁছায়; model ভুল হলে (misspecification) MLE পৌঁছায় KL-এ “সবচেয়ে কাছের ভুল model”-এ। এই দ্বিতীয় কথাটি ভাবনার প্রশ্ন ৩-এ আবার আসবে।

এবার supervised learning. Regression-এ model বলে y = fw(x) + ε, ε ~ N(০, σ²). তাহলে একটি সারির NLL = (y − fw(x))²/(2σ²) + ½ log(2πσ²). σ স্থির ধরলে w-এর জন্য বাকি থাকে শুধু বর্গ-ভুলের যোগফল। অর্থাৎ least squares হলো Gaussian noise ধরে MLE. ঐতিহাসিকভাবে যুক্তিটি উল্টো দিক থেকেও এসেছিল: Adrien-Marie Legendre ১৮০৫ সালে least squares প্রকাশ করেন, আর Carl Friedrich Gauss ১৮০৯ সালে দেখান কোন ভুলের বণ্টন ধরলে গড়ই সবচেয়ে সম্ভাব্য মান হয়; উত্তর ছিল আজকের normal distribution. পুরো টেবিল:

Model যা ধরেএকটি সারির NLL (ধ্রুবক বাদে)পরিচিত নাম
y ~ N(f(x), σ²), σ স্থির(y − f(x))²/(2σ²)squared error, least squares
y ~ Laplace(f(x), b)|y − f(x)|/babsolute error; সমাধান median-ধাঁচের
y ∈ {০, ১}, y ~ Bernoulli(σ(wᵀx))−y log p − (1 − y) log(1 − p)log loss, logistic regression
y গণনা, y ~ Poisson(ewᵀx)μ − y log μ, যেখানে μ = ewᵀxPoisson loss বা deviance (পর্ব ২০)
y ~ N(f(x), σ(x)²), σ-ও শেখা(y − f)²/(2σ²) + log σheteroscedastic Gaussian NLL

পর্ব ০২-এ loss বেছেছিলেন ব্যবসার প্রশ্ন দেখে; এই টেবিল দেখায় প্রতিটি পরিচিত loss-এর পেছনে একটি লুকানো noise-এর অনুমান আছে। MSE বাছা মানে “ভুলগুলো ঘণ্টাকৃতি আর সব জায়গায় সমান ছড়ানো” মেনে নেওয়া। ডেলিভারির সময়ের মতো ডান দিকে লম্বা লেজের ডেটায় এই অনুমান দুর্বল, তাই সেখানে অন্য বণ্টন (পরের অংশের gamma) বা অন্য loss ভালো। AI-এর ভিত্তি কোর্সের পর্ব ৫৯-এর logistic regression-এর cross-entropy loss ঠিক তৃতীয় সারি, আর Poisson-এর সারি পর্ব ২০ (Exponential family আর GLM — Poisson, binomial আর link function)-এর বিষয়।

৫ · Fisher information — চূড়ার বক্রতা থেকে standard error

MLE একটি সংখ্যা দেয়, কিন্তু সেই সংখ্যা কতটা বিশ্বাসযোগ্য? Stepper ২-এর শেষ ধাপের ইঙ্গিত: log-likelihood-এর চূড়া সরু হলে ডেটা θ-কে শক্তভাবে আটকে রাখে; চ্যাপ্টা হলে অনেক θ প্রায় সমান ভালো। চূড়ার বক্রতা মাপে দ্বিতীয় derivative, আর তার ঋণাত্মক রূপের নাম Fisher information:

I(θ) = −E[ d²ℓ/dθ² ]     J(θ̂) = −d²ℓ/dθ² |θ = θ̂     SE(θ̂) ≈ 1/√J(θ̂)

I(θ) হলো প্রত্যাশিত (expected) information, আর J(θ̂) হলো দেখা ডেটায় হিসাব করা observed information. একাধিক parameter-এ J হয়ে যায় NLL-এর Hessian (পর্ব ১১), আর SE আসে J−1-এর কর্ণের বর্গমূল থেকে। n-টি iid পর্যবেক্ষণে information যোগ হয়: In(θ) = n·I1(θ). তাই SE ∝ 1/√n, যা পর্ব ০৪-এর “mean ± sd/√n”-এর সাধারণ রূপ। কয়েকটি পরিচিত মান, প্রতিটি পর্যবেক্ষণে:

ModelMLEI1(θ)SE(θ̂)
Bernoulli(θ)k/n1/(θ(1 − θ))√(θ̂(1 − θ̂)/n)
Poisson(λ)x̄1/λ√(λ̂/n)
Exponential(λ)1/x̄1/λ²λ̂/√n
N(μ, σ²), শুধু μx̄1/σ²σ/√n

একটি numerical: ৮০টি অর্ডারে ১২টি ফেরত। θ̂ = ০.১৫, SE = √(০.১৫ × ০.৮৫/৮০) = ০.০৩৯৯. বড় n-এ θ̂ মোটামুটি normal, তাই প্রায় ৯৫% confidence interval ০.১৫ ± ১.৯৬ × ০.০৩৯৯ = (০.০৭২, ০.২২৮). এই ধাঁচের পরিসরকে Wald interval বলে; θ̂ শূন্য বা একের কাছে আর n ছোট হলে এটি খারাপ আচরণ করে (যেমন k = ০-এ প্রস্থ শূন্য), তখন অন্য পদ্ধতি লাগে।

একই θ̂, ভিন্ন n: চূড়ার বক্রতাই অনিশ্চয়তা

Bernoulli log-likelihood minus its maximum, θ̂ = 0.3, for n = 10 and n = 100

Relative log-likelihood for n = 10 and n = 100 with the same MLE 0.1θ̂ = 0.30.50.7 0−2−4−6 n = 10 (চ্যাপ্টা) n = 100 (খাড়া) −1.92 0.085–0.61 0.22–0.39
ছবি ৫.১ — দুটি ডেটাতেই ফেরতের অনুপাত ০.৩, তাই চূড়া একই জায়গায়। n = ১০০-এর বক্রতা দশ গুণ (In = n·I1), তাই চূড়া সরু। ড্যাশ রেখা সর্বোচ্চের চেয়ে ১.৯২ নিচে; যেসব θ-তে বক্ররেখা এর ওপরে, সেগুলো প্রায় ৯৫% likelihood-ভিত্তিক পরিসর: n = ১০-এ প্রায় ০.০৮৫ থেকে ০.৬১, n = ১০০-এ ০.২২ থেকে ০.৩৯. Wald-এর SE হলো √(০.২১/n): ০.১৪৫ আর ০.০৪৬.

MLE-এর তিনটি তাত্ত্বিক গুণ, কথায়

  • Consistency: model ঠিক থাকলে আর কিছু নিয়মিত শর্ত মানলে, n বাড়ার সঙ্গে θ̂ আসল θ-এর দিকে যায়। এমন অনুমানকে consistent estimator বলে। অংশ ৩-এর σ̂² biased কিন্তু consistent.
  • Asymptotic normality আর efficiency: বড় n-এ θ̂ মোটামুটি N(θ, 1/In(θ)) (asymptotic normality), আর Cramér–Rao bound বলে কোনো unbiased অনুমানের variance 1/In(θ)-এর নিচে যেতে পারে না। তাই বড় n-এ MLE সর্বোচ্চ দক্ষ। ছোট n-এ এই প্রতিশ্রুতি নেই।
  • Invariance: g(θ)-এর MLE হলো g(θ̂). λ̂ = 1/x̄ হলে গড় অপেক্ষার MLE x̄, আর ফেরতের odds θ/(1 − θ)-এর MLE θ̂/(1 − θ̂). Unbiasedness এই ধর্ম মানে না: σ̂² unbiased করলেও σ̂ (বর্গমূল) biased থাকে।

৬ · সূত্র নেই — scipy.optimize দিয়ে numerical MLE

জেলার বাইরের ডেলিভারির সময় ধনাত্মক আর ডান দিকে হেলানো: বেশিরভাগ ২ থেকে ৪ দিনে, কিছু ৮–৯ দিনে। Gaussian এখানে মানায় না (ঋণাত্মক সময় দেয়)। স্বাভাবিক পছন্দ gamma distribution, যার shape k আর scale s; গড় k·s, variance k·s². এর log-likelihood:

ℓ(k, s) = (k − 1)∑log xi − ∑xi/s − n·k·log s − n·log Γ(k)

s-এর সাপেক্ষে derivative শূন্য বসালে ŝ = x̄/k, অর্থাৎ k̂·ŝ = x̄ হুবহু। কিন্তু k-এর সমীকরণ log k − ψ(k) = log x̄ − (1/n)∑log xi, যেখানে ψ হলো digamma function; এর কোনো closed form নেই। তখন সংখ্যা দিয়ে NLL কমাতে হয়, ঠিক পর্ব ১৫-এর BFGS বা Newton দিয়ে। ভালো অভ্যাসগুলো:

  • NLL কমান, likelihood বাড়াবেন না: minimize কমায়, আর log-এর যোগফল underflow এড়ায়। stats.gamma.logpdf-এর মতো log রূপ সরাসরি ব্যবহার করুন, np.log(pdf) নয়।
  • সীমাবদ্ধতা সরান: k, s > ০; optimizer-কে log k আর log s দিন, তাহলে যেকোনো বাস্তব সংখ্যাই বৈধ (reparameterization). বিকল্প হলো bounds-সহ L-BFGS-B (পর্ব ১৬)।
  • ভালো শুরুর বিন্দু: method of moments: গড় আর variance মিলিয়ে k₀ = x̄²/v, s₀ = v/x̄.
  • যাচাই: res.success দেখুন, library-র fit-এর সঙ্গে মেলান (stats.gamma.fit-এ floc=0 না দিলে সে তৃতীয় একটি location parameter-ও fit করে), আর SE-র জন্য সর্বোচ্চ বিন্দুতে Hessian নিজে হিসাব করুন। BFGS-এর res.hess_inv শুধু optimizer-এর চলার পথে জমানো একটি আনুমানিক মান, আর এখানে তা log-parameter-এর জগতে।
import numpy as np
from scipy import stats, optimize
np.set_printoptions(precision=4, suppress=True)

rng = np.random.default_rng(11)            # কাল্পনিক: জেলার বাইরে ৬০টি ডেলিভারির সময় (দিন)
x = rng.gamma(shape=2.5, scale=1.2, size=60)

def nll(p, x):                             # p = (log k, log s): ধনাত্মক রাখার কৌশল
    return -stats.gamma.logpdf(x, a=np.exp(p[0]), scale=np.exp(p[1])).sum()

def fit(x):
    m, v = x.mean(), x.var()               # শুরু: method of moments
    res = optimize.minimize(nll, np.log([m * m / v, v / m]), args=(x,), method="BFGS")
    return np.exp(res.x), res

theta, res = fit(x)
print("MLE (k, scale):", theta, "| converged:", res.success, "| NLL:", round(res.fun, 4))
print("scipy gamma.fit:", np.array(stats.gamma.fit(x, floc=0))[[0, 2]])

def f(t): return -stats.gamma.logpdf(x, a=t[0], scale=t[1]).sum()
h = 1e-4 * theta; H = np.zeros((2, 2))     # (k, scale)-তে NLL-এর Hessian, central difference
for i in range(2):
    for j in range(2):
        ei, ej = np.eye(2)[i] * h[i], np.eye(2)[j] * h[j]
        H[i, j] = (f(theta + ei + ej) - f(theta + ei - ej)
                   - f(theta - ei + ej) + f(theta - ei - ej)) / (4 * h[i] * h[j])
se = np.sqrt(np.diag(np.linalg.inv(H)))
print("observed information H:\n", H)
print("SE from inverse Hessian:", se)

boot = np.array([fit(rng.choice(x, x.size))[0] for _ in range(300)])
print("SE from 300 bootstrap refits:", boot.std(axis=0, ddof=1))
print("mean delivery k*scale:", round(theta.prod(), 3), "| sample mean:", round(x.mean(), 3))

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

MLE (k, scale): [2.7463 1.1727] | converged: True | NLL: 117.0368
scipy gamma.fit: [2.7463 1.1727]
observed information H:
 [[ 26.2958  51.1627]
 [ 51.1627 119.8146]]
SE from inverse Hessian: [0.4741 0.2221]
SE from 300 bootstrap refits: [0.4577 0.1717]
mean delivery k*scale: 3.221 | sample mean: 3.221

নিজের লেখা BFGS আর SciPy-র gamma.fit চার দশমিক ঘর পর্যন্ত একই উত্তর দিয়েছে: k̂ = ২.৭৪৬৩, ŝ = ১.১৭২৭ (ডেটা বানানো হয়েছিল ২.৫ আর ১.২ দিয়ে)। শেষ লাইনে k̂·ŝ = ৩.২২১, নমুনার গড়ের হুবহু সমান, যা ŝ = x̄/k-এর সরাসরি ফল। Central difference-এ পাওয়া Hessian-এর ঘরগুলো তত্ত্বের সঙ্গেও মেলে: Hks = n/ŝ = ৬০/১.১৭২৭ ≈ ৫১.১৬, আর Hss = n·k̂/ŝ² ≈ ১১৯.৮. Inverse Hessian থেকে SE: k-এর ০.৪৭৪, scale-এর ০.২২২. লক্ষ করুন H-এর কোণাকুণি ঘর বড়: inverse নিলে k আর s-এর অনুমানের correlation প্রায় −০.৯১. অর্থাৎ k একটু বেশি হলে s একটু কম হয়, কারণ গুণফল k·s (গড়) ডেটা থেকে শক্তভাবে ঠিক হয়ে যায়, আলাদা আলাদা নয়। ৩০০টি bootstrap নমুনায় আবার fit করে পাওয়া SE: k-এর ০.৪৫৮, যা Hessian-এর সঙ্গে ভালো মেলে; scale-এর ০.১৭২, যা ২২% কম। পার্থক্যের দুটি কারণ: ৬০টি সারিতে normal-অনুমান পুরো খাটে না (scale-এর বণ্টন বাঁকা), আর ৩০০টি bootstrap নিজেও noisy. এই ধরনের মিল-অমিলই যাচাইয়ের উদ্দেশ্য; bootstrap-এর পুরো তত্ত্ব আর তার সীমা পর্ব ২১ (Bootstrap আর resampling — model-এর অনিশ্চয়তা মাপা)-এ। (একটি run, একটি কাল্পনিক ডেটা; ব্লকটি ৩০০টি ছোট optimization চালায়, তাই ব্রাউজারে এক-দুই সেকেন্ড লাগতে পারে।)

গণনার ডেটায় একই কৌশল: দিনে অর্ডারের সংখ্যার variance যদি গড়ের চেয়ে অনেক বেশি হয় (overdispersion), Poisson-এর SE অতিরিক্ত আশাবাদী হয়, কারণ Poisson ধরে নেয় variance = গড়। তখন negative binomial (গড় μ, variance μ + μ²/r) নেওয়া হয়, যার r-এরও closed form নেই; ঠিক উপরের মতো stats.nbinom.logpmf আর log-parameter দিয়ে minimize চালানো যায়। Regression-এর রূপে এটি পর্ব ২০-এর বিষয়।

৭ · MAP — prior যোগ করা MLE

Bayes-এর নিয়মে posterior ∝ likelihood × prior. MAP (maximum a posteriori) হলো posterior-এর সর্বোচ্চ বিন্দু। Log নিলে:

θ̂MAP = argmaxθ [ ℓ(θ) + log p(θ) ] = argminθ [ NLL(θ) − log p(θ) ]

অর্থাৎ MAP হলো MLE যেখানে loss-এর সঙ্গে একটি শাস্তি −log p(θ) যোগ হয়েছে। দুটি গুরুত্বপূর্ণ উদাহরণ:

Beta prior → pseudo-count

ফেরতের হারে Beta(α, β) prior: log p(θ) = (α − 1) log θ + (β − 1) log(1 − θ) + ধ্রুবক. ℓ-এর সঙ্গে যোগ করলে একই রূপ, শুধু k-এর জায়গায় k + α − 1 আর n − k-এর জায়গায় n − k + β − 1. তাই θ̂MAP = (k + α − 1)/(n + α + β − 2): prior যেন আগেই দেখা কিছু কল্পিত অর্ডার (pseudo-count). Beta হলো binomial-এর conjugate prior, তাই posterior-ও Beta থাকে।

Gaussian prior → L2 শাস্তি

Regression বা logistic regression-এর ওজনে wj ~ N(০, τ²): −log p(w) = ‖w‖²/(2τ²) + ধ্রুবক. Linear-Gaussian model-এ এটিই ridge, λ = σ²/τ², যা পর্ব ১৭-এ derive করেছেন। scikit-learn-এর LogisticRegression কমায় C·∑log loss + ½‖w‖² (intercept বাদে), অর্থাৎ default-এ এটি τ² = C = ১-এর Gaussian prior-সহ MAP, শুদ্ধ MLE নয়।

Prior কতটা টানে? Beta-র সূত্রটি একটু সাজালে θ̂MAP = w·(k/n) + (1 − w)·m, যেখানে m = (α − 1)/(α + β − 2) prior-এর mode আর w = n/(n + α + β − 2) ডেটার ওজন। নিচের stepper Beta(২, ১৮) prior নিয়ে (গড় ০.১, অর্থাৎ “আমাদের দোকানে সাধারণত দশে একটি ফেরত”) ডেটা বাড়ার সঙ্গে টানটি দেখায়।

MAP = (k + α − 1)/(n + α + β − 2), α = 2, β = 18; prior-এর mode m = 1/18 = 0.056
ডেটা
MLE
MAP
ডেটার ওজন w
  1. শুধু prior. কোনো অর্ডার নেই, তাই MLE সংজ্ঞায়িত নয়। MAP হলো prior-এর mode, ১/১৮ = ০.০৫৬ (গড় ০.১ থেকে একটু কম, কারণ Beta(২, ১৮) ডান দিকে হেলানো)।
  2. পাঁচটি অর্ডার, একটিও ফেরত নয়। MLE বলে ০: “এই পণ্য কখনো ফেরত আসবে না”. MAP বলে ০.০৪৩: ডেটা ২১.৭% ওজন পেয়েছে, prior ৭৮.৩%. পাঁচটি অর্ডারে শূন্য ফেরত ০.১ হারেও প্রায় ৫৯% সময় ঘটে, তাই ডেটা এখানে খুব কম বলে।
  3. ২০টিতে ৩টি। MLE ০.১৫, MAP ০.১০৫. ডেটা আর prior প্রায় সমান ওজন (০.৫২৬): যাচাই, ০.৫২৬ × ০.১৫ + ০.৪৭৪ × ০.০৫৬ ≈ ০.১০৫.
  4. ২০০টিতে ৩০টি। একই অনুপাত, কিন্তু এবার ডেটার ওজন ০.৯১৭; MAP ০.১৪২, MLE-এর খুব কাছে।
  5. ২০০০টিতে ৩০০টি। MAP ০.১৪৯, পার্থক্য হাজারে এক। ডেটা অনেক হলে prior প্রায় হারিয়ে যায়; বড় n-এ MLE আর MAP একই জায়গায় পৌঁছায়।
  6. সাধারণ নিয়ম। MAP হলো MLE আর prior-এর mode-এর ওজনযুক্ত গড়, যেখানে prior-এর “দাম” α + β − 2 = ১৮টি কল্পিত অর্ডারের সমান। শক্ত prior চাইলে α আর β দুটিই বড় করুন, গড় একই রেখে।

MAP-এর দুটি সীমা। প্রথম, MAP একটি বিন্দু; posterior-এর ছড়ানো বা অনিশ্চয়তা দেয় না। পুরো posterior নিয়ে কাজ পর্ব ৪৫ (Bayesian linear regression — posterior আর predictive অনিশ্চয়তা)-এর বিষয়। দ্বিতীয়, MLE-এর invariance MAP-এ নেই: θ-এর বদলে log-odds-এ একই prior-এর ঘনত্ব লিখলে (Jacobian-এর কারণে) mode সরে যায়, তাই MAP নির্ভর করে আপনি parameter কোন রূপে লিখেছেন তার ওপর। Posterior mean বা median এই দিক থেকে বেশি স্থির।

৮ · MLE কখন ভুল পথে যায় — ছোট n আর পুরো আলাদা ডেটা

MLE-এর সুন্দর গুণগুলো “বড় n”-এর প্রতিশ্রুতি। ছোট n-এ বা ডেটার বিশেষ গঠনে এটি চরম উত্তর দেয়, অর্থাৎ overfitting-এর সবচেয়ে সরল রূপ। দুটি পরিচিত ক্ষেত্র:

  • ছোট n, বিরল ঘটনা: ১০টি অর্ডারে শূন্য ফেরত হলে θ̂ = ০. পরে একটিও ফেরত এলে তার log loss −log ০ = ∞. Naive Bayes-এ না দেখা শব্দের একই সমস্যা pseudo-count দিয়ে সারানো হয়, যা Beta বা Dirichlet prior-এর MAP.
  • পুরো আলাদা করা যায় এমন ডেটা: দুই শ্রেণিকে একটি রেখা পুরোপুরি ভাগ করলে (linearly separable), logistic regression-এর ওজনের দিক ঠিক রেখে মাপ বাড়ালে প্রতিটি সারির সম্ভাবনা ১-এর আরও কাছে যায়, আর likelihood কেবল বাড়তেই থাকে। সসীম MLE নেই (perfect separation); Albert আর Anderson ১৯৮৪ সালে এই অস্তিত্বের শর্তগুলো লিখেছিলেন।

নিচের ব্লক দুটিই সংখ্যায় দেখায়: (ক) ২০,০০০টি কাল্পনিক নতুন পণ্য, প্রতিটির মাত্র ১০টি অর্ডার, আসল হার ০.০৮; MLE আর Beta(২, ১৮)-এর MAP-এর ভুল তুলনা। (খ) ২০টি পুরো আলাদা বিন্দুতে gradient ascent, শাস্তি ছাড়া (MLE) আর Gaussian prior-সহ (MAP, λ = ১), ১০ থেকে ১০,০০০ ধাপে ওজনের মাপ।

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(5)             # (ক) নতুন পণ্য: আসল ফেরতের হার 0.08, মাত্র ১০টি অর্ডার
a, b, n, true = 2, 18, 10, 0.08            # prior Beta(2, 18): গড় 0.10
k = rng.binomial(n, true, size=20000)      # ২০,০০০টি কাল্পনিক পণ্য
mle, map_ = k / n, (k + a - 1) / (n + a + b - 2)
print(f"share with k = 0 (MLE says 'never returned'): {np.mean(k == 0):.3f}")
for name, est in (("MLE", mle), ("MAP", map_)):
    print(f"{name}: bias {est.mean() - true:+.4f}  RMSE {np.sqrt(np.mean((est - true) ** 2)):.4f}")

x = np.r_[rng.normal(-2, 0.6, 10), rng.normal(2, 0.6, 10)]   # (খ) দুই দল, পুরো আলাদা
X, y = np.c_[np.ones(20), x], np.r_[np.zeros(10), np.ones(10)]
print("separable:", x[:10].max() < x[10:].min())
ts = (10, 100, 1000, 10000)

def run(lam):                              # gradient ascent: (log-lik − (λ/2)·w1²)/n
    w, keep = np.zeros(2), []
    for t in range(1, ts[-1] + 1):
        p = 1 / (1 + np.exp(-X @ w))
        w += 0.5 * (X.T @ (y - p) - lam * w * np.r_[0, 1]) / 20
        if t in ts: keep.append(w[1])
    return keep

res = {lam: run(lam) for lam in (0.0, 1.0)}
for lam, ws in res.items():
    print(f"lambda = {lam}: " + "  ".join(f"t={t}: w1={v:.2f}" for t, v in zip(ts, ws)))
plt.figure(figsize=(6, 3.4), layout="constrained")
for lam, ws in res.items():
    plt.semilogx(ts, ws, "o-", lw=2, label=f"lambda = {lam}")
plt.xlabel("gradient steps (log scale)"); plt.ylabel("slope weight w1")
plt.title("separable data: MLE weight keeps growing, MAP stops"); plt.legend(); plt.show()

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

share with k = 0 (MLE says 'never returned'): 0.435
MLE: bias +0.0002  RMSE 0.0862
MAP: bias -0.0156  RMSE 0.0345
separable: True
lambda = 0.0: t=10: w1=1.46  t=100: w1=2.66  t=1000: w1=4.08  t=10000: w1=5.65
lambda = 1.0: t=10: w1=1.31  t=100: w1=1.55  t=1000: w1=1.55  t=10000: w1=1.55

(ক) ২০,০০০ পণ্যের ৪৩.৫%-এ ১০টি অর্ডারে একটিও ফেরত আসেনি (তত্ত্বে ০.৯২১০ = ০.৪৩৪), অর্থাৎ প্রায় অর্ধেক পণ্যের জন্য MLE বলছে “কখনো ফেরত আসবে না”. MLE unbiased (bias +০.০০০২), কিন্তু তার RMSE ০.০৮৬২, আসল হারের চেয়েও বড়। MAP সামান্য নিচের দিকে biased (−০.০১৫৬; তত্ত্বে (০.৮ + ১)/২৮ − ০.০৮ = −০.০১৫৭), কিন্তু RMSE ০.০৩৪৫, আড়াই গুণ কম। অংশ ৩-এর মতোই: সামান্য bias দিয়ে অনেক variance কাটা। (খ) পুরো আলাদা ডেটায় শাস্তিহীন ওজন প্রতি দশ গুণ ধাপে মোটামুটি ১.৪–১.৬ করে বাড়ছে: ২.৬৬, ৪.০৮, ৫.৬৫. বৃদ্ধি ধীর (প্রায় log t-এর মতো), কিন্তু থামে না; যত বেশি চালাবেন, তত বড়, আর model তত বেশি আত্মবিশ্বাসী ০ বা ১ বলবে। Prior-সহ ওজন ১০০ ধাপেই ১.৫৫-এ থেমে গেছে, আর ১০,০০০ ধাপেও সেখানে: সসীম, একক উত্তর। ছবিতে নীল রেখা (MLE) log স্কেলে প্রায় সরলরেখায় উঠছে, কমলা (MAP) সমতল।

ডেস্কটপে সত্যিকারের run: একই ধরনের ২০টি পুরো আলাদা বিন্দু (seed একই, তবে প্রথমে binomial টানা হয়নি বলে সংখ্যাগুলো আলাদা) statsmodels আর scikit-learn-এ দিলে কী হয়? লেখার সময়ে Python 3.14.4, statsmodels 0.15.0 আর scikit-learn 1.9.1 দিয়ে, একটি uv venv-এ চালানো:

import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(5)
x = np.r_[rng.normal(-2, 0.6, 10), rng.normal(2, 0.6, 10)]
y = np.r_[np.zeros(10), np.ones(10)]

res = sm.Logit(y, sm.add_constant(x)).fit(disp=0)
print("statsmodels Logit params:", res.params.round(2), "bse:", res.bse.round(1))

for C in (1e10, 1.0):
    m = LogisticRegression(C=C, max_iter=10000).fit(x.reshape(-1, 1), y)
    print(f"sklearn C={C:g}: coef {m.coef_[0, 0]:.2f}, intercept {m.intercept_[0]:.2f}")
~/bazarghar-ml$ python separation.py
…/statsmodels/base/optimizer.py:536: PerfectSeparationWarning: Perfect separation or prediction detected, parameter may not be identified
  callback(newparams)
… (একই সতর্কবার্তা মোট ১৫ বার)
…/statsmodels/discrete/discrete_model.py:268: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  mlefit = super().fit(
statsmodels Logit params: [ 0.66 23.34] bse: [73615.1 74358.1]
sklearn C=1e+10: coef 7.43, intercept 0.23
sklearn C=1: coef 1.68, intercept 0.17

statsmodels ১৫ বার PerfectSeparationWarning দিয়েছে, তারপর জানিয়েছে optimization মেলেনি; ঢাল ২৩.৩৪, আর তার standard error প্রায় ৭৪,০০০. এটিই অংশ ৫-এর সূত্রের চরম রূপ: likelihood-এর চূড়া নেই, ঢালের দিকে বক্রতা প্রায় শূন্য, তাই 1/√J বিশাল। scikit-learn-এ C=1e10 (প্রায় শাস্তিহীন) ৭.৪৩ দিয়েছে কোনো সতর্কবার্তা ছাড়াই: solver-এর থামার সহনসীমা যেখানে পৌঁছেছে, সংখ্যাটি সেখানকার, “আসল” কোনো মান নয়। Default C=1 (Gaussian prior, τ² = ১) দিয়েছে ১.৬৮, একটি সসীম আর পুনরুৎপাদনযোগ্য MAP. শিক্ষা: শাস্তিহীন fit-এর বিশাল coefficient বা SE দেখলে প্রথমে separation সন্দেহ করুন।

আরও কয়েকটি জায়গায় MLE বিপদে পড়ে: Gaussian mixture-এ একটি উপাদান একটি বিন্দুর ওপর বসে σ → ০ করলে likelihood অসীম হয় (পর্ব ৩৯ (Gaussian mixture আর EM algorithm — নরম clustering)-এ সমাধান); parameter-এর সংখ্যা n-এর সঙ্গে বাড়লে MLE inconsistent হতে পারে (Neyman আর Scott-এর ১৯৪৮ সালের উদাহরণ, যেখানে variance-এর MLE কখনো আসল মানে পৌঁছায় না); আর model ভুল হলে SE-র সূত্রও ভুল হয়।

আরও গভীরে: “Likelihood” শব্দ আর maximum likelihood-কে একটি সাধারণ নীতি হিসেবে R. A. Fisher প্রতিষ্ঠা করেন, প্রধানত ১৯১২ সালের একটি প্রবন্ধে আর ১৯২২ সালের “On the mathematical foundations of theoretical statistics”-এ (Philosophical Transactions of the Royal Society A), যেখানে consistency, efficiency আর sufficiency শব্দগুলোও আসে; ধারণার কিছু পূর্বসূরি Lambert, Bernoulli আর Gauss-এর লেখায় খুঁজে পাওয়া যায়। Variance-এর নিচের সীমাটি C. R. Rao (১৯৪৫) আর Harald Cramér (১৯৪৬) আলাদাভাবে প্রকাশ করেন। Model ভুল হলে MLE KL-এ নিকটতম model-এ যায় আর সঠিক SE আসে “sandwich” সূত্র J−1KJ−1 থেকে (Huber ১৯৬৭, White ১৯৮২)। Separation-এর একটি জনপ্রিয় সমাধান Firth-এর ১৯৯৩ সালের penalized likelihood, যা আসলে Jeffreys prior-সহ MAP. পাঠ্যবই হিসেবে Casella আর Berger-এর Statistical Inference আর Larry Wasserman-এর All of Statistics.

পরীক্ষা ও ইন্টারভিউতে:

  • Poisson-এর MLE derive করুন। ℓ = ∑x log λ − nλ − C; dℓ/dλ = ∑x/λ − n = ০, তাই λ̂ = x̄; দ্বিতীয় derivative −∑x/λ² < ০.
  • Gaussian variance-এর MLE কেন biased? বিচ্যুতি মাপা হয় একই ডেটার x̄ থেকে, যা বর্গের যোগফলকে সবচেয়ে ছোট করে; E[σ̂²] = (n − 1)σ²/n.
  • MSE কমানো কোন MLE? স্থির variance-এর Gaussian noise ধরে। Log loss হলো Bernoulli-র NLL.
  • Bernoulli-র Fisher information আর SE? I1 = 1/(θ(1 − θ)), SE = √(θ̂(1 − θ̂)/n).
  • MAP আর MLE-এর সম্পর্ক? MAP = argmax ℓ(θ) + log p(θ); সমতল prior-এ দুটি সমান, Gaussian prior-এ L2 শাস্তি, বড় n-এ দুটি কাছাকাছি।

৯ · AI-এর যুগে — likelihood-এর কোড আর derivation যাচাই

AI assistant MLE-এর কোড দ্রুত লেখে, আর derivation-ও লিখে দেয় আত্মবিশ্বাসের সঙ্গে। ভুলগুলো সাধারণত চুপচাপ: চিহ্নের ভুল, ধ্রুবক বাদ পড়া, ভুল parameterization (scipy-র scale বনাম rate), বা optimizer না মিললেও ফল ছাপা। নিচের টেবিল এই বিষয়ের সাধারণ ভুলগুলো ধরে।

AI প্রায়ই যা করেকেন ভুলকীভাবে ধরবেন
np.prod(pdf) দিয়ে likelihood, তারপর logবড় n-এ underflow, ফল ০ বা −infসবসময় logpdf-এর যোগফল
scipy-র exponential বা gamma-তে rate আর scale গুলিয়ে ফেলেscale = 1/λ; ভুল দিলে MLE-এর inverse আসেনিজের version-এর docs পড়ুন; জানা উত্তরের ডেটায় যাচাই
stats.gamma.fit(x) ছাপে, floc=0 ছাড়াতিনটি parameter fit হয়, location-সহকোন parameter স্থির, স্পষ্ট লিখুন
res.hess_inv থেকে SE দেয়BFGS-এর আনুমানিক মান, অনেক সময় অন্য parameterization-এসর্বোচ্চ বিন্দুতে Hessian নিজে হিসাব; bootstrap দিয়ে মেলান
শাস্তিহীন logistic-এর বিশাল coefficient-কে “শক্তিশালী প্রভাব” বলেSeparation-এ MLE নেই; সংখ্যা solver-এর সহনসীমাSeparation পরীক্ষা করুন; শাস্তি বা prior দিন
derivation-এ ∑-এর ভেতরের n হারায় বা চিহ্ন উল্টায়দেখতে বিশ্বাসযোগ্য, কিন্তু ভুল সূত্র৩–৫টি সংখ্যার ডেটায় grid খুঁজে সূত্রের সঙ্গে মেলান

AI-কে শুধু কোড নয়, অনুমান, যাচাই আর অনিশ্চয়তাও চাইতে বলুন:

আমার কাছে বাজারঘরের ২০০টি ডেলিভারির সময় (দিনে, সব ধনাত্মক, ডান দিকে হেলানো) আছে। ১. Gamma আর log-normal দুটি model-এর log-likelihood সূত্র লেখো, আর scipy.stats-এ কোন argument shape, কোনটি scale, স্পষ্ট বলো। ২. scipy.optimize.minimize দিয়ে NLL কমানোর কোড দাও, log-parameter দিয়ে, method of moments থেকে শুরু করে; res.success না হলে থেমে যাবে। ৩. সর্বোচ্চ বিন্দুতে central difference দিয়ে Hessian বের করে standard error দাও, আর ২০০টি bootstrap দিয়ে মিলিয়ে দেখাও। ৪. stats.gamma.fit(x, floc=0)-এর সঙ্গে ফল মেলাও। ৫. দুটি model-এর মধ্যে কোনটি ভালো, held-out ডেটার গড় log-likelihood দিয়ে তুলনা করো, train-এর নয়। ৬. কোনো warning চাপা দিও না, আর তোমার কোন API আমার scipy version-এ বদলে যেতে পারে, বলো।

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

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

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

প্র ০১Fisher কেন জোর দিয়েছিলেন যে likelihood সম্ভাবনা নয়? এই পার্থক্য আজকের ML-এ কোথায় কাজে লাগে?

বিশ শতকের শুরুতে অজানা parameter নিয়ে যুক্তির প্রচলিত পথ ছিল “inverse probability”, যা Thomas Bayes আর Pierre-Simon Laplace-এর কাজ থেকে আসে: parameter-এর ওপর একটি সমান prior ধরে, Bayes-এর নিয়মে তার সম্ভাবনা হিসাব। R. A. Fisher এই সমান prior-এর ধারণায় আপত্তি তোলেন। তাঁর যুক্তি: θ-কে সমান prior দিলে আর একই প্রশ্ন θ²-এ লিখলে, θ²-এর ওপর prior আর সমান থাকে না; অর্থাৎ “কিছু না জানা” কথাটি parameterization-এর ওপর নির্ভর করে। ১৯২১–১৯২২ সালের লেখায় তিনি “likelihood” শব্দটি আলাদা করে আনেন, স্পষ্ট বলে যে এটি θ-এর ওপর কোনো সম্ভাবনা বণ্টন নয়, আর এর সর্বোচ্চ বিন্দুকে অনুমান হিসেবে নেন।

পার্থক্যের ব্যবহারিক রূপ এই পর্বেই দেখেছেন। প্রথম, L(θ)-এর θ-এর ওপর সমাকলন ১ হয় না, তাই “θ = ০.৪-এর likelihood ০.০৩৫” থেকে “θ = ০.৪ হওয়ার সম্ভাবনা” বলা যায় না। দ্বিতীয়, MLE invariance মানে (λ̂ থেকে 1/λ̂), কিন্তু MAP মানে না: ঠিক Fisher-এর আপত্তিটিই, prior-এর ঘনত্ব parameterization বদলালে বদলায়।

আজকের ML-এ পার্থক্যটি তিন জায়গায় চোখে পড়ে। (১) Model-এর “confidence” পড়া: একটি classifier-এর output হলো ডেটা দেওয়া শর্তে label-এর সম্ভাবনা, কিন্তু model-এর weight কতটা নিশ্চিত, সেটি আলাদা প্রশ্ন, যার উত্তর SE, bootstrap বা posterior থেকে আসে। (২) Model তুলনা: দুটি model-এর log-likelihood-এর পার্থক্য (likelihood ratio) তুলনার একটি মাপ, কিন্তু parameter বেশি হলে train-এর likelihood প্রায় সবসময় বাড়ে, তাই held-out likelihood বা AIC-এর মতো শাস্তি লাগে। (৩) Bayesian আর frequentist বিতর্ক: Fisher-এর পরে Neyman ও Pearson-এর ধারা আর পরে আধুনিক Bayesian-রা ভিন্ন পথে গেছেন; আজকের অনেক অনুশীলনকারী দুটিকেই হাতিয়ার হিসেবে ব্যবহার করেন। Fisher নিজে “fiducial” নামে একটি তৃতীয় পথও প্রস্তাব করেছিলেন, যা আজও বিতর্কিত আর মূলধারায় তেমন জায়গা পায়নি।

মূল উপলব্ধি: likelihood হলো ডেটার চোখে প্রতিটি θ কতটা সমর্থিত, তার আপেক্ষিক মাপ; θ-এর ওপর সম্ভাবনা চাইলে prior আনতে হবে, আর সেটি স্পষ্ট করে বলতে হবে।

প্র ০২Variance-এ n না n − 1 — ML-এর কাজে এই পার্থক্য কখন গুরুত্বপূর্ণ, আর কখন নয়?

অংশ ৩-এর run দেখিয়েছে, n = ৫-এ MLE-এর গড় ২৮.৮৪, আসল ৩৬; আর n = ১০০-এ পার্থক্য মাত্র ১%. তাই প্রথম উত্তর: বড় n-এ পার্থক্য প্রায় অর্থহীন। একটি feature-কে standardize করতে scikit-learn-এর StandardScaler n দিয়ে ভাগ করা sd ব্যবহার করে (ডকুমেন্টেশনে স্পষ্ট লেখা), আর হাজার সারিতে তাতে কোনো ব্যবহারিক তফাত হয় না।

কিন্তু কয়েকটি জায়গায় পার্থক্যটি বাস্তব। (১) ছোট নমুনার পরিসংখ্যান: পর্ব ০৪-এ পাঁচটি seed বা দশটি fold-এর ফল নিয়ে mean ± sd লিখেছেন। সেখানে n = ৫; n দিয়ে ভাগ করলে sd প্রায় ১১% কম আসে (√(৪/৫) ≈ ০.৮৯৪), যা t-test বা confidence interval-কে অতিরিক্ত আশাবাদী করে। সেখানে ddof = ১ নিয়ম। (২) Library-র মধ্যে অমিল: NumPy-র default ddof = ০, pandas-এর ১; একই ডেটার দুই রিপোর্টে আলাদা সংখ্যা দেখে অনেকে বিভ্রান্ত হন। (৩) Variance-এর ওপর নির্ভরশীল পরীক্ষা, যেমন Gaussian discriminant analysis-এ প্রতিটি শ্রেণির covariance (পর্ব ১৯), যেখানে কিছু শ্রেণির সারি কম হতে পারে।

গভীরতর প্রশ্নটি হলো “unbiased” কতটা মূল্যবান। Run-এ দেখেছেন, n = ৫-এ MLE-এর MSE ৪৭২.৮, unbiased-এর ৬৫৫.৫. আসলে n + 1 দিয়ে ভাগ করলে Gaussian ক্ষেত্রে MSE আরও কম হয়, যা পরিসংখ্যানের পাঠ্যবইয়ের একটি পরিচিত ফল। অর্থাৎ তিনটি ভাজক তিনটি আলাদা লক্ষ্যের সেরা: n − 1 bias-এর জন্য, n likelihood-এর জন্য, n + 1 বর্গ-ভুলের জন্য। কোন লক্ষ্য গুরুত্বপূর্ণ, সেটি কাজ ঠিক করে। আরেকটি সূক্ষ্মতা: σ̂² unbiased হলেও σ̂ (বর্গমূল) biased থাকে, কারণ বর্গমূল একটি non-linear function; unbiasedness রূপান্তরে টেকে না, MLE-এর invariance টেকে।

ML-এর জন্য বড় শিক্ষা: অনুমানের গুণ এক মাপে বিচার করা যায় না। Bias, variance আর তাদের যোগফল (MSE) আলাদা করে দেখুন, আর ছোট n-এ কোন ভাজক ব্যবহার করছেন, তা রিপোর্টে লিখুন।

মূল উপলব্ধি: বড় n-এ n বনাম n − 1 তুচ্ছ; ছোট n-এ (seed, fold, ছোট শ্রেণি) এটি সিদ্ধান্ত বদলাতে পারে, আর “unbiased” মানে “সবচেয়ে নির্ভুল” নয়।

প্র ০৩Model যদি ভুল হয় (যা প্রায় সবসময়), তবু MLE কী অনুমান করে, আর তার standard error কতটা বিশ্বাসযোগ্য?

পরিসংখ্যানবিদ George Box-এর একটি প্রায়ই উদ্ধৃত কথা: “সব model ভুল, কিছু model কাজের।” বাজারঘরের ডেলিভারির সময় আসলে gamma নয়; ছুটির দিন, বৃষ্টি আর কুরিয়ারের বদলে বণ্টনে কয়েকটি চূড়া থাকতে পারে। তাহলে অংশ ৬-এর k̂ আর ŝ কী মাপছে?

অংশ ৪-এর যুক্তি উত্তর দেয়: MLE KL(p ‖ qθ) কমায়, যেখানে p হলো আসল বণ্টন। Model-এর পরিবারে আসল p না থাকলেও, n বাড়লে θ̂ পৌঁছায় সেই θ*-এ, যেখানে gamma পরিবারের মধ্যে KL সবচেয়ে কম। Halbert White ১৯৮২ সালে Econometrica-তে এই “quasi-maximum likelihood” তত্ত্বটি সুসংহত রূপে লেখেন; Peter Huber ১৯৬৭ সালে এর একটি রূপ আগেই দিয়েছিলেন। একটি সুখবর: কিছু অংশ ভুল model-এও ঠিক থাকে। যেমন gamma-র ক্ষেত্রে k̂·ŝ = x̄ হুবহু, তাই গড় ডেলিভারির সময়ের অনুমান বণ্টনের আকৃতি ভুল হলেও consistent.

দুঃসংবাদ standard error-এ। অংশ ৫-এর 1/√J সূত্র ধরে নেয় যে model ঠিক; তখন information matrix-এর দুটি রূপ (score-এর variance আর NLL-এর Hessian) সমান। Model ভুল হলে তারা আলাদা, আর সঠিক covariance হয় sandwich: J−1KJ−1, যেখানে K = প্রতিটি সারির score-এর বাইরের গুণফলের যোগফল। Poisson-এ overdispersion এর পরিচিত উদাহরণ: variance গড়ের দ্বিগুণ হলে সাধারণ SE প্রায় √২ গুণ ছোট আসে। statsmodels-এর মতো library-তে “robust” বা HC covariance-এর বিকল্প এই কারণেই আছে।

ব্যবহারিক পরামর্শ: (১) model-এর ফিট দেখুন: histogram বা Q-Q plot-এর ওপর fit করা বণ্টন বসান। (২) SE দুইভাবে হিসাব করুন, Hessian আর bootstrap; অংশ ৬-এর run-এ scale-এর SE-তে দুটির পার্থক্য ছিল ২২%, যা একটি সংকেত। (৩) Held-out ডেটার log-likelihood দিয়ে বিকল্প model তুলনা করুন। (৪) কোন প্রশ্নের উত্তর চান, ভাবুন: গড় চাইলে ভুল আকৃতি তেমন ক্ষতি করে না; লেজের সম্ভাবনা (“৭ দিনের বেশি দেরির সম্ভাবনা”) চাইলে আকৃতি খুব গুরুত্বপূর্ণ।

মূল উপলব্ধি: ভুল model-এও MLE একটি নির্দিষ্ট জিনিস মাপে (KL-এ নিকটতম), কিন্তু তার সাধারণ SE ভুল হতে পারে; bootstrap বা sandwich দিয়ে যাচাই করুন, আর লেজের প্রশ্নে model-এর আকৃতি আলাদা করে পরীক্ষা করুন।

প্র ০৪Logistic regression-এ separation একটি বিরল দুর্ঘটনা, নাকি বাস্তব কাজে নিয়মিত সমস্যা? সমাধানগুলোর মধ্যে কোনটি কখন?

দুই-এক মাত্রায় পুরো separation বিরল মনে হয়। কিন্তু feature-এর সংখ্যা p বাড়লে ছবি বদলায়। Thomas Cover-এর ১৯৬৫ সালের একটি ফলাফল অনুযায়ী, সাধারণ অবস্থানে থাকা n-টি বিন্দুকে এলোমেলো label দিলেও, p মোটামুটি n/২-এর কাছাকাছি বা বেশি হলে সেগুলো linearly separable হওয়ার সম্ভাবনা অনেক বেড়ে যায়। One-hot করা অনেক category, বিরল শ্রেণি (যেমন বাজারঘরের জালিয়াতি অর্ডার), বা ছোট উপদলে আলাদা model বানালে quasi-separation (প্রায় পুরো আলাদা) প্রায়ই ঘটে। যেমন একটি বিরল জেলার সব অর্ডার ফেরত এলে সেই জেলার dummy-র coefficient অসীমের দিকে যায়।

Albert আর Anderson ১৯৮৪ সালে Biometrika-তে দেখান, complete বা quasi-complete separation থাকলে সসীম MLE নেই। সফটওয়্যার তখন যা দেয়, তা optimizer-এর থামার জায়গা: ডেস্কটপ run-এ statsmodels ঢাল ২৩.৩৪ আর SE প্রায় ৭৪,০০০ দিয়েছে, scikit-learn C = ১০১০-এ ৭.৪৩. এই সংখ্যার কোনোটিরই অর্থ নেই।

সমাধানগুলো: (১) L2 শাস্তি বা Gaussian prior: সবচেয়ে সহজ, আর scikit-learn-এর default. তবে default C = ১ ডেটার মাপ না দেখে বসানো একটি prior; ML সম্প্রদায়ে কেউ কেউ সমালোচনা করেছেন যে নতুন ব্যবহারকারী জানেনই না তাঁর “logistic regression” আসলে regularize করা। C-কে cross-validation দিয়ে বাছুন আর feature standardize করুন। (২) Firth-এর penalized likelihood (১৯৯৩): Jeffreys prior-এর সমান একটি শাস্তি, যা ছোট নমুনার bias কমায় আর separation-এও সসীম উত্তর দেয়; চিকিৎসা আর সমাজবিজ্ঞানের ছোট ডেটায় জনপ্রিয়। (৩) দুর্বল তথ্যবাহী prior: Gelman ও সহকর্মীরা ২০০৮ সালে standardized feature-এ Cauchy prior প্রস্তাব করেন, logistic regression-এর একটি “default” হিসেবে। (৪) ডেটা বা feature-এর নকশা: বিরল category একত্র করা, বা প্রশ্নটাই বদলানো।

লক্ষ করুন, অনুমানের (prediction) দিক থেকে separation সবসময় খারাপ খবর নয়; ভাগ সত্যিই পরিষ্কার হলে model ভালো ভাগ করে। সমস্যা হলো সম্ভাবনার মাপ (০ আর ১-এর অতিরিক্ত আত্মবিশ্বাস, পর্ব ২৬-এর calibration) আর coefficient-এর ব্যাখ্যা।

মূল উপলব্ধি: অনেক feature বা বিরল শ্রেণিতে separation নিয়মিত ঘটে; শাস্তিহীন fit-এর বিশাল সংখ্যা বিশ্বাস করবেন না, prior বা শাস্তি বেছে নিন আর তা CV-তে যাচাই করুন।

প্র ০৫MLE, MAP আর পুরো posterior — বাস্তব ML-এ কোনটি কখন? আর neural network training আসলে কোনটি?

তিনটি পথ একটি সিঁড়ির মতো। MLE শুধু ডেটা দেখে একটি বিন্দু দেয়। MAP prior যোগ করে একটি বিন্দু দেয়, যা আসলে শাস্তিসহ MLE. পুরো posterior একটি বণ্টন দেয়, যা দিয়ে অনিশ্চয়তা আর ভবিষ্যৎ অনুমানের পরিসর পাওয়া যায়। খরচও এই ক্রমে বাড়ে: MLE আর MAP একটি optimization, posterior সাধারণত sampling (পর্ব ৪৭, MCMC) বা approximation (পর্ব ৪৮, variational inference) চায়।

কখন কোনটি? ডেটা অনেক আর parameter তুলনায় কম হলে তিনটি প্রায় একই উত্তর দেয়; বড় n-এ prior-এর প্রভাব হারায় (stepper ৩-এ n = ২০০০-এ MAP আর MLE-এর পার্থক্য হাজারে এক)। পরিসংখ্যানের Bernstein–von Mises উপপাদ্য নিয়মিত শর্তে বলে, posterior তখন প্রায় N(θ̂, J−1), অর্থাৎ অংশ ৫-এর SE আর Bayesian পরিসর কাছাকাছি। ছোট n, বিরল ঘটনা, অনেক উপদল (প্রতিটি জেলা, প্রতিটি পণ্য) হলে MAP বা পুরো posterior স্পষ্টভাবে ভালো; hierarchical model-এ উপদলগুলো একে অপরের কাছ থেকে “ধার” করে। আর সিদ্ধান্তে অনিশ্চয়তা লাগলে (মজুত কত রাখবেন, ঝুঁকি কত) পুরো posterior বা অন্তত SE দরকার।

Neural network training-এ cross-entropy বা MSE কমানো হলো MLE, আর weight decay যোগ করলে মোটামুটি Gaussian prior-সহ MAP (Adam-এর সঙ্গে এর সূক্ষ্ম পার্থক্য পর্ব ১৪-এ দেখেছেন)। কিন্তু এই ব্যাখ্যা আংশিক: বড় network-এ optimizer প্রায়ই প্রকৃত সর্বোচ্চে পৌঁছায় না, early stopping আর data augmentation-এর মতো কৌশলের Bayesian অর্থ সরল নয়, আর likelihood বহু-চূড়ার। Guo ও সহকর্মীরা ২০১৭ সালে দেখান যে আধুনিক গভীর network প্রায়ই অতিরিক্ত আত্মবিশ্বাসী (calibrated নয়), যা আংশিকভাবে likelihood-কে train ডেটায় অতিরিক্ত বাড়ানোর ফল বলে ধারণা করা হয়। পুরো Bayesian deep learning নিয়ে গবেষণা চলছে, তবে বড় মাপে তা এখনো ব্যয়বহুল, আর কোন approximation কতটা বিশ্বাসযোগ্য তা নিয়ে মতভেদ আছে।

ব্যবহারিক নিয়ম: (১) প্রথমে MLE বা হালকা শাস্তির MAP দিয়ে শুরু করুন, শাস্তির মাত্রা CV-তে বাছুন। (২) ছোট n বা বিরল ঘটনায় prior-কে ডোমেইনের জ্ঞান দিয়ে বেছে তার যুক্তি লিখুন। (৩) অনিশ্চয়তা সিদ্ধান্তে লাগলে bootstrap (পর্ব ২১), পুরো posterior (পর্ব ৪৫), বা conformal পদ্ধতি দেখুন।

মূল উপলব্ধি: MLE, MAP আর posterior একই কাঠামোর তিনটি ধাপ; ডেটা যত কম আর সিদ্ধান্তে অনিশ্চয়তা যত গুরুত্বপূর্ণ, তত ওপরের ধাপ দরকার।

অনুশীলন

হিসাবগুলো খাতায় করুন, তারপর উত্তর মেলান। চাইলে অংশ ২ আর ৬-এর ব্লক বদলে যাচাই করুন।

  1. পূর্ণ numerical: (ক) পাঁচটি অর্ডারের মাঝের অপেক্ষা ২, ৫, ৩, ৬ আর ৪ মিনিট; model exponential(λ). λ̂, Fisher information In(λ̂) আর SE(λ̂) বের করুন, আর গড় অপেক্ষার MLE কত? (খ) ৮০টি অর্ডারে ১২টি ফেরত। θ̂, SE আর প্রায় ৯৫% Wald interval কত?

    (ক) ∑x = ২০, n = ৫. ℓ = n log λ − λ∑x, তাই λ̂ = n/∑x = ০.২৫ প্রতি মিনিট. d²ℓ/dλ² = −n/λ², তাই In(λ̂) = ৫/০.০৬২৫ = ৮০, SE = ১/√৮০ = ০.১১২. Invariance-এ গড় অপেক্ষা 1/λ-এর MLE = ১/০.২৫ = ৪ মিনিট = x̄. লক্ষ করুন, পাঁচটি মাত্র মাপে SE অনুমানের প্রায় ৪৫%. (খ) θ̂ = ১২/৮০ = ০.১৫. SE = √(০.১৫ × ০.৮৫/৮০) = √০.০০১৫৯৪ = ০.০৩৯৯. পরিসর ০.১৫ ± ১.৯৬ × ০.০৩৯৯ = ০.১৫ ± ০.০৭৮ = (০.০৭২, ০.২২৮).

  2. সমালোচনা ও নকশা: একটি AI assistant দিনে অর্ডারের সংখ্যার জন্য negative binomial-এর MLE লিখেছে এভাবে: L = np.prod(stats.nbinom.pmf(x, r, p)), তারপর minimize(lambda t: -L, ...) দুটি কাঁচা parameter (r, p) দিয়ে, কোনো bounds ছাড়া; SE নিয়েছে res.hess_inv থেকে; আর Poisson-এর সঙ্গে তুলনা করেছে train ডেটার likelihood দিয়ে, বলে “negative binomial ভালো”. কী কী সমস্যা, আর সঠিক নকশা কী?

    সমস্যা: (১) গুণফল দিয়ে likelihood: কয়েকশ দিনেই underflow, L = ০ আর optimizer কোনো দিক পায় না। (২) lambda t: -L-এ t ব্যবহারই হয়নি; L একটি স্থির সংখ্যা, তাই objective ধ্রুবক। (৩) r > ০ আর ০ < p < ১-এর সীমা নেই; optimizer অবৈধ মানে গেলে nan আসে। (৪) hess_inv BFGS-এর আনুমানিক মান, আর সীমাবদ্ধ parameterization-এ সরাসরি ব্যবহারযোগ্য নয়। (৫) Negative binomial-এ Poisson একটি সীমান্ত-ক্ষেত্র (r → ∞), তাই train likelihood প্রায় সবসময় বেশি হবে; সেটি প্রমাণ নয়। সঠিক নকশা: NLL = −∑stats.nbinom.logpmf; parameter log r আর logit p (বা গড় μ আর log r); শুরু method of moments থেকে; res.success পরীক্ষা; সর্বোচ্চ বিন্দুতে natural parameter-এ Hessian হিসাব করে SE, bootstrap দিয়ে মেলানো; তুলনা held-out দিনের গড় log-likelihood দিয়ে, সঙ্গে variance/গড় অনুপাত দেখে overdispersion আছে কি না যাচাই।

  3. আউটপুট অনুমান করুন: চালানোর আগে লিখে ফেলুন নিচের কোড কী ছাপবে।
    import numpy as np
    x = np.array([2.0, 4.0, 9.0])
    print(x.var(), x.var(ddof=1))
    print(np.prod([0.5] * 1100), np.sum(np.log([0.5] * 1100)))
    8.666666666666666 13.0
    0.0 -762.4618986159398

    গড় ৫, বিচ্যুতি −৩, −১, ৪, বর্গের যোগফল ২৬. ddof=0 (MLE) ২৬/৩ = ৮.৬৬৭, ddof=1 ২৬/২ = ১৩. দ্বিতীয় লাইনে ০.৫১১০০ = ২−১১০০, যা float64-এর সবচেয়ে ছোট ধনাত্মক মান (প্রায় ২−১০৭৪)-এর চেয়েও ছোট, তাই underflow হয়ে ঠিক ০.০. Log-এর যোগফল ১১০০ × ln ০.৫ = −৭৬২.৪৬, একটি সাধারণ সংখ্যা। (ডেস্কটপ Python 3.14.4 আর NumPy 2.5.4-এ চালানো; float64-এ ফল সব জায়গায় একই।)

  4. MAP-এর হিসাব: একটি নতুন পণ্যের ১০টি অর্ডারে একটিও ফেরত আসেনি। দোকানের অভিজ্ঞতা থেকে prior Beta(৩, ২৭). MLE, MAP, posterior-এর গড় (α + k)/(α + β + n) আর ডেটার ওজন w কত? কেন MAP আর posterior-এর গড় আলাদা?

    MLE = ০/১০ = ০. MAP = (০ + ৩ − ১)/(১০ + ৩ + ২৭ − ২) = ২/৩৮ = ০.০৫৩. Posterior Beta(৩, ৩৭), গড় ৩/৪০ = ০.০৭৫. w = ১০/৩৮ = ০.২৬৩: ডেটা এক-চতুর্থাংশের কিছু বেশি ওজন পেয়েছে, prior-এর mode ২/২৮ = ০.০৭১-এর দিকে টান বেশি; যাচাই, ০.২৬৩ × ০ + ০.৭৩৭ × ০.০৭১৪ ≈ ০.০৫৩. MAP হলো posterior-এর চূড়া (mode), আর গড় হলো ভারকেন্দ্র; ডান দিকে হেলানো Beta-তে গড় চূড়ার ডানে থাকে, তাই ০.০৭৫ > ০.০৫৩.

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

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

ক্রমClosed form নেই এমন একটি model-এর MLE আর তার standard error বের করার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. ডেটার ধরন দেখে distribution বাছা (যেমন ধনাত্মক, হেলানো সময়ের জন্য gamma)
  2. NLL লেখা: −∑ logpdf, গুণফল নয়
  3. Parameter-কে log রূপে লেখা আর method of moments থেকে শুরুর বিন্দু নেওয়া
  4. minimize চালিয়ে res.success আর library-র fit-এর সঙ্গে মিল দেখা
  5. সর্বোচ্চ বিন্দুতে NLL-এর Hessian হিসাব করে inverse থেকে standard error
  6. Bootstrap-এ আবার fit করে standard error মিলিয়ে দেখা

চার দিনে একটি জেলায় অর্ডার এসেছে ৩, ৫, ৪ আর ৮টি। Poisson model-এ দৈনিক হার λ-এর MLE কত?

  • ৪
  • ৬.৬৭
  • ৫
  • ৮

তিনটি ডেলিভারির সময় ২, ৪ আর ৯ ঘণ্টা। Gaussian model-এ σ²-এর maximum likelihood অনুমান কত?

  • ১৩
  • ৮.৬৭
  • ২৬
  • ৩.৬১

১০০টি অর্ডারে ২০টি ফেরত। Bernoulli model-এ θ̂-এর standard error (Fisher information থেকে) প্রায় কত?

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

Regression-এ বর্গ-ভুলের যোগফল কমানো কোন noise model ধরে maximum likelihood-এর সমান?

  • Laplace noise
  • Bernoulli label
  • x-ভেদে বদলানো variance-এর Gaussian noise
  • স্থির variance-এর Gaussian noise

দুই শ্রেণির training ডেটাকে একটি রেখা পুরোপুরি আলাদা করে। শাস্তি ছাড়া logistic regression-এর maximum likelihood fit-এ কী ঘটে?

  • ওজন একটি সসীম, একক মানে মেলে
  • সব ওজন শূন্য হয়ে যায়
  • ওজনের মাপ সীমাহীনভাবে বাড়তে থাকে, আর রিপোর্ট করা মান optimizer কোথায় থামল তার ওপর নির্ভর করে
  • Training accuracy ৫০%-এ নেমে যায়

ফেরতের হারে Beta(২, ২) prior, আর ৪টি অর্ডারে ৩টি ফেরত। MAP অনুমান কত?

  • ০.৭৫
  • ০.৬৬৭
  • ০.৬২৫
  • ০.৫

শব্দকোষ

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

মনে রাখুন

  1. Likelihood: L(θ) = ∏ p(xi | θ), θ-এর function, θ-এর ওপর সম্ভাবনা নয়; কাজ হয় ℓ = ∑ log p দিয়ে, underflow এড়াতে আর derivative সহজ করতে।
  2. Closed form: Bernoulli k/n, Poisson x̄, exponential 1/x̄, Gaussian μ̂ = x̄ আর σ̂² = (1/n)∑(x − x̄)², যার গড় (n − 1)σ²/n.
  3. Loss-এর উৎস: MLE = cross-entropy বা KL কমানো; Gaussian noise → squared loss, Laplace → absolute, Bernoulli → log loss.
  4. Numerical MLE আর SE: log-parameter-এ NLL minimize; SE = √diag(J−1), J = সর্বোচ্চ বিন্দুতে NLL-এর Hessian; bootstrap দিয়ে যাচাই। Information n-এর সঙ্গে বাড়ে, SE ∝ 1/√n.
  5. MAP: argmax ℓ + log p(θ); Beta prior → (k + α − 1)/(n + α + β − 2), Gaussian prior → L2. ছোট n বা separation-এ MLE চরম, MAP সসীম।

পরের পর্বে: এক মাত্রার Gaussian-এর MLE এখানে দেখলেন। পর্ব ১৯ (Multivariate Gaussian — covariance, Mahalanobis দূরত্ব আর শর্তসাপেক্ষ বণ্টন) একে বহু মাত্রায় নেয়: covariance matrix-এর আকৃতি, অস্বাভাবিক বিন্দু চেনার দূরত্ব, আর একটি চলক জানলে বাকিগুলোর বণ্টন।

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

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