Benchmarking ও Statistical Analysis
Benchmarking and Statistical Analysis
advanced-architecture module-এর benchmarking লেসন CPU-microbenchmark-এর engineering সমাধান দিয়েছিল — এই লেসন সেই একই সংখ্যাগুলোর পেছনের পরিসংখ্যান ব্যাখ্যা করে, সাধারণভাবে: confidence interval, p-value-এর প্রকৃত অর্থ, আর bootstrap resampling — যেকোনো research claim-এ প্রযোজ্য, শুধু CPU benchmark-এ না।
আগে এটা বুঝি
advanced-architecture/benchmarking-methodology লেসনে আমরা দেখেছিলাম
দুইটা algorithm-এর mean latency (10.2ms বনাম 10.4ms) তুলনা করার
সময় confidence interval overlap করলে “A দ্রুত” দাবি করা বিপজ্জনক।
সেই লেসনটা মূলত engineering-কেন্দ্রিক ছিল — warm-up, dead-code
elimination, NUMA pinning, CPU governor — কীভাবে একটা পরিষ্কার
সংখ্যা পাওয়া যায় তার উপর।
এই লেসন একটা ধাপ পেছনে গিয়ে জিজ্ঞাসা করে: সেই সংখ্যাটা রিপোর্ট করার পরও, সিদ্ধান্তটা আসলে কতটা নির্ভরযোগ্য? এটা শুধু CPU microbenchmark-এর প্রশ্ন না — database throughput তুলনা, দুইটা ML model-এর accuracy তুলনা, নেটওয়ার্ক protocol-এর latency তুলনা — যেকোনো জায়গায় “A বনাম B, কোনটা ভালো” প্রশ্নের পেছনে ঠিক এই একই পরিসংখ্যান লাগে। আর এখানেই সবচেয়ে বেশি সৎ গবেষকও ভুল করেন — p-value-এর অর্থ ভুল বোঝা প্রায় সর্বজনীন।
মূল ধারণা
Mean, Median, Percentile — কখন কোনটা বলে সত্যি কথা
benchmarking-methodology লেসনের সেই CPU-নির্দিষ্ট উদাহরণটা মনে
করুন — outlier-এর কারণে mean বিভ্রান্তিকর হয়ে যাওয়া। এখানে একটা
ভিন্ন, বেশি সাধারণ প্রেক্ষাপটে দেখি: কেন latency-জাতীয় ডেটা
প্রায় সবসময়ই এই সমস্যায় ভোগে, শুধু কাকতালীয়ভাবে না।
একটা distributed system-এর ১০০টা request-এর response time (মিলিসেকেন্ডে), sorted:
৯৫টা request: ১৮-২৫ ms-এর মধ্যে (স্বাভাবিক processing)
৩টা request: ৮০-১১০ ms (GC pause / retry)
২টা request: ৪৫০-৬০০ ms (network timeout + retry)এই distribution right-skewed — একটা লম্বা লেজ ডানদিকে। এটা
কাকতালীয় না; latency-জাতীয় ডেটা প্রায় সবসময়ই এভাবে skewed হয়,
কারণ ব্যর্থতার কারণগুলো (queueing, retry, GC pause, network hiccup)
সবসময় সময় যোগ করে, কখনো বিয়োগ করে না — একটা request -500ms
সময় নিতে পারে না, কিন্তু +500ms নিতে পারে।
Mean (42.1ms) কাউকেই প্রতিনিধিত্ব করে না — ৯৫% user-এর অভিজ্ঞতা
(~২০ms)-এর চেয়ে দ্বিগুণেরও বেশি, অথচ সবচেয়ে খারাপ অভিজ্ঞতা
(৬০০ms)-এর চেয়ে অনেক কম। এটা একটা কাল্পনিক সংখ্যা যা কারো
বাস্তব অভিজ্ঞতা না।
Median (21ms) সংখ্যাগরিষ্ঠ user-এর অভিজ্ঞতা সঠিকভাবে ধরে —
কিন্তু সেই ৫% user-কে সম্পূর্ণ আড়াল করে দেয় যারা ভয়াবহ অভিজ্ঞতা
পাচ্ছেন।
p99 (~580ms) সেই লুকানো ৫%-এর গল্প বলে — এটাই advanced-architecture/benchmarking-methodology
লেসনের “Tail at Scale” আলোচনার ঠিক সেই ধারণা, শুধু এখানে সাধারণ
research-context-এ প্রয়োগ করা হচ্ছে।
Variance ও Standard Deviation — “কতটা ছড়ানো” মাপা
Mean/median শুধু “কেন্দ্র” বলে — distribution কতটা ছড়ানো তা বলে না। এটা মাপে variance:
(s = sample standard deviation — variance-এর বর্গমূল, কারণ variance-এর
একক মূল ডেটার বর্গ, যা সরাসরি বোঝা কঠিন; s একই এককে ফিরিয়ে
আনে)
দুইটা algorithm একই mean দিতে পারে, সম্পূর্ণ ভিন্ন s নিয়ে:
| Algorithm | Mean | s | ব্যাখ্যা |
|---|---|---|---|
| A | 10.0 ms | 0.3 ms | প্রায় সবসময় 9.7-10.3ms-এর মধ্যে — predictable |
| B | 10.0 ms | 4.2 ms | মাঝে মাঝে 2ms, মাঝে মাঝে 18ms — অস্থির |
দুইটার “গড়” identical, কিন্তু একটা production system-এ B ব্যবহার করা অনেক বেশি ঝুঁকিপূর্ণ — latency SLA guarantee দেওয়া প্রায় অসম্ভব। শুধু mean তুলনা করলে এই পার্থক্যটা সম্পূর্ণ অদৃশ্য থেকে যায়।
Confidence Interval — একটা সম্পূর্ণ সাংখ্যিক উদাহরণ
দুইটা ML model-এর accuracy তুলনা করছি, 10-fold cross-validation-এ
(প্রতিটা fold একটা independent measurement):
Model A accuracy (১০ fold): [0.842, 0.851, 0.839, 0.847, 0.855,
0.838, 0.849, 0.844, 0.846, 0.841]
Model B accuracy (১০ fold): [0.858, 0.849, 0.862, 0.855, 0.847,
0.860, 0.851, 0.856, 0.853, 0.859]Model A: mean = 0.8452, s = 0.0057
Model B: mean = 0.8550, s = 0.0048
Standard error (SE) — mean-এর নিজস্ব uncertainty, sample size দিয়ে সংকুচিত:
95% confidence interval (normal approximation, 1.96 × SE):
দুইটা interval overlap করে না (0.8487 < 0.8521) — এই ডেটায়
Model B-র accuracy পরিসংখ্যানগতভাবে তাৎপর্যপূর্ণভাবে বেশি বলা যায়।
ভেতরে কী ঘটছে
P-value — সবচেয়ে ভুল-বোঝা সংখ্যা বিজ্ঞানে
সঠিক সংজ্ঞা: ধরে নিন null hypothesis সত্যি (অর্থাৎ, ধরে নিন Model A আর Model B-র মধ্যে কোনো real পার্থক্য নেই — উভয়ের সত্যিকার accuracy সমান, observed পার্থক্যটা নিছক sampling noise)। এই ধারণার অধীনে, এত বড়, বা এর চেয়ে বেশি চরম পার্থক্য observe করার সম্ভাবনা কত — এটাই p-value।
p < 0.05 মানে: “যদি সত্যিই কোনো পার্থক্য না থাকত, তাহলে নিছক
কাকতালীয়ভাবে এই মাপের (বা তার চেয়ে বড়) পার্থক্য দেখার সম্ভাবনা
5%-এর কম হতো।” এতটাই কম যে, প্রচলিতভাবে আমরা H₀ (কোনো পার্থক্য
নেই) প্রত্যাখ্যান করি।
যে ভুলগুলো সবাই করে
“p < 0.05 মানে 'এই effect আসল হওয়ার সম্ভাবনা 95%' অথবা 'null hypothesis সত্যি হওয়ার সম্ভাবনা মাত্র 5%'।”
এটা p-value-এর সবচেয়ে সাধারণ, সবচেয়ে বিপজ্জনক ভুল ব্যাখ্যা — এমনকি অভিজ্ঞ গবেষকরাও প্রায়ই এই ভুল করেন। American Statistical Association 2016 সালে একটা আনুষ্ঠানিক বিবৃতি প্রকাশ করে এই ভুল ব্যাখ্যার বিরুদ্ধে সতর্ক করতে বাধ্য হয়েছিল।
সমস্যাটা কোথায়: p-value হিসাব হয় ধরে নিয়ে H₀ সত্যি
(P(data | H₀))। কিন্তু “effect আসল হওয়ার সম্ভাবনা” প্রশ্ন করছে
উল্টো দিকের কিছু (P(H₀ | data)) — আর এই দুইটা জিনিস সাধারণত
সমান না (Bayes’ theorem-এর মৌলিক শিক্ষা, mathematics/probability
লেসনে দেখা)।
একটা সংখ্যাগত উদাহরণ দিয়ে বোঝা যাক — একটা medical test-এর
সাদৃশ্যে: ধরুন একটা রোগ জনসংখ্যার মাত্র 1%-এর আছে (এটাই এখানে
“null hypothesis সত্যি হওয়ার prior সম্ভাবনা” — বেশিরভাগ hypothesis-ই
প্রথমে ভুল হয়, একটা এলোমেলোভাবে বাছা exploratory research-এ)। একটা
test-এর false positive rate = 5% (ঠিক p < 0.05 থ্রেশহোল্ডের
সমতুল্য), আর true positive rate = 80%।
10,000 জনের মধ্যে: 100 জন সত্যিই আক্রান্ত (80 জন positive
ধরা পড়বে), 9,900 জন সুস্থ (5% অর্থাৎ 495 জন ভুলভাবে
positive ধরা পড়বে)। মোট positive result: 80 + 495 = 575, তার
মধ্যে সত্যিকার আক্রান্ত মাত্র 80।
5% false positive rate সত্ত্বেও, একটা positive result সত্যি
হওয়ার সম্ভাবনা মাত্র 14% — কারণ base rate (রোগের প্রকৃত প্রাদুর্ভাব)
কম। ঠিক একইভাবে, একটা p < 0.05 ফলাফল “effect সত্যি হওয়ার ৯৫%
সম্ভাবনা” বোঝায় না — সেটা নির্ভর করে effect-টা আগে থেকে কতটা
সম্ভাব্য ছিল (prior), যা p-value নিজে হিসাবেই ধরে না।
সঠিক ভাষা: “যদি সত্যিই কোনো পার্থক্য না থাকত, এই ডেটা দেখার
সম্ভাবনা 5%-এর কম” — p-value শুধু এইটুকুই বলে, তার বেশি কিছু না।
মূল ধারণা
Bootstrap Resampling — distribution ধরে না নিয়েও CI বের করা
উপরের normal-approximation CI (mean ± 1.96 × SE) একটা assumption
করে — ডেটা প্রায় normal distribution অনুসরণ করে। কিন্তু আমরা এই
লেসনেই দেখেছি latency-জাতীয় ডেটা skewed, normal না। Median বা
p99-এর মতো রাশির জন্য তো কোনো সহজ closed-form CI সূত্রই নেই।
Bootstrap এই সমস্যা সমাধান করে সম্পূর্ণ ভিন্নভাবে — assumption ছাড়াই, শুধু computation দিয়ে:
- আসল samplen টা observed measurement, যেমন ১০০টা latency
- Resampleএকই n আকারের একটা নতুন sample বানান — আসল sample থেকে replacement-সহ randomly বেছে (একই মান একাধিকবার আসতে পারে)
- Statistic হিসাব করুনএই resample-এর উপর যে statistic চান (median, mean, p99) তা হিসাব করুন
- পুনরাবৃত্তি করুনধাপ ২-৩, কয়েক হাজার বার (যেমন B=10,000)
- CI বের করুনসেই কয়েক হাজার statistic-এর 2.5th ও 97.5th percentile-ই 95% CI
কেন এটা কাজ করে (স্বজ্ঞাত ব্যাখ্যা): আসল sample-টাই সত্যিকার population সম্পর্কে আমাদের সেরা তথ্য। বারবার সেই sample থেকে replacement-সহ নতুন sample বানিয়ে, আমরা কার্যকরভাবে অনুকরণ করছি “যদি আমরা আবার আসল population থেকে নতুন sample নিতাম, তাহলে statistic-টা কতটা বদলাতে পারত” — কোনো normal distribution বা অন্য কোনো গাণিতিক সূত্রের উপর নির্ভর না করেই।
নিজে চালিয়ে দেখুন
Bootstrap দিয়ে Median-এর Confidence Interval — একটা কার্যকর, চালানোর-মতো উদাহরণ
import random
import statistics
random.seed(7)
def make_skewed_latencies(n=200):
"""বাস্তবসম্মত right-skewed latency ডেটা — বেশিরভাগ দ্রুত, কিছু ধীর।"""
data = []
for _ in range(n):
if random.random() < 0.95:
data.append(random.gauss(20, 3)) # স্বাভাবিক request
else:
data.append(random.gauss(300, 80)) # tail — GC/retry
return [max(1.0, x) for x in data]
def bootstrap_ci(data, statistic_fn, num_resamples=10000, ci=0.95):
n = len(data)
boot_stats = []
for _ in range(num_resamples):
resample = [data[random.randrange(n)] for _ in range(n)]
boot_stats.append(statistic_fn(resample))
boot_stats.sort()
lower_idx = int((1 - ci) / 2 * num_resamples)
upper_idx = int((1 + ci) / 2 * num_resamples)
return boot_stats[lower_idx], boot_stats[upper_idx]
latencies = make_skewed_latencies()
median_val = statistics.median(latencies)
mean_val = statistics.fmean(latencies)
median_ci = bootstrap_ci(latencies, statistics.median)
mean_ci = bootstrap_ci(latencies, statistics.fmean)
def p95(sample):
s = sorted(sample)
return s[int(len(s) * 0.95)]
p95_val = p95(latencies)
p95_ci = bootstrap_ci(latencies, p95)
print(f"Median : {median_val:6.2f} ms 95% bootstrap CI = [{median_ci[0]:.2f}, {median_ci[1]:.2f}]")
print(f"Mean : {mean_val:6.2f} ms 95% bootstrap CI = [{mean_ci[0]:.2f}, {mean_ci[1]:.2f}]")
print(f"p95 : {p95_val:6.2f} ms 95% bootstrap CI = [{p95_ci[0]:.2f}, {p95_ci[1]:.2f}]")Illustrative output:
Median : 20.31 ms 95% bootstrap CI = [19.71, 20.94]
Mean : 33.87 ms 95% bootstrap CI = [26.42, 43.19]
p95 : 61.44 ms 95% bootstrap CI = [24.86, 189.32]তিনটা পর্যবেক্ষণ:
১. Median-এর CI সংকীর্ণ — কারণ median একটা robust statistic, কিছু চরম outlier দিয়ে খুব বেশি প্রভাবিত হয় না, তাই resample-জুড়ে স্থিতিশীল থাকে।
২. Mean-এর CI অনেক চওড়া (26.42 থেকে 43.19) — কারণ mean
সরাসরি outlier-এর দ্বারা প্রভাবিত, resample-এ কখনো বেশি tail-value
পড়ে যায় কখনো কম, ফলে mean resample-জুড়ে অনেক বেশি ওঠানামা করে।
এটাই সংখ্যায় দেখা যায় mean কেন এই ধরনের ডেটায় কম নির্ভরযোগ্য।
৩. p95-এর CI সবচেয়ে চওড়া (24.86 থেকে 189.32) — tail
percentile সবচেয়ে কম data point দিয়ে নির্ধারিত হয় (মাত্র ~5%
data), তাই সবচেয়ে বেশি uncertain। এটা একটা গুরুত্বপূর্ণ, প্রায়ই
উপেক্ষিত ব্যবহারিক শিক্ষা: p99 claim করতে p50 claim-এর চেয়ে
অনেক বেশি sample লাগে, নির্ভরযোগ্য CI পেতে।
Bootstrap resampling normal-distribution assumption ছাড়াই median-এর মতো একটা রাশির জন্য CI দেয় — এমনকি skewed distribution-এও নির্ভরযোগ্যভাবে কাজ করে, যেখানে classic SE-ভিত্তিক CI ভুল হতে পারে।
নিজে বানান
Bootstrap দিয়ে দুইটা System তুলনা করা
- দুইটা ডেটাসেটের bootstrap CI হিসাব করুন (উপরের function পুনর্ব্যবহার করে)
- দুইটা CI overlap করে কি না স্বয়ংক্রিয়ভাবে যাচাই করুন
- সেই সাথে একটা "bootstrap difference" পদ্ধতি প্রয়োগ করুন — সরাসরি পার্থক্যের CI
- দুইটা পদ্ধতির সিদ্ধান্ত মিলছে কি না তুলনা করুন
শুধু দুইটা আলাদা CI-এর overlap দেখার চেয়ে একটা পরিসংখ্যানগতভাবে শক্তিশালী উপায় — সরাসরি পার্থক্যের bootstrap distribution বানানো:
import random
import statistics
random.seed(3)
def bootstrap_diff_ci(data_a, data_b, statistic_fn, num_resamples=10000, ci=0.95):
"""A - B পার্থক্যের bootstrap CI — সরাসরি, overlap-check-এর চেয়ে নির্ভুল।"""
n_a, n_b = len(data_a), len(data_b)
diffs = []
for _ in range(num_resamples):
resample_a = [data_a[random.randrange(n_a)] for _ in range(n_a)]
resample_b = [data_b[random.randrange(n_b)] for _ in range(n_b)]
diffs.append(statistic_fn(resample_a) - statistic_fn(resample_b))
diffs.sort()
lower_idx = int((1 - ci) / 2 * num_resamples)
upper_idx = int((1 + ci) / 2 * num_resamples)
return diffs[lower_idx], diffs[upper_idx]
# দুইটা algorithm-এর latency sample (illustrative)
algo_a = [random.gauss(22, 4) for _ in range(80)]
algo_b = [random.gauss(19, 4) for _ in range(80)]
diff_lo, diff_hi = bootstrap_diff_ci(algo_a, algo_b, statistics.median)
print(f"A-এর median: {statistics.median(algo_a):.2f} ms")
print(f"B-এর median: {statistics.median(algo_b):.2f} ms")
print(f"পার্থক্যের (A - B) 95% bootstrap CI: [{diff_lo:.2f}, {diff_hi:.2f}] ms")
if diff_lo > 0:
print("→ A পরিসংখ্যানগতভাবে ধীর (পার্থক্য সবসময় ধনাত্মক)")
elif diff_hi < 0:
print("→ A পরিসংখ্যানগতভাবে দ্রুত (পার্থক্য সবসময় ঋণাত্মক)")
else:
print("→ CI শূন্য অতিক্রম করে — তাৎপর্যপূর্ণ পার্থক্য প্রমাণিত হয়নি")Illustrative output:
A-এর median: 22.14 ms
B-এর median: 18.87 ms
পার্থক্যের (A - B) 95% bootstrap CI: [1.92, 4.61] ms
→ A পরিসংখ্যানগতভাবে ধীর (পার্থক্য সবসময় ধনাত্মক)কেন এই পদ্ধতি দুইটা আলাদা CI-এর overlap check-এর চেয়ে ভালো: দুইটা আলাদা CI দেখে “overlap নেই” সিদ্ধান্ত নেওয়া রক্ষণশীল (conservative) — এটা কখনো কখনো একটা সত্যিকার তাৎপর্যপূর্ণ পার্থক্য মিস করে ফেলে, কারণ এটা দুইটা independent uncertainty যোগ করে ফেলে দুইবার। সরাসরি পার্থক্যের bootstrap distribution বানালে এই সমস্যা হয় না — এটাই বাস্তব A/B testing platform (industry standard) যেভাবে করে।
নিজে বাড়ান:
num_resamplesকমিয়ে100করুন — CI কতটা অস্থির (run প্রতি ভিন্ন) হয়ে যায় দেখুন, আর কেন10,000+সাধারণত ব্যবহৃত হয়- একটা synthetic ক্ষেত্রে দুইটা distribution-এর সত্যিকার পার্থক্য
শূন্য বানিয়ে (একই parameter দিয়ে generate করে) — CI-টা কত শতাংশ
সময় সঠিকভাবে “শূন্য” অন্তর্ভুক্ত করে তা
1000বার পুনরাবৃত্তি করে পরীক্ষা করুন (এটাই CI-এর “coverage” যাচাই করার পদ্ধতি) - Normal-approximation CI (
mean ± 1.96×SE) আর bootstrap CI দুইটাই হিসাব করে skewed বনাম non-skewed ডেটায় তুলনা করুন — কোথায় তারা উল্লেখযোগ্যভাবে ভিন্ন ফল দেয়?
বাস্তব সিস্টেমে
যেখানে এই পরিসংখ্যান সিদ্ধান্ত নির্ধারণ করে
A/B testing platform-এর ইঞ্জিন। Netflix, Airbnb, Booking.com-এর মতো কোম্পানির internal experimentation platform-এর মূল হলো ঠিক এই লেসনের bootstrap ও CI গণনা, স্বয়ংক্রিয়ভাবে হাজার হাজার experiment-এ একসাথে প্রয়োগ করা — একজন product manager শুধু “কোনটা জিতেছে” দেখেন, কিন্তু নিচে চলছে এই একই bootstrap resampling।
ML paper-এ accuracy রিপোর্ট। ভালো ML paper শুধু “accuracy 85.5%”
লেখে না — cross-validation fold-জুড়ে standard deviation বা CI-ও
রিপোর্ট করে (এই লেসনের worked example ঠিক এই প্যাটার্ন অনুসরণ করে)।
এই CI ছাড়া একটা 0.1% improvement দাবি করা অর্থহীন — সেটা noise-এর
মধ্যেই পড়ে যেতে পারে।
Database/systems benchmark paper। সিরিয়াস venue-তে (VLDB, OSDI,
SOSP) reviewer এখন রুটিনভাবে জিজ্ঞাসা করেন error bar/CI কোথায় —
advanced-architecture/benchmarking-methodology লেসনে দেখা প্রতিটা
সতর্কতার সাথে এই লেসনের পরিসংখ্যান একসাথে ব্যবহৃত হয় একটা সম্পূর্ণ,
প্রতিরক্ষাযোগ্য claim বানাতে।
Continuous Integration-এ performance regression detection।
Rust compiler, Chromium-এর মতো বড় প্রজেক্ট প্রতি commit-এ automated
benchmark চালায় — bootstrap বা অনুরূপ পরিসংখ্যান দিয়ে সিদ্ধান্ত
নেয় একটা সামান্য সংখ্যাগত পার্থক্য সত্যিকার regression, নাকি CI-machine
noise। Naive threshold-ভিত্তিক rule ("5% ধীর হলেই fail") false
positive-এ ভরে যায়, এই কারণেই।
Base rate fallacy বাস্তব জগতে। এই লেসনের medical-test উদাহরণ
(p-value-এর ভুল ব্যাখ্যা বোঝাতে) নিজেই একটা বাস্তব সমস্যা — spam
filter, fraud detection, security intrusion detection সিস্টেমেও
একই ভুল ঘটে: একটা 1% false-positive-rate detector, বিরল ঘটনার
জন্য, প্রায়ই বেশিরভাগ alert-ই false positive তৈরি করে, যদি না
base rate বিবেচনা করা হয়।
বুঝেছেন কি না দেখুন
1একটা paper লিখেছে “p = 0.03, তাই আমাদের অনুসন্ধান 97% নিশ্চিত সত্য।”
এই বাক্যে কী ভুল আছে?
স্মরণ
এই বাক্যটা p-value-এর দুইটা সাধারণ ভুল ব্যাখ্যা একসাথে করছে।
প্রথমত, p = 0.03 মানে “যদি null hypothesis (কোনো effect নেই)
সত্যি হতো, তাহলে এই ডেটা (বা তার চেয়ে চরম) দেখার সম্ভাবনা 3%” —
এটা “আমাদের অনুসন্ধান সত্যি হওয়ার সম্ভাবনা” না। এই দুইটা সম্পূর্ণ
ভিন্ন conditional probability (P(data|H₀) বনাম P(H₀|data)),
আর এই লেসনের medical-test উদাহরণ দেখিয়েছে এই দুইটা অনেক দূরে থাকতে
পারে, base rate-এর উপর নির্ভর করে।
দ্বিতীয়ত, “97% নিশ্চিত” একটা confidence-এর ভাষা যা p-value
প্রদান করে না — p-value একটা binary-ধাঁচের threshold test-এর অংশ
(< 0.05 কি না), এটা কোনো “নিশ্চয়তার শতাংশ” না।
সঠিক ভাষা হতো: “null hypothesis সত্যি ধরে নিলে, এই মাপের পার্থক্য
কাকতালীয়ভাবে দেখার সম্ভাবনা 3%-এর কম — তাই আমরা null hypothesis
প্রত্যাখ্যান করছি প্রচলিত 0.05 থ্রেশহোল্ডে,” এবং এর সাথে effect
size ও CI যোগ করা, শুধু p-value একা না।
2কেন bootstrap CI-এ p99-এর CI প্রায় সবসময় median-এর CI-এর চেয়ে
অনেক চওড়া হয়? এটার একটা ব্যবহারিক পরিণতি কী পরের experiment ডিজাইন
করার সময়?
যুক্তি
Median একটা robust statistic — এটা নির্ধারিত হয় ডেটার “মাঝখানের”
মান দিয়ে, আর n টা ডেটা পয়েন্টের প্রায় অর্ধেকই এর কাছাকাছি থাকে।
প্রতিটা resample-এ median সামান্যই বদলায়, কারণ অনেক data point
মিলেই median নির্ধারণ করে।
p99 নির্ধারিত হয় সবচেয়ে কম সংখ্যক data point দিয়ে — মাত্র
সেরা 1% (একটা n=100 sample-এ, কার্যত একটা মাত্র point)। Bootstrap
resample-এ কোন point-টা সেই 1%-এ পড়বে তা প্রতিবার অনেক বদলে
যেতে পারে — ফলে resample-জুড়ে p99-এর মান অনেক বেশি ওঠানামা করে,
CI চওড়া হয়।
ব্যবহারিক পরিণতি: যদি কোনো experiment-এর লক্ষ্য p99 latency
নিয়ে একটা নির্দিষ্ট claim করা (যেমন “p99 20% কমেছে”), তাহলে median
নিয়ে একই claim-এর চেয়ে অনেক বেশি sample দরকার একটা সংকীর্ণ,
বিশ্বাসযোগ্য CI পেতে — এটা cs-theory/hypothesis-formation-and-experiment-design
লেসনের sample-size আলোচনার সরাসরি সম্প্রসারণ। Pre-registration
লেখার সময় p99-নির্ভর claim-এর জন্য উল্লেখযোগ্যভাবে বড় n ধরে
রাখা উচিত।
3দুইটা caching strategy-র median latency-র bootstrap CI: A =
[14.2, 15.8]ms, B = [15.1, 16.9]ms। এই দুইটা CI overlap করে
([15.1, 15.8])। এই অবস্থায় সঠিক উপসংহার কী, আর কী বলা উচিত না?
প্রয়োগ
[14.2, 15.8]ms, B = [15.1, 16.9]ms। এই দুইটা CI overlap করে
([15.1, 15.8])। এই অবস্থায় সঠিক উপসংহার কী, আর কী বলা উচিত না?সঠিক উপসংহার: “এই ডেটায় A আর B-র মধ্যে পরিসংখ্যানগতভাবে
তাৎপর্যপূর্ণ পার্থক্য পাওয়া যায়নি — যদিও A-এর point estimate
(14.2-15.8-এর মাঝামাঝি কোথাও) সংখ্যাগতভাবে B-এর চেয়ে কম, এই
পার্থক্যটা measurement noise-এর মধ্যেই পড়তে পারে।”
যা বলা উচিত না: “A দ্রুত” — শুধু point estimate ছোট হওয়াটা যথেষ্ট প্রমাণ না, এই লেসনের পুরো কেন্দ্রীয় বার্তা এটাই।
পরবর্তী পদক্ষেপ (একটা উপসংহারে না গিয়ে): এই লেসনের বিল্ড-ইট অংশের পরামর্শ অনুযায়ী, সরাসরি পার্থক্যের (A - B) bootstrap CI হিসাব করা উচিত — দুইটা আলাদা CI-এর overlap check-এর চেয়ে এটা বেশি নির্ভুল সিদ্ধান্ত দেয়, কারণ এতে দুইটা sample-এর মধ্যে সম্ভাব্য correlation বা ভিন্ন variance সরাসরি হিসাবে আসে। যদি পার্থক্যের CI-ও শূন্য অতিক্রম করে, তাহলে নিশ্চিতভাবে বলা যায় পার্থক্যটা তাৎপর্যপূর্ণ প্রমাণিত হয়নি — আর তখন sample size বাড়ানোই পরবর্তী যৌক্তিক পদক্ষেপ, নতুন metric খোঁজা না (যা p-hacking-এ নিয়ে যাবে)।
এরপর কী
আমরা এখন জানি কীভাবে একটা claim পরিসংখ্যানগতভাবে প্রতিরক্ষাযোগ্য করতে হয়। কিন্তু একটা প্রশ্ন এখনো বাকি: আপনার সহকর্মী, বা এক বছর পরের আপনি নিজে, যদি এই একই experiment আবার চালাতে চান — তারা কি একই ফলাফল পাবেন? Random seed, library version, hardware, এমনকি floating-point rounding-এর ছোট পার্থক্যও একটা “প্রতিরক্ষাযোগ্য” ফলাফলকে অপ্রতিরূপণযোগ্য করে দিতে পারে।
পরের লেসনে আমরা reproducibility-র প্রশ্নে ঢুকব — এটা কেন একটা প্রকৃত সংকট (crisis), reproducibility ও replicability-র পার্থক্য, আর আপনার নিজের কাজকে reproducible করার একটা বাস্তব checklist।
আরও পড়ুন
- Producing Wrong Data Without Doing Anything Obviously Wrong! — Todd Mytkowicz, Amer Diwan, Matthias Hauswirth, Peter F. Sweeney · ASPLOS 2009 — advanced-architecture module-এই আলোচিত, measurement bias-এর ক্লাসিক উদাহরণ
- An Introduction to the Bootstrap — Bradley Efron, Robert Tibshirani · Bootstrap resampling-এর মূল, প্রামাণ্য পাঠ্য
- The ASA Statement on p-Values: Context, Process, and Purpose — American Statistical Association · 2016 — p-value-এর অপব্যাখ্যা নিয়ে পরিসংখ্যানবিদদের আনুষ্ঠানিক, সর্বসম্মত সতর্কবার্তা