পাঠ ১৬ · ৩০-এর মধ্যে · মডিউল ৩

EDA — পদ্ধতিগত ভাবে

Exploratory data analysis
৮ মিনিট পড়া মাঝারি · Intermediate Pandas, ydata-profiling

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

  • EDA-র উদ্দেশ্য — কেন মডেলের আগে ডেটা explore করতে হয়
  • Univariate, bivariate ও multivariate analysis-এর কৌশল
  • প্রতিটি column-এ কী প্রশ্ন করতে হবে — checklist
  • ydata-profiling দিয়ে স্বয়ংক্রিয় EDA report তৈরি
  • Bangladesh business context-এ EDA-র উদাহরণ

১ · EDA কী এবং কেন

১৯৭৭ সালে Princeton-এর গণিতবিদ John Tukey "Exploratory Data Analysis" বইতে একটি বৈপ্লবিক ধারণা আনলেন — ডেটা পেলে সরাসরি hypothesis test বা মডেলে ঢুকে যাওয়া ভুল। আগে চোখ দিয়ে, হাত দিয়ে, প্লট দিয়ে ডেটাকে "বোঝা" দরকার। এটাই EDAExploratory Data Analysisডেটাকে graphical ও summary-statistics-এর মাধ্যমে detect করার পদ্ধতি — pattern, outlier, missing, distribution আবিষ্কার। মডেলিং-এর আগে অপরিহার্য পদক্ষেপ।।

আজও Daraz, bKash, Pathao-র data team-এর প্রতিটি project শুরু হয় EDA দিয়ে। কেন?

EDA-র চার লক্ষ্য

১) Sanity check: ডেটা কি import সঠিক হলো? row/column count মিলছে?
২) Quality check: missing, duplicate, outlier কোথায়?
৩) Pattern discovery: distribution-এর shape, variable-এর সম্পর্ক।
৪) Hypothesis generation: কী মডেল উপযুক্ত? কোন feature engineering লাগবে?

২ · ডেটা পেলে প্রথম ১০ মিনিট

যেকোনো নতুন ডেটাসেট পেলে নিচের ১০ command-এ ৭০% তথ্য পাওয়া যায়:

  • df.shape — row × column।
  • df.head(), df.tail() — প্রথম ও শেষ ৫টি row।
  • df.sample(10) — randomly ১০টি row (head/tail-এ pattern miss হলে)।
  • df.info() — dtype + non-null count।
  • df.describe() — numeric column-এর summary stat।
  • df.describe(include='object') — categorical column-এর summary।
  • df.isnull().sum() — missing count per column।
  • df.duplicated().sum() — duplicate row সংখ্যা।
  • df.nunique() — প্রতিটি column-এ unique value কত।
  • df.dtypes — কোনটা int, float, object, datetime।
ভাবুন আপনি Daraz-এ ১০ লাখ অর্ডারের একটি CSV পেলেন। সরাসরি ML মডেল চালালে garbage in, garbage out। প্রথম ১০ মিনিট EDA — যেমন একজন রাঁধুনি বাজার থেকে এনে চাল-ডাল চেক করে নেন আগে — পচা বাছেন, পরিমাণ মাপেন, তারপর রান্না।

৩ · Univariate analysis — একটি column

Univariate মানে "এক variable"। এক column-এ কী আছে?

Numeric column-এ:

  • Central tendency: mean, median, mode।
  • Spread: std, var, IQR, range।
  • Shape: skewnessSkewnessdistribution কতটা asymmetric। Right-skew (positive) — long tail ডানে, যেমন আয়ের distribution। Left-skew — long tail বামে।, kurtosis।
  • Visualization: histogram, KDE plot, box-plot।

Categorical column-এ:

  • Cardinality: unique value কত।
  • Frequency: value_counts() — কোন category কতবার।
  • Mode: সবচেয়ে common value।
  • Visualization: bar chart, pie (২-৩ category হলে)।
Bangladeshi mobile-banking ডেটায় "amount" column প্রায়ই right-skewed — অধিকাংশ transaction ৫০০-৫০০০ টাকা, কিন্তু কয়েকটি ১০ লাখ। Mean ও median-এর পার্থক্য বড় — log transform বিবেচনা করুন।

৪ · Bivariate analysis — দুই column-এর সম্পর্ক

দু'টি variable-এর মধ্যে কী সম্পর্ক — এটি প্রায়ই সবচেয়ে interesting। Type-অনুযায়ী technique ভিন্ন:

  • Numeric vs Numeric: scatter plot, correlation (Pearson, Spearman)।
  • Numeric vs Categorical: box-plot/violin grouped by category, mean-by-group bar chart।
  • Categorical vs Categorical: crosstab, stacked bar, chi-square test।

Correlation — Pearson formula:

$$r_{xy} = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum (x_i - \bar{x})^2 \sum (y_i - \bar{y})^2}}$$

$r$ -১ থেকে ১। ১ — perfect positive linear, -১ — perfect negative, ০ — no linear relationship। কিন্তু সাবধান — Pearson শুধু linear সম্পর্ক ধরে। Curved relationship miss হবে।

"Correlation does not imply causation" — যদি ice-cream বিক্রি ও ডুবে মৃত্যু correlated হয়, সেটা ice-cream-এর দোষ না — উভয়ই গ্রীষ্মে বাড়ে (confounding variable: তাপমাত্রা)।

৫ · Multivariate analysis — অনেক column একসাথে

১০-৫০ column-এর data-তে pairwise visualization বিস্ফোরিত হয়। কৌশল:

  • Correlation heatmap: সব numeric column-এর pairwise correlation একটি ম্যাট্রিক্সে।
  • Pair plot (sns.pairplot): প্রতিটি pair-এর scatter — ছোট data-তে কাজ করে।
  • PCA / t-SNE: high-D-কে ২-D-তে project করে cluster দেখা।
  • Parallel coordinates: প্রতিটি observation একটি rope হিসেবে সব column-এর উপর দিয়ে।
  • Facet grids: একটি categorical variable-এর প্রতিটি level-এ আলাদা plot।

৬ · ydata-profiling — এক command-এ পুরো report

ydata-profilingydata-profilingআগের নাম pandas-profiling। একটি Python library যা DataFrame পেলে স্বয়ংক্রিয়ভাবে HTML report তৈরি করে — প্রতিটি column-এর distribution, missing, correlation, duplicate সব এক ক্লিকে। — এক command-এ ৫০-পাতার HTML report। প্রতিটি column-এ:

  • Type detection (numeric, categorical, datetime)।
  • Missing %, unique %, zeros %।
  • Distribution histogram।
  • Top values, extreme values।
  • Cross-correlation matrix (numeric, categorical)।
  • Duplicate rows, missing patterns (heatmap)।

Production EDA-তে এটি প্রথম step। তারপর interesting findings-এ manually deep-dive।

EDA-র পদ্ধতিগত workflow Systematic exploration pipeline ১ · Sanity check shape, head, info ২ · Quality missing, duplicate ৩ · Univariate describe, hist ৪ · Bivariate corr, scatter ৫ · Multivariate heatmap, PCA ৬ · Pattern findings + hypotheses ৭ · Decisions cleaning, features ৮ · ydata-profiling — এক command-এ স্বয়ংক্রিয় ৫০-পাতার report profile = ProfileReport(df); profile.to_file("report.html") EDA → Cleaning → Modelling — অর্ধেক কাজ প্রথম stage-এ।
EDA-র sequential workflow — প্রতিটি stage পরের stage-কে inform করে।

৭ · Pandas দিয়ে quick EDA

একটি ছোট bKash-জাতীয় transaction dataset-এ EDA চালান।

Python · pandas
import pandas as pd
import numpy as np

# নকল bKash data
np.random.seed(42)
n = 500
df = pd.DataFrame({
    'user_id': np.random.randint(1000, 1100, n),
    'amount': np.random.lognormal(7, 1.2, n).round(0),
    'district': np.random.choice(['Dhaka','Chattogram','Sylhet','Khulna','Rajshahi'], n),
    'is_merchant': np.random.choice([0, 1], n, p=[0.7, 0.3]),
    'hour': np.random.randint(0, 24, n)
})
# কিছু missing inject
df.loc[np.random.choice(df.index, 30), 'district'] = np.nan

print("Shape:", df.shape)
print("\nDtypes:\n", df.dtypes)
print("\nMissing:\n", df.isnull().sum())
print("\nDescribe:\n", df.describe())
print("\nDistrict frequency:\n", df['district'].value_counts(dropna=False))

    
Output-এ দেখবেন — Dhaka সবচেয়ে বেশি, ৩০টি missing district, amount-এর mean ও median বড় ফারাক (right-skew confirmed)।

৮ · Bivariate — district অনুযায়ী amount

Python · pandas
import pandas as pd, numpy as np
np.random.seed(42)
n = 500
df = pd.DataFrame({
    'amount': np.random.lognormal(7, 1.2, n).round(0),
    'district': np.random.choice(['Dhaka','Chattogram','Sylhet','Khulna','Rajshahi'], n),
    'is_merchant': np.random.choice([0, 1], n, p=[0.7, 0.3])
})

# District-এ গড় amount
print("District average amount:")
print(df.groupby('district')['amount'].agg(['mean', 'median', 'count']).round(0))

# Merchant vs personal amount
print("\nMerchant vs personal:")
print(df.groupby('is_merchant')['amount'].describe()[['mean','50%','std']].round(0))

    
Bivariate analysis — categorical (district) vs numeric (amount)। groupby + agg = সবচেয়ে ব্যবহৃত EDA pattern।

৯ · ডেটাকে যে প্রশ্নগুলো করতে হয়

একটি checklist যা EDA-র সময় মাথায় রাখুন:

  1. Schema: column-এর meaning কী? unit কী (BDT/USD, kg/lb)?
  2. Time: data কোন period-এর? seasonality আছে?
  3. Source: কে collect করেছে? bias-এর সম্ভাবনা?
  4. Granularity: এক row = এক user, এক transaction, না এক day?
  5. Duplicates: exact duplicate? near-duplicate?
  6. Missing pattern: random না systematic? (পাঠ ১৭-তে বিস্তারিত)।
  7. Outliers: data-entry error না real extreme value?
  8. Class balance: target variable balanced না imbalanced?
  9. Leakage: কোন feature কি future-এর তথ্য contain করে?
EDA শেষ নেই। ১ দিনের EDA সংক্ষিপ্ত; ১ সপ্তাহের EDA gold standard। মডেল accuracy-র চেয়ে data-quality-র উপর accuracy বেশি নির্ভর করে।

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

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

প্র ০১ আপনি Daraz থেকে ১ কোটি অর্ডারের ডেটা পেলেন। প্রথম ৩০ মিনিটে কী কী করবেন? কেন এই ক্রম?

১ কোটি row-এর data — production-scale। সরাসরি ML বা SQL-এ ঢুকে গেলে ভুল আবিষ্কারের সম্ভাবনা ২-৩ দিন পর — তখন rework। তাই structured EDA।

মিনিট ০-৫: Loading ও sanity

  • প্রথমে nrows=10000-এ load — full data download দীর্ঘ সময় নিতে পারে।
  • df.shape, df.head(), df.tail(), df.sample(20)।
  • Column name-এ typo, weird unicode, trailing space দেখুন।
  • Date column থাকলে — date range কত? gap আছে?

মিনিট ৫-১০: Schema-র সাথে মিল

  • প্রতিটি column-এর intended meaning আছে কি data dictionary-তে?
  • dtype সঠিক? "order_amount" object হলে — string format-এ আছে, number-এ convert দরকার।
  • "is_returned" 0/1 না True/False না Y/N — inconsistency?

মিনিট ১০-১৫: Quality scan

  • df.isnull().sum() / len(df) * 100 — কোন column-এ ১০%+ missing?
  • df.duplicated(['order_id']).sum() — duplicate primary key থাকলে data পাইপলাইনে bug।
  • Numeric column-এ negative value (যা থাকা উচিত নয়) — যেমন amount < 0।
  • Outlier হাতে-কলমে: df['amount'].nlargest(20), nsmallest(20)।

মিনিট ১৫-২০: Univariate

  • df.describe() + df.describe(include='object')।
  • Numeric column-এ histogram (sample ১ লাখ row, full ১ কোটি-তে slow)।
  • Categorical column-এ value_counts(normalize=True).head(20)।

মিনিট ২০-২৫: Bivariate (target থাকলে)

  • Target কী? "is_returned"? "delivered"? "rating"?
  • Target-এর class balance চেক।
  • Target বনাম top ৫টি feature — groupby mean।
  • Numeric feature-গুলোর correlation matrix।

মিনিট ২৫-৩০: Quick ydata-profiling

  • profile = ProfileReport(df.sample(50000)) — full data-তে slow হবে।
  • HTML report download করে review।
  • Findings & questions document করুন stakeholder-দের জন্য।

কেন এই ক্রম:

  • Sanity প্রথম — corrupted load-এ পরের সব ভুল।
  • Quality আগে pattern-এর — junk রেখে pattern খুঁজে লাভ নেই।
  • Univariate before bivariate — একক বুঝলে সম্পর্ক বোঝা সহজ।
  • ydata-profiling শেষে — manual exploration prime context তৈরি করে।

মূল উপলব্ধি: "EDA = exploration" শুনতে freestyle, কিন্তু senior engineer-রা একটা mental checklist follow করেন। স্ট্রাকচার্ড EDA = কম রি-ওয়ার্ক।

প্র ০২ কেন EDA শেষ করে আবার EDA-তে ফিরতে হয়? "iterative EDA" বলতে কী বোঝায়?

এটি junior data scientist-দের সবচেয়ে বড় ভুল ধারণা — "EDA একবার করি, তারপর modeling"। বাস্তব production কাজে EDA cyclic।

কেন EDA iterative:

  • Findings new questions তৈরি করে: Dhaka-তে amount mean বেশি — কেন? merchant ratio? high-value subscriber? নতুন EDA।
  • Feature engineering EDA-তে ফেরায়: "amount_log" বানালেন — distribution-এর shape কেমন? skewness কমেছে?
  • Modeling-এ residual EDA: মডেল-এর error কোথায় বেশি? Dhaka-তে? merchant-এ? error-এর univariate analysis।
  • New data, same EDA: ১ মাস পর নতুন batch — distribution drift? নতুন category?

Iterative EDA-র চারটি stage:

(১) Initial EDA — first contact

  • Schema, quality, basic stat, ydata-profiling।
  • Goal: ডেটার "ভূগোল" শেখা।

(২) Hypothesis-driven EDA

  • "মেয়েরা কি বেশি cosmetic কেনেন?" — নির্দিষ্ট subset analysis।
  • Stakeholder প্রশ্ন থেকে EDA।

(৩) Feature-engineering EDA

  • নতুন column বানালেন — distribution, correlation, target relation দেখুন।
  • Encoding ও scaling-এর আগে EDA।

(৪) Post-modeling EDA

  • Residual analysis: error প্রতি segment।
  • Feature importance: which feature মডেল কী use করছে?
  • Mistake patterns: false-positive কোথায়?

উদাহরণ — Pathao churn prediction:

  • Initial EDA: ১৫% user churn (target imbalance)।
  • Hypothesis EDA: weekend-এ active user-রা churn কম — pattern observe।
  • Feature EDA: "days_since_last_ride" বানিয়ে check — strong predictor।
  • Post-model EDA: model-এর error গাজীপুর-এ বেশি — area-specific feature missing।
  • আবার iterate: গাজীপুর data investigate, নতুন feature, আবার model।

EDA-র একটি বহুল-উদ্ধৃত quote (Tukey):

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem."

Iteration-এ ভুল হলে কী হয়:

  • প্রথম EDA-তে missing pattern miss → wrong imputation → biased model।
  • Initial EDA-তে time-leakage feature ধরা না পড়ে → production-এ accuracy ০।
  • Drift detect না করে → ৬ মাস পর model স্বয়ংক্রিয় degraded।

মূল উপলব্ধি: EDA project-এর "শুরু" না — entire lifecycle-জুড়ে EDA। ভাল data scientist EDA-র loop খোলা রাখেন প্রতিটি stage-এ।

প্র ০৩ "ydata-profiling এক command-এ সব করে দেয়, তাহলে manual EDA শেখার দরকার কী?" — এই যুক্তির বিরুদ্ধে আপনার response কী?

এই প্রশ্ন প্রতিটি cohort-এ আসে। উত্তরটি subtle — automated tools wonderful কিন্তু replace করে না।

ydata-profiling কী করে ভাল:

  • প্রতিটি column-এর histogram, describe, missing — instant।
  • Correlation matrix সব numeric variable-এ।
  • Duplicate row detection।
  • Constant column, high-cardinality column flag।
  • Standard report — stakeholder-এর কাছে presentable।

কিন্তু যা ধরে না:

(১) Domain context

  • "amount = -50" — ydata flag করে না necessarily। কিন্তু আপনি জানেন bKash-এ amount negative হতে পারে না (refund alag table)।
  • "date = 2099-01-01" — outlier, কিন্তু ydata "extreme value" বলে; আপনি জানেন এটা data-entry placeholder।
  • "pin_code = 1216" — Dhaka-র। ভৌগোলিক validation ydata করে না।

(২) Business question

  • "কেন March-এ বিক্রি কমলো?" — ydata-র histogram দেখে বুঝবেন না। আপনি জানেন March = Ramadan, behavior বদলায়।
  • Specific subset analysis — ydata generic, আপনার question-specific deep-dive লাগে।

(৩) Data lineage

  • Column "user_score" কোথা থেকে আসছে? upstream pipeline-এ bug?
  • ydata দেখায় distribution — আপনার interrogate করতে হয় source।

(৪) Time-leakage detection

  • "customer_lifetime_value" feature target predict-এ ব্যবহৃত — কিন্তু এটা future-এর তথ্য contain করে।
  • ydata correlation-এ "perfect predictor" দেখাবে — manual reasoning দরকার ধরতে।

(৫) Multi-table relationship

  • ydata একটি DataFrame-এ কাজ করে।
  • "orders" + "users" + "products" join করে relationship — manual।

সঠিক ব্যবহার:

  • ydata = first pass: ১০ মিনিটে ৭০% information।
  • Manual = deep dive: পরের ৭-৮ ঘণ্টা domain-specific।
  • Communication: ydata report stakeholder-কে; manual finding আপনার Jupyter-এ।

একটি অনুরূপ analogy: "Calculator আছে, math শেখার দরকার কী?" — calculator addition দেয়, কিন্তু কখন addition use করবেন তা শিখতে hয়। Tool ছাড়া আপনি অসহায়; tool-শুধু আপনি অগভীর। দু'টোই দরকার।

Practice: প্রতিটি project-এ ydata first; তারপর তিনটি প্রশ্ন hand-write করুন report পড়ে — সেগুলো manually investigate। এভাবে দু'টি skill develop।

মূল উপলব্ধি: Tool human judgment-এর substitute না, multiplier। যিনি tool ও judgment দু'টোই rapid-deploy করতে পারেন — তিনি best data scientist।

প্র ০৪ একটি Bangladesh fintech কোম্পানির fraud detection project-এ আপনি EDA করছেন। কী কী সম্ভাব্য issue থাকতে পারে যা EDA-তে ধরতে হবে?

Fraud detection — ML-এর সবচেয়ে challenging domain গুলোর একটা। class imbalance extreme, fraudster adapt করেন, signal subtle। EDA এখানে life-saver।

(১) Class imbalance

  • Fraud rate সাধারণত ০.১% — ০.৫%। ১০ লাখ transaction-এ ৫০০-৫০০০ fraud।
  • EDA-তে confirm: df['is_fraud'].value_counts(normalize=True)।
  • Implication: accuracy meaningless; precision, recall, AUC দরকার।
  • SMOTE, undersampling, class_weight — modeling stage-এ। কিন্তু EDA-তে চেনা।

(২) Temporal pattern

  • Fraud কি সময়ের সাথে বদলায়? (drift)।
  • Hour-of-day pattern: রাত ২-৪টায় fraud বেশি?
  • Weekend vs weekday।
  • Seasonality: Eid-এর আগে surge?
  • EDA: time-series plot of fraud rate — drift চোখে পড়ে।

(৩) Geographic pattern

  • কিছু district অস্বাভাবিক fraud rate?
  • VPN/Tor user IP — bd-এর বাইরে from?
  • SIM card district vs transaction district mismatch?
  • EDA: choropleth, district vs is_fraud crosstab।

(৪) User behavior anomaly

  • একটি account থেকে অসংখ্য transaction অল্প সময়ে — velocity check।
  • একটি SIM-এ ২০টি account — multi-account fraud।
  • Amount pattern: round numbers (৫০০০, ১০০০০) — testing payouts।
  • EDA: per-user transaction count distribution; Pareto check।

(৫) Data leakage

  • সবচেয়ে বিপজ্জনক: "is_blocked_by_admin" feature-এ "is_fraud" predict — পুরোপুরি leak।
  • "investigation_status" — fraud হওয়ার পর update; modeling-এ নিষিদ্ধ।
  • EDA-তে: target-এর সাথে correlation 0.95+? সন্দেহ।
  • Time-of-feature-creation দেখুন — feature transaction-এর পরে generated?

(৬) Adversarial pattern

  • Fraudster knows model rules — adapt করে।
  • Pattern "stable" না — যেমন "amount > 50000 = fraud" detect হলে fraudster ৪৯,৯৯৯ পাঠায়।
  • EDA: histogram-এ "just-below-threshold" spike?

(৭) Missing data pattern

  • Fraud transaction-এ "device_id" missing বেশি? — informative missing (MNAR)।
  • KYC field-এ missing — incomplete onboarding fraud signal।
  • EDA: missing-vs-target heatmap।

(৮) Network features

  • একই IP থেকে অনেক account — graph EDA।
  • Money-mule pattern: A → B → C → A circular flow।
  • Standard pandas EDA enough না; networkx বা graph DB।

(৯) Bangladesh-specific

  • NID-এর pattern — fake NID detection।
  • Mobile operator (GP, Robi, Banglalink) — fraud rate ভিন্ন কি?
  • Cash-out point district — known fraud hub?
  • Bengali-numeric mixing — phone number, NID-এ data quality issue।

(১০) Regulatory check

  • Bangladesh Bank — large transaction reporting threshold।
  • BFIU AML rules — pattern compliance।
  • EDA-তে identify: কোন transaction reportable?

মূল উপলব্ধি: Fraud EDA = generic EDA + domain-specific paranoia। প্রতিটি column-এ "এটা কি adversary manipulate করতে পারে?" চিন্তা করুন। ভাল fraud analyst skeptical, creative, এবং continuously learning।

অনুশীলন

  1. Univariate practice: Pandas-এ একটি DataFrame বানান যেখানে ১০০০টি random "income" value (lognormal distribution)। তারপর mean, median, skewness, এবং histogram print করুন। Mean ও median-এর পার্থক্য কেন বড়?
    import pandas as pd, numpy as np
    np.random.seed(0)
    income = np.random.lognormal(10, 1, 1000)
    df = pd.DataFrame({'income': income})
    print(f"Mean: {df['income'].mean():,.0f}")
    print(f"Median: {df['income'].median():,.0f}")
    print(f"Skewness: {df['income'].skew():.2f}")

    Mean > median — right-skew (positive skewness)। Lognormal-এ tail ডানে — কয়েকজন very-high earner mean টেনে নেয়। Median resistant — middle value report করে।

  2. Bivariate practice: "district" ও "amount" column-এর জন্য groupby দিয়ে মান বের করুন: গড়, মধ্যক, count, std। কোন district-এ variability সবচেয়ে বেশি?
    df.groupby('district')['amount'].agg(['mean','median','count','std']).round(0)

    সাধারণত std বেশি Dhaka-তে — কারণ urban-এ both small & large transaction mix। Std কম যেখানে — homogeneous user base।

  3. ydata-profiling practice: Sklearn-এর Iris dataset-এ ydata-profiling চালান এবং report-এর তিনটি interesting finding লিখুন।
    # pip install ydata-profiling
    from sklearn.datasets import load_iris
    import pandas as pd
    from ydata_profiling import ProfileReport
    iris = load_iris(as_frame=True)
    df = iris.frame
    profile = ProfileReport(df, title="Iris EDA")
    profile.to_file("iris_report.html")

    Common findings:

    • "petal length" ও "petal width" highly correlated (~০.৯৬) — multicollinearity warning।
    • Three target classes balanced (৫০ each)।
    • "sepal width"-এ slight bimodal — species-specific।

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

কোড রানার কাজ না করলে? ব্রাউজারে কাজ না করলে Google Colab ব্যবহার করুন — Google-এর ফ্রি অনলাইন Python পরিবেশ।