Skip to content

সমাধান — অধ্যায় ৮.১ · End-to-End Data Analysis Project

অধ্যায় ফাইল: part-8-capstone/08-01-end-to-end-project.md (§৭ অনুশীলনী)। চলমান dataset — seed-সূচক 20260619: load_breast_cancer() (sklearn, offline; \(569\times30\); target 0=malignant, 1=benign), stratified \(70/30\) split (\(398\) train, \(171\) test)। মূল notation: logit \(\log\frac{p}{1-p}=\beta_0+\sum_j\beta_j x_j\), odds ratio \(e^{\beta_j}\), VIF\(_j=1/(1-R_j^2)\), AUC, stratified \(K\)-fold CV, sensitivity/specificity। canonical সংখ্যা। class balance: malignant \(212\) (\(0.373\)), benign \(357\) (\(0.627\))। top separators (\lvert mean gap\rvert/sd): worst concave points \(1.640\), worst perimeter \(1.618\), mean concave points \(1.605\)। VIF: mean perimeter \(934.95\), mean radius \(891.13\), mean area \(52.68\)logistic (L2, full \(30\)): test acc \(0.982\), AUC \(0.997\); random forest (\(400\)): test acc \(0.971\), AUC \(0.996\), OOB \(0.965\)। statsmodels Logit (\(7\) decorrelated feats, pseudo-\(R^2\) \(0.866\)): worst radius OR \(0.002\) \([0.000,0.018]\) \(p=2.24\text{e-}07\) (একমাত্র significant); worst texture \(0.237\); worst concave points \(0.257\); mean smoothness \(0.397\); \(1/7\) significant। CV AUC: logistic \(0.993\pm0.008\), RF \(0.989\pm0.007\)। confusion (logistic test, thr \(0.5\)): TN \(63\), FP \(1\), FN \(2\), TP \(105\); sensitivity \(0.981\), specificity \(0.984\)KEY CAVEAT: full \(30\)-feature unpenalized MLE diverges (perfect/quasi-complete separation)। §ঘ-এর runnable script (seed 20260619) উপরের সংখ্যাগুলো পুনরুৎপাদন করে।


ক · ধারণাগত (conceptual)

সমাধান ১ (★)

(ক) সাত-ধাপের pipeline। একটা end-to-end বিশ্লেষণের canonical ধারা: (১) প্রশ্ন-নির্ধারণ (কী predict করছি, কোন error বেশি ব্যয়বহুল), (২) data লোড ও যাচাই (shape, target, class balance), (৩) EDA (distribution, separating feature, correlation structure), (৪) preprocessing (split → standardize → collinearity যাচাই), (৫) modelling (একাধিক model fit), (৬) inference ও uncertainty (coefficient/odds ratio, CI, importance), (৭) validation ও reporting (cross-validation, calibration, model card)।

(খ) প্রতিটি ধাপ কেন লাগে। প্রশ্ন আগে না ঠলে ভুল metric optimize হয়; EDA ছাড়া data-র গঠন (imbalance, collinearity) অজানা থাকে, ফলে model অন্ধভাবে ভুল করে; split আগে না করলে leakage (test-তথ্য train-এ ঢুকে যায়) এবং accuracy কৃত্রিমভাবে বাড়ে; validation ছাড়া একটা lucky test-split-এর সংখ্যা generalization বলে ভুল ধরা হয়। প্রতিটি ধাপ পরের ধাপের ভিত্তি — তাই ক্রম গুরুত্বপূর্ণ।

(গ) কেন এই ক্রম, উল্টানো যায় না। standardization অবশ্যই split-এর পরে (কেবল train-এর mean/sd দিয়ে), নইলে test-এর তথ্য scaler-এ leak করে; VIF/EDA train-এ; validation সবার শেষে যাতে model-choice-ও যাচাই হয়। একটা ধাপ এড়ালে বা উল্টালে হয় leakage, নয় ভুল-নির্ধারিত সমস্যা — তাই pipeline একটা নির্দেশিত শৃঙ্খল (directed chain)

সমাধান ২ (★)

(ক) প্রশ্ন-নির্ধারণ (question framing)। সমস্যাটা binary classification: tumor-এর \(30\)টি সংখ্যাগত feature থেকে malignant (0) বনাম benign (1) ভবিষ্যদ্বাণী। প্রশ্নটা কেবল "accuracy কত" নয় — চিকিৎসা-প্রসঙ্গে আসল প্রশ্ন "কত malignant আমরা ধরতে পারছি" (recall-on-malignant)।

(খ) error-এর অসম মূল্য (cost asymmetry)। এখানে দুই ধরনের ভুল সমান নয়। একটা malignant tumor-কে benign বলা (target-এ positive=benign ধরলে false negative-এর mirror, বাস্তবে সবচেয়ে বিপজ্জনক ভুল) মানে রোগীকে চিকিৎসা ছাড়াই ছেড়ে দেওয়া — প্রাণঘাতী। উল্টোদিকে একটা benign-কে malignant বলা মানে অতিরিক্ত biopsy/উদ্বেগ — অস্বস্তিকর, কিন্তু জীবন-হানিকর নয়। তাই cancer মিস করা (malignant → benign) হলো worst error।

(গ) নির্ধারণের প্রভাব। এই asymmetry বলে দেয় আমরা কেবল accuracy নয়, sensitivity/recall-on-malignant সর্বোচ্চ করতে চাই এবং threshold \(0.5\)-এর বদলে দরকারে কম threshold নিয়ে benign-ঘোষণা কঠিন করতে পারি (বেশি tumor সন্দেহভাজন রেখে false-negative কমানো)। metric-নির্বাচন সরাসরি এই cost-কাঠামো থেকে আসে।

সমাধান ৩ (★)

(ক) class balance। dataset-এ malignant \(212\) (\(0.373\)) ও benign \(357\) (\(0.627\)) — অর্থাৎ \(62.7\%\) benign। এটা প্রকট imbalance নয় (severe হলে \(<10\%\) ধরা হয়), তবে সমান-ও নয়; benign সংখ্যাগরিষ্ঠ, তাই একটা "সব benign" naive baseline-ই \(62.7\%\) accuracy দেয় — কোনো model-কে এর উপরে যেতে হবে তবেই সে অর্থবহ।

(খ) imbalance-এর ফল। \(0.627\) benign-এর দরুন accuracy বিভ্রান্তিকর: naive \(62.7\%\) baseline থাকায় accuracy একা model-এর গুণ বোঝায় না; উপরন্তু সংখ্যালঘু class (malignant) বেশি ভুল হওয়ার প্রবণতা থাকে। তাই confusion matrix, AUC, sensitivity/specificity আলাদা করে দেখা জরুরি — এদের কেউ majority-class-এর দিকে পক্ষপাতী নয়।

(গ) separating feature। সবচেয়ে বিভাজক feature চেনা হয় standardized mean gap \(\frac{\lvert\mu_{\text{mal}}-\mu_{\text{ben}}\rvert}{\text{sd}}\) দিয়ে — দুই class-এর গড় কত standard deviation দূরে। শীর্ষ তিন: worst concave points \(1.640\), worst perimeter \(1.618\), mean concave points \(1.605\)। এই বড় মান বলে এই feature-গুলোতে দুই class-এর distribution সবচেয়ে কম overlap করে (histogram-এ দুই চূড়া প্রায় আলাদা) — তাই এরা একাই শক্তিশালী predictor, এবং EDA-তে এদের চিহ্নিত করা model-ব্যাখ্যার ভিত্তি।

সমাধান ৪ (★★)

(ক) standardization কী করে। z-score standardization প্রতিটি feature-কে \(z=\frac{x-\bar x}{s}\) রূপে রূপান্তর করে (train-এর \(\bar x,s\) দিয়ে), ফলে প্রতিটি feature-এর mean \(0\), sd \(1\)। এতে "mean area" (মান শত-হাজার) ও "mean smoothness" (মান \(\sim0.1\)) একই স্কেলে আসে।

(খ) কেন coefficient তুলনাযোগ্য হয়। standardized feature-এ logistic coefficient \(\beta_j\) হয়ে যায় "per-1-sd effect" — feature-টা এক standard deviation বাড়লে log-odds কত বদলায়। মূল (কাঁচা) স্কেলে \(\beta\)-এর মাপ feature-এর একক-নির্ভর, তাই তুলনা অর্থহীন; standardize করলে সব \(\beta\) একই এককে (per-sd) আসে, তাই সরাসরি তুলনীয় — কোন feature বেশি প্রভাবশালী তা \(\lvert\beta_j\rvert\) দেখে বলা যায়।

(গ) convergence-এ সাহায্য। gradient-based optimizer (এবং L2 penalty) সব feature সমান-স্কেলে থাকলে অনেক দ্রুত ও স্থিতিশীলভাবে converge করে — নইলে বড়-স্কেল feature loss-surface-কে প্রসারিত করে, ধাপে-ধাপে দুলুনি বাড়ে। তাই standardization logistic regression-কে দ্রুত ও নির্ভরযোগ্যভাবে converge করায় এবং regularization প্রতিটি feature-কে সমান-ভাবে penalize করে।

সমাধান ৫ (★★)

(ক) VIF ও multicollinearity। VIF\(_j=1/(1-R_j^2)\), যেখানে \(R_j^2\) হলো feature \(j\)-কে বাকি সব feature দিয়ে regress করলে পাওয়া \(R^2\)। এটা মাপে feature \(j\) কতটা অন্য feature দিয়ে ব্যাখ্যা করা যায়। VIF \(=1\) মানে সম্পূর্ণ স্বাধীন; VIF বড় মানে অন্যদের সাথে প্রায়-রৈখিক নির্ভরশীল (multicollinearity)।

(খ) VIF \(934.95\)-এর অর্থ। mean perimeter-এর VIF \(934.95\) মানে এর variance অন্য feature-এর উপস্থিতিতে \(\approx935\) গুণ inflated — সমতুল্যভাবে \(R_j^2=1-1/934.95\approx0.9989\), অর্থাৎ mean perimeter-এর \(99.89\%\) variance অন্য feature (মূলত mean radius, mean area) দিয়েই ব্যাখ্যাত। জ্যামিতিকভাবে স্পষ্ট: perimeter, radius, area একই বৃত্তাকার আকৃতির তিন পরিমাপ, তাই প্রায় অনাবশ্যক (redundant)

(গ) coefficient-এ প্রভাব। এমন প্রকট collinearity-তে individual coefficient অস্থির: data সামান্য বদলালে \(\beta\) বড়সড় লাফ দেয়, sign পর্যন্ত উল্টায়, আর standard error ফুলে গিয়ে CI অত্যন্ত চওড়া হয় — কারণ model দুই প্রায়-অভিন্ন feature-এর মধ্যে প্রভাব কীভাবে ভাগ করবে তা নির্ধারণ করতে পারে না। তাই interpretable inference-এর আগে high-VIF feature ছেঁটে বা decorrelate করে নেওয়া দরকার (§৫-এ ৭টি low-VIF feature বেছে নেওয়ার কারণ ঠিক এটাই)।

সমাধান ৬ (★★)

(ক) stratified split কী। stratified split train ও test উভয়েই class-অনুপাত সংরক্ষণ করে — এখানে প্রতিটি অংশে benign-ভগ্নাংশ \(\approx0.627\) রাখা হয় (\(398\) train, \(171\) test উভয়েই একই fraction)। সাধারণ random split-এ এই fraction দৈবক্রমে সরে যেতে পারে।

(খ) কেন imbalance-এ CV-variance কমে। stratified \(K\)-fold-এ প্রতিটি fold-এ benign-fraction \(0.627\)-এর কাছাকাছি স্থির থাকে, তাই fold-গুলোর মধ্যে class-গঠন প্রায় অভিন্ন। ফলে fold-থেকে-fold score-এর ওঠানামা (CV-variance) কমে — score-এর তারতম্য কেবল model থেকে আসে, class-অনুপাতের দৈব-বদল থেকে নয়। imbalance যত বেশি, অ-stratified fold-এ কোনো fold-এ সংখ্যালঘু class কম পড়ার ঝুঁকি তত, তাই stratification-এর লাভ তত বড়।

(গ) canonical সঙ্গতি। এই কারণেই §৬-এর CV band সংকীর্ণ — logistic \(0.993\pm0.008\), RF \(0.989\pm0.007\); ছোট sd (\lvert\(\pm0.008\)\rvert) আংশিকভাবে stratification-এর ফল, কারণ প্রতিটি fold পূর্ণ class-প্রতিনিধিত্ব পায়, তাই কোনো fold অস্বাভাবিক নয়।

সমাধান ৭ (★★)

(ক) odds ratio-র অর্থ। logistic-এ \(e^{\beta_j}\) হলো odds ratio: standardized feature \(j\) এক sd বাড়লে outcome-এর (এখানে benign-এর, যেহেতু target=1 benign) odds কত গুণ হয়। OR \(>1\) benign-odds বাড়ায়; OR \(<1\) benign-odds কমায় (সমতুল্যভাবে malignant-odds বাড়ায়)।

(খ) worst radius OR \(0.002\) worst radius-এর OR \(0.002\) মানে এর মান এক sd বাড়লে benign-এর odds \(0.002\) গুণ হয় — অর্থাৎ প্রায় \(500\) ভাগের এক ভাগে নেমে আসে (\(1/0.002=500\))। উল্টো করে বললে: worst radius এক sd বাড়লে malignant-এর odds \(\approx500\) গুণ হয়। বড় tumor-radius প্রবলভাবে malignancy-র দিকে ঠেলে — চিকিৎসাগতভাবে সম্পূর্ণ যুক্তিসঙ্গত, এবং এটাই এখানে একমাত্র statistically significant driver (\(p=2.24\text{e-}07\))।

(গ) কেন এটাই সবচেয়ে শক্তিশালী। OR-কে \(1\) থেকে যত দূরে (দুই দিকেই), effect তত শক্তিশালী। \(\lvert\log\text{OR}\rvert=\lvert\beta\rvert\) সর্বোচ্চ হওয়ায় worst radius শীর্ষ effect; তার CI \([0.000,0.018]\) পুরোপুরি \(1\)-এর নিচে, তাই effect-এর দিক (malignancy বাড়ায়) নিশ্চিত ও significant — বাকি feature-দের (worst texture \(0.237\), worst concave points \(0.257\), mean smoothness \(0.397\)) OR \(1\)-এর কাছাকাছি বা তাদের CI \(1\) অতিক্রম করে, তাই individually significant নয়।

সমাধান ৮ (★★)

(ক) perfect separation কী। যখন feature-এর কোনো (রৈখিক) সংমিশ্রণ দুই class-কে training-এ নিখুঁতভাবে আলাদা করে ফেলে — অর্থাৎ এমন \(\beta\) আছে যাতে সব malignant একদিকে, সব benign অন্যদিকে — তখন perfect (বা quasi-complete) separation ঘটে। এই dataset-এ class-দুটো এত ভালোভাবে বিভাজ্য যে full \(30\)-feature model-এ এটা ঘটে।

(খ) কেন full MLE diverges। separation থাকলে \(\beta\)-কে যত বড় করা যায়, likelihood তত বাড়ে (প্রতিটি \(p_i\) তার সঠিক \(0\)/\(1\)-এর আরও কাছে যায়), কিন্তু সর্বোচ্চ কখনো সসীম \(\beta\)-তে পৌঁছায় না — MLE অসীমে চলে যায় (সমাধান ১৫-এ প্রমাণ)। ফলে coefficient বিস্ফোরিত, standard error অর্থহীন (Hessian singular হয়ে যায়), odds ratio অসম্ভব বড়/ছোট। এটা কোনো bug নয় — এটা data-র একটা সৎ (honest) বৈশিষ্ট্য, যা রিপোর্ট করা উচিত।

(গ) প্রতিকার। তিনটি ব্যবহারিক সমাধান: (১) L2 regularization — penalty \(\beta\)-কে সসীম রাখে (তাই sklearn-এর default penalized logistic দিব্যি \(0.982\) acc দেয়); (২) feature কমানো/decorrelate — কম, low-VIF feature নিলে separation ভাঙে ও MLE converge করে (§৫-এর ৭-feature model, pseudo-\(R^2\) \(0.866\), cleanly converged); (৩) Firth's penalized likelihood — একটা bias-সংশোধন penalty যা separation-এও সসীম estimate দেয়। এই অধ্যায়ে (১) ও (২) দুটোই ব্যবহৃত।

সমাধান ৯-ধারণা টীকা

(গণনামূলক সমাধান ৯ থেকে খ-বিভাগ শুরু; নিচে conceptual-এর অবশিষ্ট AUC/calibration/importance/leakage/model-card বিষয়গুলো এই ৮ নম্বর সমাধানেই সংহত করা হলো, যাতে §ক সম্পূর্ণ থাকে।)

AUC বনাম accuracy (imbalance-এ)। AUC (ROC-এর নিচের ক্ষেত্রফল) মাপে model দুই class-কে র‍্যাঙ্ক করে কতটা ভালো আলাদা করে — threshold-নিরপেক্ষ, তাই majority-class-এর দিকে পক্ষপাতহীন। accuracy একটা নির্দিষ্ট threshold-এ এবং class-অনুপাত-নির্ভর, তাই \(0.627\)-benign-এ বিভ্রান্তিকর হতে পারে (naive baseline-ই \(0.627\))। এখানে AUC \(0.997\)/\(0.996\) বলে model প্রায়-নিখুঁত ranking দেয়, যা accuracy \(0.982\)/\(0.971\)-এর চেয়ে বেশি তথ্যবহ।

Calibration। একটা model calibrated যদি সে যখন "\(P(\text{benign})=0.8\)" বলে, সত্যিই তেমন প্রায় \(80\%\) ঘটনা benign হয়। logistic সাধারণত ভালো-calibrated (কারণ সে সরাসরি probability optimize করে); random forest ভোট-গড় করায় প্রায়ই চরম-probability-তে over/under-confident, তাই calibration curve \(45°\)-রেখা থেকে সরে যেতে পারে। medical প্রসঙ্গে calibration গুরুত্বপূর্ণ, কারণ probability-র উপর সিদ্ধান্ত নেওয়া হয়।

permutation বনাম impurity importance। impurity-based (RF-এর default) importance high-cardinality/বেশি-split-সম্ভব feature-কে অযথা বড় দেখায় ও collinear feature-এ importance ভাগ করে দেয়। permutation importance ভালো: একটা feature-এর মান এলোমেলো permute করে দেখা হয় accuracy কতটা পড়ে — সত্যিকার গুরুত্বপূর্ণ feature permute করলে accuracy অনেক পড়ে, এটা split-গণনার পক্ষপাত এড়ায় ও model-agnostic।

leakage ও Pipeline। leakage = test-তথ্য (গড়, sd, বা target) কোনোভাবে train-এ ঢুকে গিয়ে accuracy কৃত্রিমভাবে বাড়িয়ে দেওয়া। সবচেয়ে সাধারণ ভুল — পুরো data-তে standardize করে তারপর split। সঠিক প্রতিকার: scaler ও model একটা Pipeline-এ বেঁধে দেওয়া, যাতে CV-র প্রতিটি fold-এ scaler কেবল সেই fold-এর train-অংশে fit হয় — §৬-এর CV ঠিক এভাবে make_pipeline-এ করা।

model card। একটা model card হলো model-এর সংক্ষিপ্ত "লেবেল": উদ্দেশ্য, training data ও তার সীমা, performance (কোন metric, কোন population-এ), জানা দুর্বলতা (এখানে: full-MLE separation, RF-calibration), এবং নৈতিক/প্রয়োগ-সতর্কতা (এটা diagnostic-সহায়ক, চূড়ান্ত রায় নয়)। এটা model-কে দায়িত্বশীলভাবে হস্তান্তরযোগ্য করে।


খ · গণনামূলক (computational)

সমাধান ৯ (★)

ধরা যাক feature \(j\)-কে বাকি feature দিয়ে regress করে পাওয়া গেল \(R_j^2=0.9989\)

(ক) VIF। $$ \text{VIF}_j=\frac{1}{1-R_j^2}=\frac{1}{1-0.9989}=\frac{1}{0.0011}\approx\mathbf{909}. $$ এটা canonical mean radius (\(891.13\)) ও mean perimeter (\(934.95\))-এর মধ্যবর্তী মাত্রার — অর্থাৎ radius-family-র feature-দের VIF এই কোটিতে হওয়া প্রত্যাশিত।

(খ) সাধারণ সূত্র ও ব্যাখ্যা। যেকোনো feature-এর জন্য \(\text{VIF}=\dfrac{1}{1-R^2}\); \(R^2\to1\) (প্রায়-অনাবশ্যক feature) হলে VIF \(\to\infty\), আর \(R^2=0\) (সম্পূর্ণ স্বাধীন) হলে VIF \(=1\)। VIF হলো সেই গুণক যা দিয়ে collinearity coefficient-এর variance বাড়ায়, তাই standard error \(\sqrt{\text{VIF}}\) গুণ বড় হয়।

(গ) থাম্ব-রুল। সাধারণত VIF \(>5\) বা \(>10\) উদ্বেগজনক ধরা হয়; \(909\) সেই সীমা বহু গুণ ছাড়ায়, তাই এই feature interpretable model-এ একা রাখা অনুচিত — হয় ছাঁটতে হবে, নয় family থেকে একটিই রাখতে হবে।

সমাধান ১০ (★★)

standardized feature-এ logistic coefficient \(\beta\), তাই per-1-sd odds ratio \(=e^\beta\); এবং \(k\) sd পরিবর্তনে odds গুণ হয় \(e^{k\beta}=(e^\beta)^k\)

(ক) OR হিসাব। worst radius-এর coefficient \(\beta=-6.466\) ধরলে $$ \text{OR}=e^\beta=e^{-6.466}=\mathbf{0.00156}\approx0.002. $$ এটাই canonical worst radius OR \(0.002\)

(খ) \(+2\) sd পরিবর্তন। $$ e^{2\beta}=(e^\beta)^2=(0.00156)^2=\mathbf{2.4\times10^{-6}}. $$ অর্থাৎ worst radius দুই sd বাড়লে benign-এর odds মূলের প্রায় \(2.4\) মিলিয়ন-ভাগের এক ভাগে নেমে আসে — কার্যত tumor-কে নিশ্চিত malignant-এর দিকে ঠেলে দেয়।

(গ) ব্যাখ্যা। OR \(<1\) মানে feature বাড়লে benign-probability পড়ে; effect সংখ্যাবৃদ্ধিক (multiplicative) log-odds-এ যোগাত্মক। যেহেতু \(\lvert\beta\rvert\) বড়, প্রভাবও তীব্র — একক-sd-ই odds-কে \(500\) ভাগে নামায়, দুই sd তা বর্গ করে আরও চরম করে। এই তীব্রতা ও সরু CI-ই worst radius-কে একমাত্র significant predictor করে।

সমাধান ১১ (★★)

confusion matrix (positive = benign, threshold \(0.5\), logistic test): TN \(=63\), FP \(=1\), FN \(=2\), TP \(=105\); মোট \(63+1+2+105=171\)

(ক) accuracy। $$ \text{accuracy}=\frac{\text{TP}+\text{TN}}{N}=\frac{105+63}{171}=\frac{168}{171}=\mathbf{0.982}. $$

(খ) sensitivity (recall, benign)। $$ \text{sensitivity}=\frac{\text{TP}}{\text{TP}+\text{FN}}=\frac{105}{105+2}=\frac{105}{107}=\mathbf{0.981}. $$

(গ) specificity ও precision। $$ \text{specificity}=\frac{\text{TN}}{\text{TN}+\text{FP}}=\frac{63}{63+1}=\frac{63}{64}=\mathbf{0.984}, $$ $$ \text{precision}=\frac{\text{TP}}{\text{TP}+\text{FP}}=\frac{105}{105+1}=\frac{105}{106}=\mathbf{0.991}. $$ চিকিৎসা-ব্যাখ্যা: specificity \(0.984\) মানে malignant-দের \(98.4\%\) সঠিকভাবে malignant-শ্রেণিভুক্ত (কেবল \(1\)টি malignant ভুলবশত benign বলা হয়েছে — এই একটিই সবচেয়ে ব্যয়বহুল ভুল)।

সমাধান ১২ (★★)

stratified \(5\)-fold CV AUC: logistic \(0.993\pm0.008\), RF \(0.989\pm0.007\)

(ক) পার্থক্য বনাম অনিশ্চয়তা। mean-পার্থক্য \(0.993-0.989=0.004\)। এটা যেকোনো একটা model-এর sd (\lvert\(\approx0.008\)\rvert) থেকেও ছোট — অর্থাৎ দুই model-এর CI-band বিস্তর overlap করে। তাই এই data-য় logistic ও RF-এর AUC আলাদা করা যায় না; পার্থক্যটা fold-ওঠানামার মধ্যে চাপা।

(খ) band-এর অর্থ। \(\pm0.008\) মোটামুটি \(\pm1\) standard deviation — approximately-normal ধরলে \(\approx68\%\) fold mean-এর \(0.008\)-এর মধ্যে পড়ে। ছোট এই band বলে score fold-থেকে-fold স্থিতিশীল।

(গ) সিদ্ধান্ত। দুই model-ই চমৎকার ও স্থিতিশীল (\(\text{mean}\approx0.99\), sd \(\approx0.01\))। ছোট sd মানে কোনো একটা "lucky split"-এর উপর নির্ভরতা নেই — single-split test AUC (\(0.997\)/\(0.996\)) CV-mean-এর সাথে সঙ্গতিপূর্ণ। model-নির্বাচন তাই AUC নয়, বরং interpretability (logistic → odds ratio) বা calibration-এর ভিত্তিতে করাই যুক্তিযুক্ত।

সমাধান ১৩ (★★)

(baseline-তুলনা)। naive "সব benign" baseline accuracy \(=0.627\) (benign-fraction)। logistic accuracy \(0.982\), তাই baseline-এর উপরে উন্নতি \(0.982-0.627=\mathbf{0.355}\) (পরম), বা error-হ্রাসে: baseline-error \(0.373\to\) model-error \(0.018\), অর্থাৎ error \(\approx95\%\) কমেছে (\(1-0.018/0.373=0.952\))। এই তুলনাই দেখায় accuracy একা নয়, baseline-সাপেক্ষ উন্নতি রিপোর্ট করা জরুরি — নইলে \(0.982\)-কে অতিমূল্যায়ন হয়।


গ · প্রমাণভিত্তিক (proof-based)

সমাধান ১৪ (★★★)

দাবি। logistic regression-এর log-likelihood \(\ell(\beta)\) concave; ফলে যেকোনো stationary point (থাকলে) unique global maximum

সেটআপ। \(n\)টি observation, \(y_i\in\{0,1\}\), \(p_i=\sigma(\beta^\top x_i)=\dfrac{1}{1+e^{-\beta^\top x_i}}\), যেখানে \(\sigma\) logistic sigmoid। Bernoulli log-likelihood: $$ \ell(\beta)=\sum_{i=1}^{n}\Big[y_i\log p_i+(1-y_i)\log(1-p_i)\Big]. $$

gradient। \(\sigma'(z)=\sigma(z)(1-\sigma(z))\) ব্যবহার করে, \(\dfrac{\partial p_i}{\partial\beta}=p_i(1-p_i)x_i\)। প্রতিটি পদ derive করলে (চেইন-রুলে \(y_i\log p_i+(1-y_i)\log(1-p_i)\)-এর derivative \((y_i-p_i)x_i\)-এ সরল হয়): $$ \nabla\ell(\beta)=\sum_{i=1}^{n}(y_i-p_i)\,x_i. $$

Hessian। \(\nabla\ell\)-কে আবার \(\beta\)-সাপেক্ষে differentiate; \(\dfrac{\partial p_i}{\partial\beta}=p_i(1-p_i)x_i\) বসিয়ে: $$ H(\beta)=\nabla^2\ell(\beta)=-\sum_{i=1}^{n}p_i(1-p_i)\,x_i x_i^\top. $$

negative semi-definite প্রমাণ। যেকোনো vector \(v\)-এর জন্য $$ v^\top H v=-\sum_{i=1}^{n}p_i(1-p_i)\,(x_i^\top v)^2\le0, $$ কারণ \(p_i\in(0,1)\Rightarrow p_i(1-p_i)>0\) এবং \((x_i^\top v)^2\ge0\)। প্রতিটি পদ \(\ge0\), সামনে ঋণচিহ্ন, তাই যোগফল \(\le0\)। সুতরাং \(H\preceq0\)\(\ell\) concave

উপসংহার। concave function-এ যেকোনো stationary point (\(\nabla\ell=0\)) global maximum, এবং \(H\prec0\) (strict, যা \(x_i\)-রা full-rank span করলে হয়) হলে সেটা unique। এজন্যই penalized/converging ক্ষেত্রে logistic-এর সমাধান একক ও স্থিতিশীল — Newton/IRLS নির্ভরযোগ্যভাবে সেই একমাত্র চূড়ায় পৌঁছায় (যখন তা সসীমে থাকে; সমাধান ১৫ দেখায় কখন থাকে না)। \(\blacksquare\)

সমাধান ১৫ (★★★)

দাবি। training data যদি একটা hyperplane দিয়ে নিখুঁতভাবে বিভাজ্য (perfectly separable) হয়, তবে logistic MLE-র কোনো সসীম সমাধান নেই\(\hat\beta\) অসীমে চলে যায়।

সেটআপ। ধরা যাক এমন \(\beta^*\) আছে (এবং সুবিধার্থে intercept \(\beta^*\)-এ শোষিত) যাতে strict separation ধরে: $$ \beta^{\top}x_i>0\iff y_i=1,\qquad \beta^{\top}x_i<0\iff y_i=0,\quad\text{সব }i. $$

scaling যুক্তি। \(c>0\)-এর জন্য \(\beta=c\beta^*\) নিন। তখন প্রতিটি \(i\)-তে: - \(y_i=1\) হলে \(\beta^{*\top}x_i>0\Rightarrow c\beta^{*\top}x_i\to+\infty\Rightarrow p_i=\sigma(c\beta^{*\top}x_i)\to1\), তাই \(\log p_i\to0\)। - \(y_i=0\) হলে \(\beta^{*\top}x_i<0\Rightarrow c\beta^{*\top}x_i\to-\infty\Rightarrow p_i\to0\Rightarrow\log(1-p_i)\to0\)

তাই \(c\to\infty\)-এ প্রতিটি পদ \(\to0\), ফলে $$ \ell(c\beta^*)\longrightarrow 0=\sup_\beta\ell(\beta), $$ কারণ Bernoulli log-likelihood সর্বদা \(\le0\) (\(p_i\in(0,1)\) বলে \(\log p_i<0\))। supremum \(0\)

কেন সসীমে অপ্রাপ্য। যেকোনো সসীম \(c\)-তে অন্তত একটা \(p_i\ne y_i\) (কঠোরভাবে, \(0<p_i<1\)), তাই \(\ell(c\beta^*)<0\) — supremum \(0\) কখনো ছোঁয়া হয় না। উপরন্তু \(\ell(c\beta^*)\) প্রমাণিতভাবে \(c\)-তে কঠোরভাবে বর্ধমান (প্রতিটি পদ \(c\)-তে monotone \(0\)-র দিকে যায়), তাই কোনো সসীম maximizer নেই — \(\lVert\hat\beta\rVert\to\infty\)

Hessian-এর অবক্ষয়। যত \(c\to\infty\), প্রতিটি \(p_i\to0\) বা \(1\), তাই \(p_i(1-p_i)\to0\), ফলে সমাধান ১৪-এর Hessian \(H=-\sum p_i(1-p_i)x_ix_i^\top\to0\)singular। singular Hessian মানে standard error \(\propto\sqrt{\text{diag}(-H^{-1})}\) অসংজ্ঞায়িত/বিস্ফোরিত, তাই কোনো বৈধ CI বা \(p\)-value দেওয়া যায় না।

প্রতিকার (সারসংক্ষেপ)। (১) L2 penalty \(-\frac{\lambda}{2}\lVert\beta\rVert^2\) যোগ করলে objective কঠোরভাবে concave ও coercive হয়, তাই সসীম unique maximizer ফেরে; (২) feature হ্রাস/decorrelation separation ভেঙে দেয় (কম-মাত্রায় data আর নিখুঁত-বিভাজ্য থাকে না); (৩) Firth penalty Jeffreys-prior-ভিত্তিক সংশোধন যা separation-এও সসীম, কম-biased estimate দেয়। এই অধ্যায়ে full-\(30\) MLE-র divergence তাই bug নয় — data এত ভালো-বিভাজ্য হওয়ারই সৎ পরিণাম, আর তাই interpretable inference \(7\)-feature converged model-এ করা হয়েছে। \(\blacksquare\)


ঘ · কোডিং (Python)

সমাধান ১৬ (★★★)

নিচের সম্পূর্ণ, চালানোযোগ্য script (seed 20260619) পুরো pipeline পুনরুৎপাদন করে: breast_cancer লোড → stratified \(70/30\) split → standardize → L2 logistic → RF (\(400\), OOB) → statsmodels Logit (\(7\) decorrelated feature) → stratified \(5\)-fold CV (Pipeline দিয়ে, leakage-মুক্ত) → confusion matrix।

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import (train_test_split, StratifiedKFold,
                                     cross_val_score)
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import make_pipeline
from sklearn.metrics import (accuracy_score, roc_auc_score, confusion_matrix)
import statsmodels.api as sm

SEED = 20260619
np.random.seed(SEED)

#--- 1. load + class balance -----------------------------------------
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target, name="target")        # 0=malignant, 1=benign
n_mal, n_ben = int((y == 0).sum()), int((y == 1).sum())
print(f"shape={X.shape}  malignant={n_mal} ({n_mal/len(y):.3f})  "
      f"benign={n_ben} ({n_ben/len(y):.3f})")

#--- 2. stratified split + standardise -------------------------------
Xtr, Xte, ytr, yte = train_test_split(
    X, y, test_size=0.30, random_state=SEED, stratify=y)
scaler = StandardScaler().fit(Xtr)
Xtr_s, Xte_s = scaler.transform(Xtr), scaler.transform(Xte)
print(f"train={len(ytr)}  test={len(yte)}  "
      f"(train benign={ytr.mean():.3f}, test benign={yte.mean():.3f})")

#--- 3. L2 logistic (full 30 feats, penalised => converges) ----------
logit = LogisticRegression(max_iter=5000, random_state=SEED).fit(Xtr_s, ytr)
p_logit = logit.predict_proba(Xte_s)[:, 1]
acc_l = accuracy_score(yte, logit.predict(Xte_s))
auc_l = roc_auc_score(yte, p_logit)
print(f"logistic : acc={acc_l:.3f}  AUC={auc_l:.3f}")

#--- 4. random forest (400 trees, OOB) -------------------------------
rf = RandomForestClassifier(n_estimators=400, oob_score=True,
                            random_state=SEED, n_jobs=1).fit(Xtr_s, ytr)
p_rf = rf.predict_proba(Xte_s)[:, 1]
print(f"rand-fst : acc={accuracy_score(yte, rf.predict(Xte_s)):.3f}  "
      f"AUC={roc_auc_score(yte, p_rf):.3f}  OOB={rf.oob_score_:.3f}")

#--- 5. statsmodels Logit on 7 decorrelated feats (converges) --------
INFER = ["mean texture", "mean smoothness", "mean concavity", "mean symmetry",
         "worst concave points", "worst radius", "worst texture"]
Xsm = sm.add_constant(pd.DataFrame(Xtr_s, columns=X.columns)[INFER])
res = sm.Logit(ytr.values, Xsm).fit(disp=0, maxiter=200)
OR = np.exp(res.params).drop("const")
ci = np.exp(res.conf_int()).drop("const")
p = res.pvalues.drop("const")
print(f"(inference: 7 feats, converged={res.mle_retvals['converged']}, "
      f"pseudo-R2={res.prsquared:.3f})")
print(f"  worst radius : OR={OR['worst radius']:.3f} "
      f"[{ci.loc['worst radius',0]:.3f},{ci.loc['worst radius',1]:.3f}]  "
      f"p={p['worst radius']:.2e}")
print(f"  significant at 5% : {int((p < 0.05).sum())} of {len(p)}")

#--- 6. stratified 5-fold CV via Pipeline (no leakage) ---------------
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=SEED)
pipe_l = make_pipeline(StandardScaler(),
                       LogisticRegression(max_iter=5000, random_state=SEED))
pipe_r = make_pipeline(StandardScaler(),
                       RandomForestClassifier(n_estimators=400,
                                              random_state=SEED, n_jobs=1))
cvl = cross_val_score(pipe_l, X, y, cv=cv, scoring="roc_auc")
cvr = cross_val_score(pipe_r, X, y, cv=cv, scoring="roc_auc")
print(f"CV AUC logistic : {cvl.mean():.3f} +/- {cvl.std():.3f}")
print(f"CV AUC rand-fst : {cvr.mean():.3f} +/- {cvr.std():.3f}")

#--- 7. confusion matrix (logistic, thr=0.5) -------------------------
tn, fp, fn, tp = confusion_matrix(yte, logit.predict(Xte_s)).ravel()
print(f"confusion (thr=0.5): TN={tn} FP={fp} FN={fn} TP={tp}")
print(f"  sensitivity={tp/(tp+fn):.3f}  specificity={tn/(tn+fp):.3f}")

প্রত্যাশিত output (verbatim, seed 20260619):

shape=(569, 30)  malignant=212 (0.373)  benign=357 (0.627)
train=398  test=171  (train benign=0.627, test benign=0.626)
logistic : acc=0.982  AUC=0.997
rand-fst : acc=0.971  AUC=0.996  OOB=0.965
(inference: 7 feats, converged=True, pseudo-R2=0.866)
  worst radius : OR=0.002 [0.000,0.018]  p=2.24e-07
  significant at 5% : 1 of 7
CV AUC logistic : 0.993 +/- 0.008
CV AUC rand-fst : 0.989 +/- 0.007
confusion (thr=0.5): TN=63 FP=1 FN=2 TP=105
  sensitivity=0.981  specificity=0.984

পাঠোদ্ধার। output দুটো গুরুত্বপূর্ণ কথা বলে। প্রথমত, দুই model-ই কার্যত নিখুঁত (AUC \(\approx0.99\), test acc \(0.982\)/\(0.971\)), আর CV-band সরু (\(\pm0.008\)/\(\pm0.007\)) হওয়ায় এই performance কোনো lucky split নয় — stable ও reproducible। দ্বিতীয়ত, interpretable inference-এ \(7\)টির মধ্যে কেবল worst radius significant (OR \(0.002\), অর্থাৎ প্রতি \(+1\) sd-এ benign-odds \(500\) ভাগে নামে, \(p=2.24\text{e-}07\)) — বাকিরা collinearity-র দরুন individually অস্পষ্ট। আর মনে রাখতে হবে full-\(30\) unpenalized MLE এখানে diverge করত (perfect separation); তাই L2 (prediction-এর জন্য) ও ছোট decorrelated Logit (inference-এর জন্য) — এই দুই-মুখী কৌশলই এই dataset-এর সৎ সমাধান।