পাঠ ৫১ · ৫৭-এর মধ্যে · মডিউল ১১
Home / Courses / Numerical Methods / সেনসিটিভিটি অ্যানালাইসিস

সেনসিটিভিটি অ্যানালাইসিস ও মন্টে কার্লো এরর এস্টিমেশন

Sensitivity Analysis & Monte Carlo Error Estimation
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • সেনসিটিভিটি অ্যানালাইসিসের ধারণা এবং কেন এটি L50-এর ফরওয়ার্ড/ব্যাকওয়ার্ড এররের স্বাভাবিক সম্প্রসারণ
  • random.gauss দিয়ে ফিক্সড-সিড মন্টে কার্লো সিমুলেশন লেখা এবং statistics.mean/ statistics.stdev দিয়ে আউটপুট-স্প্রেড পরিমাপ করা
  • দুটো সত্যিকারের ডেমোতে দেখা — কীভাবে ভিন্ন সমীকরণ একই ইনপুট-অনিশ্চয়তাকে ভিন্নভাবে আউটপুটে প্রোপাগেট করে (রিলেটিভ সেনসিটিভিটির ধারণা)
  • মন্টে কার্লো (সিমুলেশন-ভিত্তিক) বনাম অ্যানালিটিক্যাল (ডেরিভেটিভ-ভিত্তিক) সেনসিটিভিটি অনুমানের তুলনা

১ · সেনসিটিভিটি অ্যানালাইসিস কী এবং কেন এটি দরকার

বাস্তব-বিশ্বের ইনপুট কখনোই একদম নিখুঁত হয় না — একটি মাপা দৈর্ঘ্য, একটি সেন্সর রিডিং, একটি অনুমিত প্যারামিটার — সবকিছুতেই কিছু না কিছু অনিশ্চয়তা (uncertainty) থাকে। প্রশ্ন হলো — এই ছোট ইনপুট-অনিশ্চয়তা একটি গণনার মধ্য দিয়ে গিয়ে আউটপুটে কতটা অনিশ্চয়তা তৈরি করে? এটাই সেনসিটিভিটি অ্যানালাইসিসSensitivity analysisইনপুটের একটি ছোট পরিবর্তন/অনিশ্চয়তা, একটি গণনার আউটপুটে কতটা পরিবর্তন/অনিশ্চয়তা তৈরি করে তার পদ্ধতিগত অধ্যয়ন। — L50-এ আমরা একটি একক রুট-ফাইন্ডিং সমস্যায় এই ধারণা দেখেছি (ডেরিভেটিভ দিয়ে); এই পাঠে সেই ধারণাটাকে আরও সাধারণ, বাস্তবসম্মত পরিস্থিতিতে প্রসারিত করা হচ্ছে, যেখানে ফাংশনটি জটিল হতে পারে বা ডেরিভেটিভ হাতে বের করা কঠিন হতে পারে।

২ · মন্টে কার্লো এরর এস্টিমেশন — সিমুলেশন দিয়ে সেনসিটিভিটি মাপা

মন্টে কার্লো পদ্ধতিMonte Carlo methodএলোমেলো (random) স্যাম্পলিং বহুবার পুনরাবৃত্তি করে একটি গাণিতিক ফলাফল আনুমানিকভাবে বের করার পরিসংখ্যানগত কৌশল। -এর ধারণাটা সরল: গাণিতিক ডেরিভেটিভ বা বদ্ধ-ফর্ম সূত্র ছাড়াই, শুধু ইনপুটকে বহুবার এলোমেলোভাবে পার্টার্ব করে (একটি বাস্তবসম্মত অনিশ্চয়তা-বিতরণ থেকে স্যাম্পল করে, যেমন গসিয়ান/নরমাল ডিস্ট্রিবিউশন), প্রতিবার আউটপুট গণনা করে, তারপর সেই আউটপুটগুলোর প্রকৃত স্ট্যান্ডার্ড ডেভিয়েশন মাপা — এটাই আউটপুটের অনিশ্চয়তার একটি বাস্তবসম্মত অনুমান। ধাপগুলো:

১. পার্টার্ব
random.gauss(nominal, uncertainty) দিয়ে ইনপুটের হাজার হাজার এলোমেলো স্যাম্পল তৈরি করো।
২. গণনা
প্রতিটি স্যাম্পলের জন্য আসল গণনাটা (যেকোনো জটিলতার) চালাও এবং আউটপুট সংরক্ষণ করো।
৩. পরিসংখ্যান
statistics.mean ও statistics.stdev দিয়ে আউটপুট-স্যাম্পলগুলোর real স্প্রেড মাপো।

ফিক্সড সিড (random.seed(42)) ব্যবহার করা জরুরি — এটি নিশ্চিত করে প্রতিবার কোড চালালে ঠিক একই এলোমেলো স্যাম্পলগুলো তৈরি হয়, ফলাফল রিপ্রোডিউসিবল (পুনরুৎপাদনযোগ্য) থাকে, যা ডিবাগিং ও তুলনার জন্য অপরিহার্য।

৩ · ডেমো ১ — একটি দোলকের (pendulum) দোলনকাল-এ দৈর্ঘ্য-অনিশ্চয়তার প্রভাব

একটি সরল দোলকের দোলনকাল (period) নির্ভর করে তার দৈর্ঘ্য L-এর বর্গমূলের উপর:

$$ T = 2\pi\sqrt{\frac{L}{g}} $$

ধরা যাক আমরা L মাপি 2.0 মিটার হিসেবে, কিন্তু মাপার যন্ত্রের অনিশ্চয়তা (স্ট্যান্ডার্ড ডেভিয়েশন) 0.05 মিটার। নিচের কোড সেলে L-কে ১০,০০০ বার random.gauss দিয়ে পার্টার্ব করে প্রতিবার T গণনা করা হয়েছে, এবং ফলাফলের real mean ও stdev বের করা হয়েছে — তুলনার জন্য ডেরিভেটিভ-ভিত্তিক (অ্যানালিটিক্যাল) আনুমানিক সূত্রও পাশাপাশি গণনা করা হয়েছে।

Python
import random
import statistics
import math

def pendulum_period(L, g=9.8):
    return 2 * math.pi * math.sqrt(L / g)

L_nominal = 2.0        # মিটার
L_uncertainty = 0.05    # মাপার অনিশ্চয়তা (stdev, মিটার)

random.seed(42)  # ফিক্সড সিড -- রিপ্রোডিউসিবিলিটির জন্য
N = 10000
outputs = []
for _ in range(N):
    L_sample = random.gauss(L_nominal, L_uncertainty)
    outputs.append(pendulum_period(L_sample))

mean_T = statistics.mean(outputs)
stdev_T = statistics.stdev(outputs)
nominal_T = pendulum_period(L_nominal)

print(f"নমিনাল T (L = {L_nominal} এ)        = {nominal_T:.10f}")
print(f"মন্টে কার্লো mean T ({N} স্যাম্পল)   = {mean_T:.10f}")
print(f"মন্টে কার্লো stdev T                = {stdev_T:.10f}")
print()

# তুলনার জন্য: ডেরিভেটিভ-ভিত্তিক আনুমানিক (অ্যানালিটিক্যাল) সেনসিটিভিটি
dT_dL = math.pi / math.sqrt(L_nominal * 9.8)
predicted_stdev = abs(dT_dL) * L_uncertainty
print(f"dT/dL (নমিনাল L-এ)                  = {dT_dL:.10f}")
print(f"পূর্বাভাসিত stdev = |dT/dL| * L_uncertainty = {predicted_stdev:.10f}")
print()

rel_input = L_uncertainty / L_nominal
rel_output = stdev_T / mean_T
print(f"আপেক্ষিক ইনপুট অনিশ্চয়তা (L_uncertainty/L)  = {rel_input:.6f}")
print(f"আপেক্ষিক আউটপুট অনিশ্চয়তা (stdev_T/mean_T) = {rel_output:.6f}")

    
মন্টে কার্লো stdev 0.0354779737, আর ডেরিভেটিভ-ভিত্তিক পূর্বাভাসিত stdev 0.0354806724 — দুটো প্রায় হুবহু মিলে যায় (ছোট পার্টার্বেশনের জন্য দুটো পদ্ধতি একই উত্তর দেয়, যা মন্টে কার্লো পদ্ধতির শুদ্ধতা যাচাই করে)। কিন্তু আসল আকর্ষণীয় ফলাফল হলো আপেক্ষিক অনিশ্চয়তা: ইনপুটে ২.৫% অনিশ্চয়তা (0.025) থাকলেও, আউটপুটে মাত্র ~১.২৫% (0.0125) অনিশ্চয়তা তৈরি হয় — অর্থাৎ বর্গমূল-ভিত্তিক সম্পর্ক ইনপুট-অনিশ্চয়তাকে অর্ধেক করে দেয় (কারণ T ∝ √L-এর আপেক্ষিক সেনসিটিভিটি ঠিক 0.5)।

৪ · ডেমো ২ — যখন সমীকরণ ইনপুট-অনিশ্চয়তা বাড়িয়ে দেয়

সব সমীকরণ ইনপুট-অনিশ্চয়তা কমায় না — কিছু সমীকরণ সেটাকে বাড়িয়ে দেয়। নিচের কোড সেলে ঠিক একই L_nominal ও L_uncertainty ব্যবহার করে, কিন্তু এবার V = L³ (যেমন একটি ঘনকের আয়তন, দৈর্ঘ্যের সাথে ঘন-সম্পর্কিত) গণনা করা হয়েছে।

Python
import random
import statistics

def cube_volume(L):
    return L ** 3   # যেমন একটি ঘনকের আয়তন

L_nominal = 2.0
L_uncertainty = 0.05

random.seed(42)  # একই সিড, একই স্যাম্পল -- তুলনা ন্যায্য রাখতে
N = 10000
outputs = [cube_volume(random.gauss(L_nominal, L_uncertainty)) for _ in range(N)]

mean_V = statistics.mean(outputs)
stdev_V = statistics.stdev(outputs)
nominal_V = cube_volume(L_nominal)

print(f"নমিনাল V (L = {L_nominal} এ) = {nominal_V:.10f}")
print(f"মন্টে কার্লো mean V           = {mean_V:.10f}")
print(f"মন্টে কার্লো stdev V           = {stdev_V:.10f}")
print()

rel_input = L_uncertainty / L_nominal
rel_output = stdev_V / mean_V
print(f"আপেক্ষিক ইনপুট অনিশ্চয়তা  = {rel_input:.6f}")
print(f"আপেক্ষিক আউটপুট অনিশ্চয়তা = {rel_output:.6f}")
print(f"অনুপাত (আউটপুট/ইনপুট)     = {rel_output / rel_input:.6f}")

    
এবার আপেক্ষিক আউটপুট অনিশ্চয়তা 0.074974 — আপেক্ষিক ইনপুট অনিশ্চয়তা (0.025)-এর প্রায় ৩ গুণ (অনুপাত ~2.999)। এটা কাকতালীয় নয় — V = L³ সমীকরণে পাওয়ার (exponent) হলো 3, এবং যেকোনো y = xⁿ ধরনের সম্পর্কের জন্য আপেক্ষিক আউটপুট অনিশ্চয়তা ≈ n × আপেক্ষিক ইনপুট অনিশ্চয়তা (ছোট পার্টার্বেশনের জন্য)। বর্গমূলের ক্ষেত্রে n = 0.5 (অনিশ্চয়তা কমায়), ঘনকের ক্ষেত্রে n = 3 (অনিশ্চয়তা বাড়ায়) — এটাই একটি গণনার "সেনসিটিভিটি" পরিমাপ করার একটি ব্যবহারিক উপায়।
মূল কথা · Key takeaway

মন্টে কার্লো এরর এস্টিমেশন — ইনপুট বহুবার এলোমেলোভাবে পার্টার্ব করে আউটপুটের real স্প্রেড পরিসংখ্যানগতভাবে মাপা — L50-এর ডেরিভেটিভ-ভিত্তিক সেনসিটিভিটি ধারণাকে যেকোনো জটিলতার গণনায় (এমনকি যেখানে ডেরিভেটিভ বের করা কঠিন বা অসম্ভব) প্রয়োগযোগ্য করে তোলে। এটাই বাস্তব ইঞ্জিনিয়ারিং ও ফাইন্যান্সের (M12/L53-L54) অনিশ্চয়তা-বিশ্লেষণের একটি মূল হাতিয়ার — পরের পাঠ (L52) এই কোর্সের সব মেথডকে একটি সিদ্ধান্ত-কাঠামোয় একত্র করবে।

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

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

প্র ০১ ডেমো ১-এ (দোলক) আপেক্ষিক আউটপুট অনিশ্চয়তা ইনপুটের চেয়ে ছোট, কিন্তু ডেমো ২-এ (কিউব) তা বড়। এই পার্থক্যের গাণিতিক কারণ কী?

দোলকের সূত্র T ∝ L^0.5 — এক্সপোনেন্ট (n) মাত্র 0.5, যা 1-এর চেয়ে ছোট, তাই ইনপুট-অনিশ্চয়তা "সংকুচিত" হয়ে আউটপুটে যায়। কিউব সূত্র V ∝ L^3 — এক্সপোনেন্ট 3, যা 1-এর চেয়ে অনেক বড়, তাই ইনপুট-অনিশ্চয়তা "বিবর্ধিত" (amplified) হয়ে আউটপুটে যায়। সাধারণভাবে, y = xⁿ-এর আপেক্ষিক সেনসিটিভিটি ঠিক n।

প্র ০২ ডেরিভেটিভ-ভিত্তিক (অ্যানালিটিক্যাল) সেনসিটিভিটি অনুমান থাকতে, মন্টে কার্লো পদ্ধতির বাড়তি সুবিধা কী?

ডেরিভেটিভ-ভিত্তিক অনুমান শুধু ছোট পার্টার্বেশনে নির্ভুল (লিনিয়ার আনুমানিকতা), এবং একটি সাফসুতরো, ডিফারেনশিয়েবল বদ্ধ-ফর্ম সূত্র লাগে। মন্টে কার্লো পদ্ধতি এমন যেকোনো গণনার সাথে কাজ করে — একটি সম্পূর্ণ অ্যালগরিদম (যেমন একটি ITERATIVE সলভার, M2-M9-এর যেকোনো মেথড), একটি নন-ডিফারেনশিয়েবল ফাংশন, অথবা একাধিক ইনপুটের জটিল ইন্টার‌অ্যাকশন — কোনো ডেরিভেটিভ সূত্র বের করার দরকার নেই, শুধু বহুবার চালিয়ে ফলাফল পর্যবেক্ষণ করলেই চলে।

প্র ০৩ কোড সেলে random.seed(42) ব্যবহার না করলে কী সমস্যা হতে পারত?

সিড ছাড়া প্রতিবার কোড চালালে ভিন্ন ভিন্ন এলোমেলো স্যাম্পল তৈরি হতো, ফলে mean/stdev সামান্য ভিন্ন হতো প্রতিবার — ফলাফল রিপ্রোডিউসিবল থাকত না। শিক্ষামূলক বা ডিবাগিং প্রেক্ষাপটে (এবং দুটো ভিন্ন সমীকরণের ন্যায্য তুলনা করতে, যেমন ডেমো ১ ও ২-এ একই সিড ব্যবহার করে একই এলোমেলো L-স্যাম্পলগুলো পুনর্ব্যবহার করা হয়েছে) একটি ফিক্সড সিড অপরিহার্য।

অনুশীলন

  1. চিন্তা করুন: ডেমো ১-এ যদি L_uncertainty-কে 0.05 থেকে 0.10-তে (দ্বিগুণ) পরিবর্তন করা হয়, তাহলে মন্টে কার্লো stdev_T মোটামুটি কী অনুপাতে বদলাবে বলে আপনার ধারণা?

    যেহেতু ছোট পার্টার্বেশনের জন্য সম্পর্কটা প্রায় লিনিয়ার (stdev_T ≈ |dT/dL| × L_uncertainty), ইনপুট অনিশ্চয়তা দ্বিগুণ করলে আউটপুট stdev-ও মোটামুটি দ্বিগুণ হওয়ার কথা।

  2. পরীক্ষা করুন: ডেমো ১-এর কোড সেলে L_uncertainty = 0.05-কে L_uncertainty = 0.10-এ পরিবর্তন করে Run চেপে দেখুন stdev_T-এর real মান কী দাঁড়ায় — আপনার অনুমান মিলল কিনা যাচাই করুন।

    L_uncertainty = 0.10-তে মন্টে কার্লো stdev_T ≈ 0.071017 — আগের 0.05-এর stdev (0.035478)-এর প্রায় ঠিক দ্বিগুণ। এটাই নিশ্চিত করে ছোট পার্টার্বেশনের জন্য output uncertainty ইনপুট uncertainty-এর সাথে প্রায় লিনিয়ারলি স্কেল করে — একটি বাস্তব, পুনরুৎপাদনযোগ্য (ফিক্সড সিডের কারণে) ফলাফল।

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

আগের পাঠ
ফরওয়ার্ড ও ব্যাকওয়ার্ড এরর অ্যানালাইসিস