EDA — পদ্ধতিগত ভাবে
এই পাঠে যা শিখবেন
- 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 দিয়ে। কেন?
১) 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।
৩ · 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 হলে)।
৪ · 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 হবে।
৫ · 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।
৭ · Pandas দিয়ে quick EDA
একটি ছোট bKash-জাতীয় transaction dataset-এ EDA চালান।
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))
৮ · Bivariate — district অনুযায়ী amount
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))
৯ · ডেটাকে যে প্রশ্নগুলো করতে হয়
একটি checklist যা EDA-র সময় মাথায় রাখুন:
- Schema: column-এর meaning কী? unit কী (BDT/USD, kg/lb)?
- Time: data কোন period-এর? seasonality আছে?
- Source: কে collect করেছে? bias-এর সম্ভাবনা?
- Granularity: এক row = এক user, এক transaction, না এক day?
- Duplicates: exact duplicate? near-duplicate?
- Missing pattern: random না systematic? (পাঠ ১৭-তে বিস্তারিত)।
- Outliers: data-entry error না real extreme value?
- Class balance: target variable balanced না imbalanced?
- Leakage: কোন feature কি future-এর তথ্য contain করে?
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ আপনি 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।
অনুশীলন
-
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 করে।
-
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।
-
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-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ১৭ · Missing data কীভাবে ভরাব পরবর্তী পাঠ EDA-তে missing detect — এবার fix করার পদ্ধতি।
- পাঠ ১৫ · A/B Testing আগের পাঠ Hypothesis test ও experimental design।
- পাঠ ১৮ · Outlier detection এই পাঠের সাথে সম্পর্কিত EDA-তে outlier flag — পরবর্তী step।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।