সমাধান — অধ্যায় ৫.১ · Simple & Multiple Linear Regression¶
অধ্যায়
part-5-modeling/05-01-linear-regression.md-এর section ৭-এর সব অনুশীলনীর পূর্ণ সমাধান। সব সংখ্যাগত ফল NumPy দিয়ে যাচাই করা হয়েছে। চলমান উদাহরণ — TINY: \((1,2),(2,3),(3,5),(4,4),(5,6)\); FULL: \(\text{price}\sim\text{area}+\text{age}+\text{rooms}\), true \(\beta=[25,\,0.45,\,-0.8,\,6]\), seeddefault_rng(20260619), noise \(\sigma=15\), predictor-রা পরস্পর-স্বাধীন।
ক · ধারণাগত (conceptual)¶
প্রশ্ন ১ (★) — coefficient interpretation¶
মডেল \(\widehat{\text{price}} = 25 + 0.45\cdot\text{area}\)।
(ক) Intercept \(25\): এটি \(\text{area}=0\)-এ মডেলের ভবিষ্যদ্বাণী — অর্থাৎ "শূন্য বর্গমিটার আয়তনের" একটি কাল্পনিক বাড়ির পূর্বাভাসিত দাম \(25\) লাখ। বাস্তবে \(\text{area}=0\) অর্থহীন, তাই intercept-এর এখানে আক্ষরিক অর্থ নেই — এটি কেবল রেখাটিকে সঠিক উচ্চতায় বসায় (গাণিতিক anchor)। data-র পরিসরের বাইরে গিয়ে intercept-কে ব্যাখ্যা করা extrapolation, যা বিপজ্জনক।
(খ) Slope \(0.45\): area এক বর্গমিটার বাড়লে পূর্বাভাসিত দাম গড়ে \(0.45\) লাখ বাড়ে। এটিই রেখার ঢাল — predictor-এর এক-একক পরিবর্তনে \(\hat y\)-এর গড় পরিবর্তন।
(গ) Causal নয়। "area বাড়লে price ঠিক \(0.45\) বাড়বে" — এটি একটি causal শোনালেও regression তা প্রমাণ করে না। regression কেবল observed data-তে area ও price-এর association ধরে (১.৪-এর "correlation ≠ causation")। হয়তো বড় বাড়ি ভালো এলাকায় থাকে (confounder = location), আর সেই এলাকাই দাম বাড়ায়। সত্যিকারের causal দাবি করতে হলে randomized/controlled পরিস্থিতি বা causal inference দরকার — নিছক fitted slope যথেষ্ট নয়।
প্রশ্ন ২ (★) — \(R^2\) ব্যাখ্যা¶
- (ক) ভুল। \(R^2\) "\(81\%\) সময় সঠিক" নয় — regression সংখ্যাগত ভবিষ্যদ্বাণী করে, "সঠিক/ভুল" দ্বিমিক ফল নয়। এটি একটি সাধারণ ভ্রান্তি।
- (খ) সঠিক। \(R^2 = 1 - \text{SSE}/\text{SST}\) মানে \(y\)-এর মোট variation (SST)-এর \(81\%\) মডেল (fitted রেখা) ব্যাখ্যা করেছে, বাকি \(19\%\) residual-এ রয়ে গেছে। এটিই সঠিক সংজ্ঞা।
- (গ) প্রায় — কিন্তু সাবধান। simple regression-এ \(R^2 = r^2\), তাই \(r = \pm\sqrt{0.81} = \pm 0.9\), \(0.81\) নয়। তাই বাক্যটি যেমন লেখা তেমন ভুল (correlation \(0.9\), \(0.81\) নয়); চিহ্ন slope থেকে আসে।
প্রশ্ন ৩ (★★) — "holding others constant"¶
multiple regression-এ একটি coefficient হলো partial effect — বাকি সব predictor স্থির রেখে শুধু ওই একটির এক-একক পরিবর্তনের প্রভাব। তাই \(\hat\beta_{\text{age}} \approx -0.76\)-এর অর্থ: area ও rooms একই রেখে বয়স ১ বছর বাড়লে দাম গড়ে \(0.76\) কমে।
simple regression \(\text{price}\sim\text{age}\) (একা) চালালে coefficient একই থাকার নিশ্চয়তা নেই। কারণ: যদি age অন্য predictor-দের (যেমন area) সাথে correlated হয় — ধরুন পুরোনো বাড়িগুলো একটু বড় হয় — তবে simple regression-এ age-এর coefficient সেই area-এর প্রভাবও কিছুটা "শুষে নেয়" (confounding via correlated predictors)। multiple regression area-কে আলাদা ধরে বলে age-এর coefficient হয় বিশুদ্ধ partial effect। predictor-রা পরস্পর uncorrelated (orthogonal) হলেই কেবল marginal ও partial effect সমান হয়। (FULL data-তে predictor-রা স্বাধীনভাবে তৈরি, তাই সেখানে পার্থক্য ছোট — কিন্তু নীতিগতভাবে এটাই multiple regression-এর শক্তি।)
প্রশ্ন ৪ (★★) — heteroscedasticity-র প্রভাব¶
(ক) \(\hat\beta\) biased হয় না। OLS estimate-এর নিরপেক্ষতা (unbiasedness) কেবল linearity + zero-mean error-এর উপর নির্ভর করে — equal variance লাগে না। error-variance \(x\)-এর সাথে বাড়লেও \(\mathbb E[\hat\beta] = \beta\) অটুট। (§ কোডে যাচাই: heteroscedastic data-তেও \(\hat\beta \approx\) true।)
(খ) সমস্যা standard error / CI-তে। Gauss–Markov-এর "equal variance" শর্ত ভাঙলে OLS আর BLUE থাকে না (সবচেয়ে কম-variance থাকে না), এবং — সবচেয়ে গুরুত্বপূর্ণ — coefficient-গুলোর standard error-এর সূত্র ভুল হয়ে যায়। ফলে \(t\)-test, \(p\)-value, confidence interval সব বিশ্বাসযোগ্যতা হারায় (সাধারণত SE কম দেখায়, তাই আমরা অতিরিক্ত আত্মবিশ্বাসী হই)। point estimate ঠিক, কিন্তু তার উপর অনিশ্চয়তার মাপ ভুল — এই সূক্ষ্ম পার্থক্যই ৫.২-এর diagnostics-এর কেন্দ্রীয় বিষয় (robust SE, weighted least squares সমাধান)।
প্রশ্ন ৫ (★★) — normal equation কখন অনন্য সমাধান দেয় না¶
দাবিটি মিথ্যা হয় যখন \(X^\top X\) singular (non-invertible), অর্থাৎ \(X\)-এর column-গুলো linearly independent নয় — perfect multicollinearity।
Concrete উদাহরণ: ধরুন area দুটো এককে রাখলাম — area_sqm (বর্গমিটার) ও area_sqft (বর্গফুট)। এরা একটির ধ্রুবক গুণিতক (\(\text{sqft} = 10.76\times\text{sqm}\)), তাই দুই column linearly dependent। তখন \(X\)-এর rank পূর্ণ নয়, \(X^\top X\)-এর determinant \(0\), inverse নেই।
কারণ (বীজগাণিতিক): \((X^\top X)^{-1}\) থাকার শর্তই হলো \(X\) full column-rank — অর্থাৎ column-গুলো স্বাধীন (০.৫-এর rank ধারণা)। জ্যামিতিক: column-রা স্বাধীন না হলে অসীম সংখ্যক \(\hat\beta\) একই projection \(\hat y\) দেয় — কোনটিকে "the" সমাধান বলব, তা নির্ধারিত নয়। (সমাধান: একটি অপ্রয়োজনীয় column বাদ দেওয়া, বা regularization — পরে।)
খ · গণনামূলক (computational)¶
প্রশ্ন ৬ (★) — TINY-তে হাতে slope ও intercept¶
\(x = (1,2,3,4,5),\ y = (2,3,5,4,6),\ n=5\)। \(\bar x = \frac{1+2+3+4+5}{5} = 3\), \(\bar y = \frac{2+3+5+4+6}{5} = 4\)।
| \(x_i\) | \(y_i\) | \(x_i-\bar x\) | \(y_i-\bar y\) | গুণফল | \((x_i-\bar x)^2\) |
|---|---|---|---|---|---|
| 1 | 2 | \(-2\) | \(-2\) | \(4\) | \(4\) |
| 2 | 3 | \(-1\) | \(-1\) | \(1\) | \(1\) |
| 3 | 5 | \(0\) | \(1\) | \(0\) | \(0\) |
| 4 | 4 | \(1\) | \(0\) | \(0\) | \(1\) |
| 5 | 6 | \(2\) | \(2\) | \(4\) | \(4\) |
| যোগ | \(\mathbf{S_{xy}=9}\) | \(\mathbf{S_{xx}=10}\) |
অর্থাৎ fitted রেখা \(\boxed{\hat y = 1.3 + 0.9\,x}\)।
প্রশ্ন ৭ (★★) — TINY-তে হাতে \(R^2\)¶
(ক) fitted value ও residual (\(\hat y_i = 1.3 + 0.9x_i\)):
| \(x_i\) | \(y_i\) | \(\hat y_i\) | \(\hat\varepsilon_i = y_i-\hat y_i\) | \(\hat\varepsilon_i^2\) | \((y_i-\bar y)^2\) |
|---|---|---|---|---|---|
| 1 | 2 | \(2.2\) | \(-0.2\) | \(0.04\) | \(4\) |
| 2 | 3 | \(3.1\) | \(-0.1\) | \(0.01\) | \(1\) |
| 3 | 5 | \(4.0\) | \(1.0\) | \(1.00\) | \(1\) |
| 4 | 4 | \(4.9\) | \(-0.9\) | \(0.81\) | \(0\) |
| 5 | 6 | \(5.8\) | \(0.2\) | \(0.04\) | \(4\) |
| যোগ | \(\mathbf{0.0}\) | \(\mathbf{SSE=1.9}\) | \(\mathbf{SST=10}\) |
(খ) \(\text{SSE} = 0.04+0.01+1.00+0.81+0.04 = 1.9\); \(\text{SST} = \sum(y_i-\bar y)^2 = 10\)।
(গ) \(\displaystyle R^2 = 1 - \frac{\text{SSE}}{\text{SST}} = 1 - \frac{1.9}{10} = 0.81\)।
(ঘ) residual-এর যোগফল \(-0.2 - 0.1 + 1.0 - 0.9 + 0.2 = 0.0\) — ঠিক \(0\), যা intercept থাকার সরাসরি ফল (প্রশ্ন ১১গ দ্রষ্টব্য)।
লক্ষ করুন \(R^2 = 0.81 = (0.9)^2 = r^2\) — কারণ এখানে Pearson \(r = S_{xy}/\sqrt{S_{xx}S_{yy}} = 9/\sqrt{10\cdot10} = 0.9\) (১.৪-এর সংযোগ)। NumPy যাচাই: \(R^2 = 0.81\) হুবহু।
প্রশ্ন ৮ (★★) — TINY-তে matrix form¶
\(X = \begin{bmatrix}1&1\\1&2\\1&3\\1&4\\1&5\end{bmatrix}\), \(y = (2,3,5,4,6)^\top\)।
(ক) $$ X^\top X = \begin{bmatrix} n & \sum x_i \ \sum x_i & \sum x_i^2 \end{bmatrix} = \begin{bmatrix} 5 & 15 \ 15 & 55 \end{bmatrix},\qquad X^\top y = \begin{bmatrix} \sum y_i \ \sum x_i y_i \end{bmatrix} = \begin{bmatrix} 20 \ 69 \end{bmatrix}. $$ (\(\sum x_i = 15,\ \sum x_i^2 = 1+4+9+16+25 = 55,\ \sum y_i = 20,\ \sum x_i y_i = 2+6+15+16+30 = 69\)।)
(খ) \(\det(X^\top X) = 5\cdot 55 - 15\cdot 15 = 275 - 225 = 50\)। \(2\times2\) inverse সূত্রে: $$ (X^\top X)^{-1} = \frac{1}{50}\begin{bmatrix} 55 & -15 \ -15 & 5 \end{bmatrix} = \begin{bmatrix} 1.1 & -0.3 \ -0.3 & 0.1 \end{bmatrix}. $$
(গ) $$ \hat\beta = (X^\top X)^{-1}X^\top y = \begin{bmatrix} 1.1 & -0.3 \ -0.3 & 0.1 \end{bmatrix}\begin{bmatrix} 20 \ 69 \end{bmatrix} = \begin{bmatrix} 1.1\cdot20 - 0.3\cdot69 \ -0.3\cdot20 + 0.1\cdot69 \end{bmatrix} = \begin{bmatrix} 22 - 20.7 \ -6 + 6.9 \end{bmatrix} = \begin{bmatrix} 1.3 \ 0.9 \end{bmatrix}. $$ হুবহু প্রশ্ন ৬-এর \((\hat\beta_0, \hat\beta_1) = (1.3, 0.9)\) — matrix ও scalar পদ্ধতি একই উত্তর দেয় (যেমনটা হওয়ার কথা)। \(\blacksquare\)
প্রশ্ন ৯ (★★) — \(R^2\) ও adjusted \(R^2\)¶
\(\text{SST}=4000,\ \text{SSE}=640,\ n=200,\ p=4\)।
(ক) \(\displaystyle R^2 = 1 - \frac{640}{4000} = 1 - 0.16 = 0.84\)।
(খ) \(\displaystyle R^2_{\text{adj}} = 1 - \frac{\text{SSE}/(n-p)}{\text{SST}/(n-1)} = 1 - \frac{640/196}{4000/199} = 1 - \frac{3.2653}{20.1005} = 1 - 0.16245 = 0.8376\)।
(গ) adjusted \(R^2\) (\(0.8376\)) সাধারণ \(R^2\) (\(0.84\))-এর চেয়ে সামান্য কম, কারণ এটি predictor-সংখ্যার জন্য "জরিমানা" করে — degrees of freedom \(n-p\) (এখানে \(196\)) ভাগে আসে, তাই অপ্রয়োজনীয় predictor যোগ করে \(R^2\) ফোলানো যায় না।
গ · প্রমাণভিত্তিক (proof-based)¶
প্রশ্ন ১০ (★★) — normal equation calculus দিয়ে¶
\(S(\beta_0,\beta_1) = \sum_{i=1}^n (y_i - \beta_0 - \beta_1 x_i)^2\)।
\(\beta_0\)-এর সাপেক্ষে partial derivative: $$ \frac{\partial S}{\partial \beta_0} = \sum_i 2(y_i - \beta_0 - \beta_1 x_i)(-1) = -2\sum_i (y_i - \beta_0 - \beta_1 x_i) = 0. $$ ভাগ করে: \(\sum_i y_i - n\beta_0 - \beta_1\sum_i x_i = 0\), অর্থাৎ $$ \sum_i y_i = n\beta_0 + \beta_1 \sum_i x_i. \tag{Normal eqn 1} $$ \(n\) দিয়ে ভাগ করলে \(\bar y = \beta_0 + \beta_1\bar x\), তাই সরাসরি \(\boxed{\hat\beta_0 = \bar y - \hat\beta_1\bar x}\)।
\(\beta_1\)-এর সাপেক্ষে: $$ \frac{\partial S}{\partial \beta_1} = \sum_i 2(y_i - \beta_0 - \beta_1 x_i)(-x_i) = -2\sum_i x_i(y_i - \beta_0 - \beta_1 x_i) = 0, $$ $$ \Rightarrow \sum_i x_i y_i = \beta_0\sum_i x_i + \beta_1\sum_i x_i^2. \tag{Normal eqn 2} $$ এখন (1) থেকে \(\beta_0 = \bar y - \beta_1\bar x\) বসাই (2)-এ: $$ \sum_i x_i y_i = (\bar y - \beta_1\bar x)\sum_i x_i + \beta_1\sum_i x_i^2 = \bar y\sum_i x_i + \beta_1\Big(\sum_i x_i^2 - \bar x\sum_i x_i\Big). $$ \(\sum_i x_i = n\bar x\) ব্যবহার করে গুছিয়ে: $$ \sum_i x_i y_i - n\bar x\,\bar y = \beta_1\Big(\sum_i x_i^2 - n\bar x^2\Big) \;\Longrightarrow\; \hat\beta_1 = \frac{\sum_i x_i y_i - n\bar x\bar y}{\sum_i x_i^2 - n\bar x^2} = \frac{S_{xy}}{S_{xx}}. $$ (শেষ ধাপে পরিচিত পরিচয়: \(\sum(x_i-\bar x)(y_i-\bar y) = \sum x_i y_i - n\bar x\bar y\) এবং \(\sum(x_i-\bar x)^2 = \sum x_i^2 - n\bar x^2\)।) \(\blacksquare\)
প্রশ্ন ১১ (★★★) — matrix normal equation ও orthogonality¶
(ক) \(S(\beta) = (y-X\beta)^\top(y-X\beta) = y^\top y - 2\beta^\top X^\top y + \beta^\top X^\top X\beta\) (যেহেতু \(\beta^\top X^\top y\) একটি scalar, তার transpose-এর সমান)। gradient (০.৫-এর matrix calculus): $$ \nabla_\beta S = -2X^\top y + 2X^\top X\beta. $$ \(\nabla_\beta S = \mathbf 0\) বসিয়ে: \(X^\top X\beta = X^\top y\) — এটিই normal equation। \(X\) full column-rank হলে \(X^\top X\) invertible, তাই $$ \hat\beta = (X^\top X)^{-1}X^\top y. \qquad\blacksquare $$ (\(S\) একটি convex quadratic — \(X^\top X\) positive-semidefinite — তাই এই critical point সত্যিই global minimum।)
(খ) residual \(\hat\varepsilon = y - X\hat\beta\)। তাহলে $$ X^\top\hat\varepsilon = X^\top(y - X\hat\beta) = X^\top y - X^\top X\hat\beta = X^\top y - X^\top y = \mathbf 0, $$ কারণ normal equation থেকেই \(X^\top X\hat\beta = X^\top y\)। অর্থাৎ residual vector প্রতিটি predictor column-এর সাথে orthogonal। \(\blacksquare\)
(গ) \(X\)-এ intercept column \(= \mathbf 1 = (1,1,\dots,1)^\top\)। এই column-এর সাথে orthogonality মানে \(\mathbf 1^\top\hat\varepsilon = 0\), অর্থাৎ \(\sum_i\hat\varepsilon_i = 0\)। তাই intercept থাকলে residual-এর যোগফল সবসময় ঠিক শূন্য (প্রশ্ন ৭-এ TINY data-তে দেখা গেছে)। জ্যামিতিক ছবি: \(\hat y = X\hat\beta\) হলো \(y\)-এর column space \(\text{col}(X)\)-এ orthogonal projection; residual সেই subspace-এর লম্ব, তাই subspace-এর প্রতিটি দিকের (column-এর) সাথে dot product শূন্য।
প্রশ্ন ১২ (★★★) — MLE = OLS (Gaussian error-এ)¶
ধরি \(y_i \sim \mathcal N(x_i^\top\beta,\ \sigma^2)\) স্বাধীনভাবে। একটি observation-এর density: $$ f(y_i;\beta,\sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2}}\exp!\Big(-\frac{(y_i - x_i^\top\beta)^2}{2\sigma^2}\Big). $$
(ক) স্বাধীনতার কারণে likelihood \(= \prod_i f(y_i)\), তাই log-likelihood (৪.৩-এর পদ্ধতি): $$ \ell(\beta,\sigma^2) = \sum_{i=1}^n \ln f(y_i;\beta,\sigma^2) = -\frac n2\ln(2\pi\sigma^2) - \frac{1}{2\sigma^2}\sum_{i=1}^n (y_i - x_i^\top\beta)^2 . $$
(খ) \(\beta\) কেবল শেষ পদে আছে: \(-\frac{1}{2\sigma^2}\sum_i (y_i - x_i^\top\beta)^2\)। প্রথম পদ \(\beta\)-নিরপেক্ষ ধ্রুবক। যেহেতু \(\frac{1}{2\sigma^2} > 0\) এবং সামনে ঋণাত্মক চিহ্ন, \(\ell\)-কে \(\beta\)-র সাপেক্ষে maximize করা মানে \(\sum_i (y_i - x_i^\top\beta)^2\)-কে minimize করা — যা ঠিক OLS-এর objective। তাই $$ \hat\beta_{\text{MLE}} = \arg\max_\beta \ell(\beta,\sigma^2) = \arg\min_\beta \sum_i (y_i - x_i^\top\beta)^2 = \hat\beta_{\text{OLS}} = (X^\top X)^{-1}X^\top y. \qquad\blacksquare $$ অর্থাৎ "least squares কেন?" — এর একটি গভীর উত্তর: Gaussian error ধরে নিলে OLS-ই maximum likelihood estimate। (এটি ৪.৩-এর MLE আর এই অধ্যায়ের OLS-এর মধ্যে সেতু।)
ঘ · কোডিং (Python)¶
প্রশ্ন ১৩ (★★) — from-scratch OLS¶
import numpy as np
def ols_fit(X, y):
"""Normal equation দিয়ে OLS: beta = (X^T X)^{-1} X^T y.
solve ব্যবহার করি — explicit inverse-এর চেয়ে দ্রুত ও সংখ্যাগতভাবে স্থিতিশীল।"""
X = np.asarray(X, float); y = np.asarray(y, float)
return np.linalg.solve(X.T @ X, X.T @ y)
# TINY dataset
x = np.array([1., 2, 3, 4, 5])
y = np.array([2., 3, 5, 4, 6])
X = np.column_stack([np.ones(len(x)), x]) # intercept column যোগ
beta = ols_fit(X, y)
print("beta_hat =", np.round(beta, 4)) # [1.3 0.9]
# np.polyfit-এর সাথে মিলিয়ে দেখা (polyfit slope আগে, intercept পরে দেয়)
slope, intercept = np.polyfit(x, y, 1)
print("polyfit (intercept, slope) =", round(intercept, 4), round(slope, 4)) # 1.3 0.9
print("match?", np.allclose(beta, [intercept, slope])) # True
আউটপুট: beta_hat = [1.3 0.9], polyfit-ও (1.3, 0.9) — হুবহু মেলে। np.linalg.solve ব্যবহার করা হলো কারণ \((X^\top X)^{-1}\) স্পষ্ট গণনা করা ব্যয়বহুল ও সংখ্যাগতভাবে কম স্থিতিশীল (বিশেষত ill-conditioned \(X^\top X\)-এ); solve সরাসরি linear system সমাধান করে — production কোডে এটাই প্রমিত অভ্যাস।
প্রশ্ন ১৪ (★★★) — FULL dataset সিমুলেট ও residual diagnostics¶
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def ols_fit(X, y):
return np.linalg.solve(X.T @ X, X.T @ y)
# ---------- (ক) data simulation (seeded; অধ্যায়ের canonical generator) ----------
rng = np.random.default_rng(20260619)
n = 200
area = rng.uniform(50, 200, n) # বর্গমিটার
age = rng.uniform(0, 40, n) # বছর
rooms = rng.integers(1, 9, n) # 1..8 কামরা, area-নিরপেক্ষ
true_beta = np.array([25, 0.45, -0.8, 6.0]) # [intercept, area, age, rooms]
X = np.column_stack([np.ones(n), area, age, rooms])
price = X @ true_beta + rng.normal(0, 15.0, n) # error ~ N(0, 15^2)
# ---------- (খ) fit ও true-র সাথে তুলনা ----------
beta_hat = ols_fit(X, price)
print("true beta =", true_beta)
print("OLS beta =", np.round(beta_hat, 4))
# -> [22.021 0.46 -0.7679 6.4958] : true-র কাছাকাছি, হুবহু নয় (সসীম n + noise)
# lstsq-এর সাথে মিল (sanity)
beta_ls, *_ = np.linalg.lstsq(X, price, rcond=None)
print("matches lstsq?", np.allclose(beta_hat, beta_ls)) # True
# ---------- (গ) residual diagnostics ----------
yhat = X @ beta_hat
resid = price - yhat
print("sum residuals ~ 0 :", np.isclose(resid.sum(), 0)) # True (intercept-এর ফল)
for j, name in enumerate(["area", "age", "rooms"], start=1):
c = np.corrcoef(resid, X[:, j])[0, 1]
print(f"corr(resid, {name}) = {c:.2e}") # সব ~1e-14 -> orthogonal (গণনাগত শূন্য)
# residual vs fitted plot — প্যাটার্ন আছে কি?
fig, ax = plt.subplots(figsize=(7, 4.5))
ax.scatter(yhat, resid, s=12, alpha=0.5, color="#2b6cb0")
ax.axhline(0, color="red", lw=1, ls="--")
ax.set_xlabel("fitted value (y-hat)")
ax.set_ylabel("residual (y - y-hat)")
ax.set_title("Residuals vs Fitted (no funnel / curve => LINE looks OK)")
fig.tight_layout()
fig.savefig("residuals_vs_fitted.png", dpi=150)
# ---------- (ঘ) R^2 ----------
SSE = resid @ resid
SST = np.sum((price - price.mean())**2)
R2 = 1 - SSE / SST
print(f"R^2 = {R2:.4f}") # ~0.7562
আউটপুট (সংক্ষেপে):
true beta = [25. 0.45 -0.8 6. ]
OLS beta = [22.021 0.46 -0.7679 6.4958]
matches lstsq? True
sum residuals ~ 0 : True
corr(resid, area) = 3.74e-16
corr(resid, age) = 1.11e-14
corr(resid, rooms) = 5.63e-15
R^2 = 0.7562
ব্যাখ্যা: (খ) \(\hat\beta \approx [22.0,\,0.46,\,-0.77,\,6.50]\) — true \([25,\,0.45,\,-0.8,\,6]\)-এর কাছাকাছি কিন্তু হুবহু নয়, কারণ মাত্র \(n=200\) observation ও \(\sigma=15\) noise; predictor-রা পরস্পর-স্বাধীন বলে চারটি সহগই পরিষ্কারভাবে recover হয়েছে, আর \(n\) বাড়ালে estimate true-র দিকে আরও গড়িয়ে যাবে (consistency, ৪.৩-এর প্রসঙ্গ)। (গ) residual diagnostics: যোগফল ঠিক \(0\) (intercept-এর গাণিতিক ফল), আর প্রতিটি predictor-এর সাথে residual-এর correlation \(\sim 10^{-14}\) — অর্থাৎ গণনাগতভাবে শূন্য (orthogonal), যা প্রশ্ন ১১খ-এর \(X^\top\hat\varepsilon=\mathbf 0\)-এর সরাসরি প্রমাণ। residual-vs-fitted plot-এ কোনো funnel (heteroscedasticity-র লক্ষণ) বা বাঁক (nonlinearity-র লক্ষণ) নেই — তাই LINE অনুমান এখানে যুক্তিসঙ্গত (data ঠিক ওই মডেল থেকেই তৈরি)।