সমাধান — অধ্যায় ১.১ · Data Types, Populations & Samples¶
এই ফাইলে ১.১ অধ্যায়ের সব অনুশীলনীর পূর্ণ সমাধান। প্রতিটি কোড runnable; নিচে প্রকৃত output দেওয়া (reproducible — seed উল্লেখ করা)।
Conceptual¶
সমাধান ১ — population নাকি sample [easy]¶
| চরিত্র | কারণ | unit | |
|---|---|---|---|
| (ক) জরিপ করা ১,২০০ জন | sample | পুরো ভোটার-গোষ্ঠী থেকে নেওয়া পর্যবেক্ষিত অংশ | একজন ভোটার |
| (খ) আজকের সব ১০,০০০ bulb | population | প্রশ্নটি (গুণমান) এই গোটা ব্যাচ সম্পর্কে | একটি bulb |
| (গ) পরীক্ষা করা ৫০টি bulb | sample | ওই population থেকে নেওয়া অংশ | একটি bulb |
মূল কথা: "বাংলাদেশের সব ভোটার" হলো (ক)-এর population (যা আমরা পুরোপুরি দেখি না), আর (খ) নিজেই একটি population — কারণ প্রশ্ন বদলালে কোনটা population তা বদলায়। (খ) দেখায় population সবসময় বিশাল জনগোষ্ঠী হতে হয় না — সংজ্ঞাটা প্রশ্ন-নির্ভর।
সমাধান ২ — parameter নাকি statistic [easy]¶
| চরিত্র | চিহ্ন | |
|---|---|---|
| (ক) সব পরিবারের প্রকৃত গড় আয় | parameter (population, অজানা) | \(\mu\) |
| (খ) ৫০০ পরিবারের গড় আয় | statistic (sample থেকে গণনাযোগ্য) | \(\bar{x}\) |
| (গ) সব পণ্যের সত্যিকারের ত্রুটি-অনুপাত | parameter | \(p\) |
নিয়ম: Greek অক্ষর (\(\mu, p\)) → parameter (population); Roman অক্ষর (\(\bar{x}\)) → statistic (sample)। (খ)-এর \(\bar{x}\) হলো (ক)-এর \(\mu\)-এর একটি estimate।
সমাধান ৩ — data type শনাক্তকরণ [medium]¶
| variable | data type | কারণ | |
|---|---|---|---|
| (ক) ZIP/postal code | nominal | সংখ্যা দেখতে হলেও এর গড়/ক্রম অর্থহীন; নিছক লেবেল | |
| (খ) শরীরের তাপমাত্রা | numeric — continuous | যেকোনো ভগ্নাংশ মান (\(98.6°\)F) নিতে পারে | |
| (গ) \(1\)–\(5\) তারকা রেটিং | ordinal | ক্রম আছে (৫ > ৪ > …), কিন্তু "৫−৪" বনাম "২−১" ব্যবধান সমান অর্থ বহন করে না | |
| (ঘ) ইমেল spam কিনা | binary | ঠিক দুটি শ্রেণি (spam / not), প্রায়ই \(1/0\) | |
| (ঙ) পরিবারের সদস্য সংখ্যা | numeric — discrete | গণনাযোগ্য পূর্ণসংখ্যা ("কতজন") |
মূল শিক্ষা (§২.৩-এর সতর্কতা): ZIP code "সংখ্যা দেখতে" কিন্তু nominal — সংরক্ষণ-রূপ নয়, অর্থ ঠিক করে data type। রেটিং ordinal, continuous নয়; তাই "গড় রেটিং" রিপোর্ট করা যায় ঠিকই কিন্তু সাবধানে ব্যাখ্যা করতে হয়।
সমাধান ৪ — বড় sample-ও কেন biased হতে পারে [medium]¶
এই sampling-কে বলা হয় self-selection / convenience sampling (স্ব-নির্বাচিত নমুনা)। সমস্যা দুই স্তরে:
- Coverage bias: শুধু ওই টেক-ব্লগের পাঠকেরাই লিঙ্কটি দেখতে পান। তাঁরা সাধারণ জনগোষ্ঠীর প্রতিনিধি নন — সম্ভবত গড়ের চেয়ে বেশি টেক-সচেতন, তরুণ, বেশি অনলাইন-সক্রিয়। ফলে "গড় ইন্টারনেট-ব্যবহার" পদ্ধতিগতভাবে বেশি আসবে।
- Non-response / self-selection bias: যাঁরা স্বেচ্ছায় ক্লিক করে উত্তর দেন, তাঁরাও বিশেষ ধরনের (বিষয়ে আগ্রহী) — এলোমেলো নন।
বড় \(n\) সমস্যা মেটায় না। \(1{,}00{,}000\) উত্তরদাতাও যদি একই দিকে পক্ষপাতদুষ্ট হন, তবে \(\bar{x}\) সত্যিকারের \(\mu\) থেকে একটি systematic দূরত্বে থেকে যায়; size বাড়লে শুধু সেই ভুল মানের চারপাশে variance কমে — মানে আমরা "আরও আত্মবিশ্বাসের সাথে ভুল"। নির্ভুলতার চাবি size নয়, randomness ও representativeness (§২.৫, §৪.২)। সমাধান হতো গোটা জনগোষ্ঠী থেকে একটি SRS (বা সঠিকভাবে weighted probability sample)।
Computational¶
সমাধান ৫ — binary গড় = অনুপাত (যাচাই) [easy]¶
import numpy as np
rng = np.random.default_rng(0)
b = rng.integers(0, 2, 500) # 0/1 binary, n = 500
print("mean =", b.mean()) # গড়
print("# ones =", b.sum()) # ১-এর সংখ্যা
print("ones / n =", b.sum() / 500)
print("equal? ", np.isclose(b.mean(), b.sum() / 500))
প্রকৃত output:
গড় (\(0.55\)) ঠিক (১-এর সংখ্যা)/\(n = 275/500 = 0.55\)-এর সমান — এটিই §৪.১-এর প্রমাণের সংখ্যাগত নিশ্চিতি: \(\bar{x} = k/n = \hat{p}\)। binary data-তে গড় ও অনুপাত একই জিনিস।
সমাধান ৬ — dtype ও ordered comparison [medium]¶
import numpy as np, pandas as pd
rng = np.random.default_rng(42)
n = 200
city = rng.choice(["Dhaka","Chattogram","Khulna"], size=n, p=[0.5,0.3,0.2])
age = rng.integers(18, 60, size=n)
income = np.round(rng.lognormal(mean=10.6, sigma=0.45, size=n) / 1000, 1)
satisfaction = rng.choice(["Low","Medium","High"], size=n, p=[0.25,0.45,0.30])
subscribed = rng.integers(0, 2, size=n)
df = pd.DataFrame({
"city": pd.Categorical(city),
"age": age, "income_k": income,
"satisfaction": pd.Categorical(satisfaction,
categories=["Low","Medium","High"], ordered=True),
"subscribed": subscribed,
})
print(df.dtypes)
print((df["satisfaction"] > "Low").sum())
প্রকৃত output:
(ক) taxonomy লেবেল:
| column | dtype | taxonomy |
|---|---|---|
city |
category | nominal |
age |
int64 | numeric — discrete |
income_k |
float64 | numeric — continuous |
satisfaction |
category (ordered) | ordinal |
subscribed |
int64 | binary |
(খ) (df["satisfaction"] > "Low").sum() = \(153\)। যেহেতু satisfaction ordered categorical (Low < Medium < High), > "Low" তুলনা বৈধ এবং Medium বা High সব row-কে True দেয়। অর্থাৎ ২০০ জনের মধ্যে ১৫৩ জন Low-এর চেয়ে বেশি সন্তুষ্ট (বাকি \(47\) জন Low)। ordered=True না দিলে এই তুলনা TypeError দিত — ordinal data সঠিকভাবে এনকোড করার এটাই বড় সুবিধা।
Coding¶
সমাধান ৭ — summarize_column [medium]¶
import pandas as pd
def summarize_column(s):
"""dtype দেখে স্বয়ংক্রিয়ভাবে সঠিক summary ফেরত দেয়।"""
if pd.api.types.is_numeric_dtype(s):
return ("numeric", round(s.mean(), 2), round(s.std(), 2))
else:
return ("categorical", s.value_counts().to_dict())
print("income_k:", summarize_column(df["income_k"]))
print("city :", summarize_column(df["city"]))
প্রকৃত output:
income_k: ('numeric', 44.88, 20.17)
city : ('categorical', {'Dhaka': 104, 'Chattogram': 61, 'Khulna': 35})
ফাংশনটি numeric column-এ (mean, std) আর categorical-এ গণনা ফেরত দেয় — ঠিক §৫.৪-এর "data type অনুযায়ী বৈধ summary" নীতির স্বয়ংক্রিয় রূপ। is_numeric_dtype int64/float64-কে numeric ধরে, category/object-কে নয়। (চাইলে subscribed binary-কে আলাদা শাখায় রেখে proportion ফেরত দেওয়া যেত — সেটি একটি ভালো সম্প্রসারণ।)
সমাধান ৮ — repeated sampling: sampling distribution-এর প্রথম ঝলক [hard]¶
import matplotlib; matplotlib.use("Agg")
import numpy as np, matplotlib.pyplot as plt
rng = np.random.default_rng(7)
N = 20_000
pop = rng.lognormal(mean=10.6, sigma=0.5, size=N) / 1000 # population
mu = pop.mean() # TRUE μ
weights = pop / pop.sum() # biased: ∝ income
B = 500 # পুনরাবৃত্তি
srs_means = np.empty(B)
bias_means = np.empty(B)
for j in range(B):
srs_means[j] = rng.choice(pop, size=300, replace=False).mean()
idx = rng.choice(np.arange(N), size=300, replace=False, p=weights)
bias_means[j] = pop[idx].mean()
print(f"pop mean μ = {mu:.2f}")
print(f"mean of SRS means = {srs_means.mean():.2f} (err {srs_means.mean()-mu:+.2f})")
print(f"mean of biased means= {bias_means.mean():.2f} (err {bias_means.mean()-mu:+.2f})")
fig, ax = plt.subplots(figsize=(8, 4.5))
ax.hist(srs_means, bins=30, alpha=0.6, color="#2563eb", label="SRS means")
ax.hist(bias_means, bins=30, alpha=0.6, color="#dc2626", label="biased means")
ax.axvline(mu, color="black", lw=2, label=f"true μ = {mu:.1f}")
ax.set_xlabel("sample mean of income (k BDT)"); ax.set_ylabel("frequency")
ax.set_title("Sampling distribution of the mean: SRS vs biased (500 repeats)")
ax.legend()
fig.tight_layout()
# fig.savefig("srs_vs_biased_sampling_dist.png", dpi=150) # চাইলে সংরক্ষণ
প্রকৃত output:
(ক)+(খ) ব্যাখ্যা। ৫০০টি SRS-এর sample-mean-গুলোর গড় \(\approx 45.21\) — true \(\mu = 45.25\)-এর প্রায় হুবহু উপরে; এদের histogram \(\mu\)-এর চারপাশে symmetric (প্রতিসম)-ভাবে কেন্দ্রীভূত। বিপরীতে biased sample-mean-গুলোর গড় \(\approx 57.77\), \(\mu\) থেকে \(+12.5\) ডানে সরে গিয়ে একটি আলাদা histogram তৈরি করে যা \(\mu\)-কে ঘিরে নেই।
কারণ §৪.২: SRS-এ \(\mathbb{E}[X_i] = \mu\), তাই \(\mathbb{E}[\bar{X}] = \mu\) — পুনরাবৃত্ত sample-এর গড় \(\mu\)-তেই বসে (unbiased)। income-weighted sampling-এ বেশি-আয়ের unit বেশি সম্ভাবনায় বাছাই হয়, তাই কার্যকরভাবে \(\mathbb{E}[X_i] > \mu\), ফলে \(\mathbb{E}[\bar{X}] > \mu\) (biased) — এবং পুনরাবৃত্তি যত বাড়ুক, এই \(+12.5\) ঝোঁক যায় না। (এই sample-mean-এর নিজস্ব distribution-ই sampling distribution, যার রূপ ও বিস্তার Part III-এর CLT ও Part IV-এর inference-এ মূল ভূমিকা নেবে।)
Proof¶
সমাধান ৯ — ধ্রুবক যোগে গড় সরে [medium] ★¶
দাবি: \(y_i = x_i + c\) হলে \(\bar{y} = \bar{x} + c\)।
প্রমাণ. সংজ্ঞা থেকে, যোগফলকে দুই ভাগে ভাঙি: $$ \bar{y} = \frac{1}{n}\sum_{i=1}^{n} y_i = \frac{1}{n}\sum_{i=1}^{n} (x_i + c) = \frac{1}{n}\left(\sum_{i=1}^{n} x_i + \sum_{i=1}^{n} c\right) = \frac{1}{n}\sum_{i=1}^{n} x_i + \frac{1}{n}\,(n c) = \bar{x} + c. \qquad \blacksquare $$ এখানে \(\sum_{i=1}^{n} c = nc\) ব্যবহার করেছি (\(c\) ধ্রুবক, \(n\) বার যোগ)।
যাচাই (কোডে): x = [2,4,6,8], \(c = 10\) → \(\bar{x} = 5\), \(\bar{y} = 15 = 5 + 10\)। ✓
গুরুত্ব: এই "location shift" বৈশিষ্ট্যই center-কে স্থানান্তরযোগ্য (translation-equivariant) করে; অধ্যায় 1.2-এর standardization (\(z = (x-\bar{x})/s\), যেখানে \(c = -\bar{x}\)) ঠিক এই নীতির উপর দাঁড়ানো — সেখানে centering-এর পর নতুন গড় হয় \(\bar{x} + (-\bar{x}) = 0\)।
সমাধান ১০ — single-draw indicator-এর expectation = \(p\) [hard] ★★¶
Setup. population-এ \(M\)টি unit; \(K\)টির বৈশিষ্ট্যটি আছে, তাই \(p = K/M\)। SRS-এ একটি unit তুললে প্রতিটি unit সমান সম্ভাবনা \(1/M\) পায়। indicator \(X = 1\) যদি তোলা unit-এর বৈশিষ্ট্যটি থাকে, নাহলে \(X = 0\)।
ধাপ ১ — \(X\)-এর distribution। বৈশিষ্ট্যযুক্ত \(K\)টি unit-এর যেকোনো একটি ওঠার সম্ভাবনা: $$ P(X = 1) = \frac{K}{M} = p, \qquad P(X = 0) = 1 - p. $$ অর্থাৎ \(X \sim \text{Bernoulli}(p)\)।
ধাপ ২ — expectation। সংজ্ঞা থেকে: $$ \mathbb{E}[X] = 1 \cdot P(X=1) + 0 \cdot P(X=0) = 1 \cdot p + 0 \cdot (1-p) = p. \qquad \blacksquare $$
ধাপ ৩ — \(\hat{p} = \bar{X}\) কেন unbiased। \(n\) আকারের SRS-এ প্রতিটি draw-এর indicator \(X_1,\dots,X_n\), প্রত্যেকের \(\mathbb{E}[X_i] = p\) (ধাপ ২)। sample proportion ঠিক এদের গড়: $$ \hat{p} = \frac{(\text{বৈশিষ্ট্যযুক্ত-এর সংখ্যা})}{n} = \frac{1}{n}\sum_{i=1}^{n} X_i = \bar{X} \quad(\text{§৪.১ অনুসারে}). $$ এখন §৪.২-এর linearity প্রয়োগ করে: $$ \mathbb{E}[\hat{p}] = \mathbb{E}[\bar{X}] = \frac{1}{n}\sum_{i=1}^{n}\mathbb{E}[X_i] = \frac{1}{n}\,(n p) = p. $$ অর্থাৎ \(\hat{p}\) গড়ে ঠিক \(p\) দেয় — কোনো systematic ঝোঁক নেই, তাই এটি unbiased estimator। (টীকা: কঠোরভাবে without-replacement SRS-এ \(X_i\)-রা সামান্য পরস্পর-নির্ভর; কিন্তু linearity-of-expectation independence (স্বাধীনতা) ছাড়াই খাটে, তাই unbiasedness অক্ষুণ্ন থাকে। নির্ভরশীলতা শুধু variance-কে প্রভাবিত করে — সেটি পরবর্তী অং