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

Outlier detection

Outlier detection
৭ মিনিট পড়া মাঝারি · Intermediate z-score, IQR, IsoForest

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

  • Outlier কী, কেন গুরুত্বপূর্ণ, কখন error কখন signal
  • Z-score ও IQR — univariate outlier detection
  • Isolation Forest ও DBSCAN — multivariate technique
  • কোন handling strategy কখন (drop, cap, transform, keep)
  • Bangladesh fraud-detection context-এ outlier-এর ভূমিকা

১ · Outlier কী এবং কেন

OutlierOutlierএকটি observation যা বাকি data থেকে অস্বাভাবিকভাবে দূরে। হতে পারে data-entry error, sensor malfunction, বা genuine extreme — যেমন billionaire-এর net worth। — যে value বাকি data থেকে অস্বাভাবিকভাবে দূরে। কিন্তু "অস্বাভাবিক" আপেক্ষিক — definition data ও context-এর উপর নির্ভর।

Outlier ৩ ধরনের কারণে আসে:

  • Data-entry error: "age = 250" — typo।
  • Measurement error: sensor malfunction, OCR mistake।
  • Genuine extreme: বাস্তবেই rare — যেমন bKash-এ একটি ১ কোটি টাকার transaction।

প্রথম দু'টি — drop/correct। তৃতীয়টি — সবচেয়ে interesting। Fraud, anomaly, breakthrough প্রায়ই outlier।

Tukey-এর সতর্কবার্তা

"The outliers are sometimes the data." — কখনো outlier-ই হলো গবেষণার মূল লক্ষ্য। Ozone hole ১৯৮৫-তে outlier হিসেবে discard হয়েছিল satellite data-তে — পরে দেখা গেল true signal। বাংলাদেশে covid-spike প্রথমে outlier-ভুল ভাবা হয়েছিল।

২ · Z-score method

Z-scoreZ-scoreএকটি value-র mean থেকে কত standard deviation দূরে। Formula: $z = (x - \mu)/\sigma$. Normal distribution-এ |z| > 3 — top/bottom ০.৩%। — value-টি mean থেকে কত std দূরে।

$$z = \frac{x - \mu}{\sigma}$$

Rule of thumb: $|z| > 3$ — outlier (Normal distribution-এ এমন ০.২৭%)।

Limitation:

  • Mean ও std নিজেই outlier-এ sensitive — outlier-এ inflated, ফলে detection কম।
  • Skewed distribution-এ অনুপযুক্ত।
  • Multivariate context handle করে না।

৩ · IQR rule (Tukey's fences)

$$Q_1 = \text{২৫th percentile}, \quad Q_3 = \text{৭৫th percentile}, \quad \text{IQR} = Q_3 - Q_1$$

Outlier:

$$x < Q_1 - 1.5 \times \text{IQR} \quad \text{বা} \quad x > Q_3 + 1.5 \times \text{IQR}$$

Box-plot-এর "whisker"-এর বাইরে — outlier। ১.৫ → "moderate"; ৩.০ → "extreme" (Tukey)।

সুবিধা: robust — quartile outlier-এ resistant।
সীমাবদ্ধতা: univariate only।

ভাবুন BSEC-এ stock price monitor। Daily closing price-এ z-score = ৪ মানে — গড় থেকে ৪σ দূরে। হঠাৎ একদিনে এমন হলে — circuit breaker, suspicion of insider trading। Outlier detection ≠ "বাদ দাও" — বরং "investigate করো"।

৪ · Isolation Forest — multivariate

Isolation ForestIsolation ForestLiu et al. (২০০৮)-র algorithm। Random tree বানিয়ে — outlier কে অল্প split-এ "isolate" করা যায়। Sklearn-এ IsolationForest। বড় data-তে fast। (২০০৮, Liu et al.) — outlier-কে আলাদা করার তত্ত্ব।

Idea: random feature বেছে random threshold-এ split। Outlier "অস্বাভাবিক" — অল্প split-এ isolated হয়। Inlier-কে অনেক split দরকার।

  • Score = average path length to isolation।
  • কম score = outlier।
  • $O(n \log n)$ — fast।

Sklearn: IsolationForest(contamination=0.05) — ৫% rows outlier হিসেবে flag।

৫ · DBSCAN — density-based

DBSCANDBSCANDensity-Based Spatial Clustering। Dense region → cluster, sparse region → noise/outlier। Parameter: ε (radius) ও MinPts (minimum neighbors)। primarily clustering algorithm — কিন্তু "noise" point automatically outlier।

  • প্রতিটি point-এর ε-radius-এ MinPts neighbor থাকতে হবে।
  • না থাকলে — noise (label = -1)।

সুবিধা: arbitrary shape cluster ধরে।
অসুবিধা: ε-tuning কঠিন; high-D-এ degraded।

৬ · Mahalanobis distance

Multivariate outlier-এর "z-score" — covariance-aware:

$$D^2 = (x - \mu)^T \Sigma^{-1} (x - \mu)$$

Normal-distributed multivariate-এ $D^2$ chi-square distribution follow। Threshold: $\chi^2_{0.975, p}$।

৭ · Decision: drop, cap, transform, keep

(ক) Drop:

  • স্পষ্ট error (age = 999, salary = -1)।
  • Domain-impossible value।

(খ) Cap (winsorize):

  • ৯৯-percentile-এ clip — value retain কিন্তু effect bound।
  • উদাহরণ: df['amount'] = df['amount'].clip(upper=df['amount'].quantile(0.99))।

(গ) Transform:

  • Log, sqrt, Box-Cox — skewness কমায়, outlier-এর effect dampen।
  • income → log(income) — এটি common।

(ঘ) Keep + flag:

  • Tree model outlier-resistant — keep all।
  • is_outlier column যোগ — predictive feature।
Outlier drop-এর আগে — সবসময় investigate। "Bug-pixel"-এর মতো দেখায় যা NASA-র Voyager image-এ — কিন্তু পরে চাঁদের surface-এর volcano। Outlier হারালে discovery হারান।
Outlier handling decision Detect → diagnose → decide Outlier পেলেন কারণ কী? error or signal? Error → drop age=999, salary=-1 Skew → log/cap winsorize at p99 Signal → keep + flag fraud, breakthrough 📌 Drop-এর আগে — investigate। Outlier-ই কখনো গবেষণার লক্ষ্য। Methods: z-score, IQR, IsolationForest, DBSCAN
Outlier diagnostic — কারণ-চিহ্নিত করে তবে action।

৮ · Pandas-এ univariate outlier detection

Python · pandas
import pandas as pd
import numpy as np

np.random.seed(0)
data = np.concatenate([
    np.random.normal(5000, 1000, 95),
    [50000, 60000, 80000, -2000, 0]   # outlier
])
df = pd.DataFrame({'amount': data})

# z-score method
mean, std = df['amount'].mean(), df['amount'].std()
df['z'] = (df['amount'] - mean) / std
df['is_outlier_z'] = df['z'].abs() > 3

# IQR method
q1, q3 = df['amount'].quantile([0.25, 0.75])
iqr = q3 - q1
lower, upper = q1 - 1.5*iqr, q3 + 1.5*iqr
df['is_outlier_iqr'] = (df['amount'] < lower) | (df['amount'] > upper)

print(f"Z-score outliers: {df['is_outlier_z'].sum()}")
print(f"IQR outliers: {df['is_outlier_iqr'].sum()}")
print("\nSuspect rows:")
print(df[df['is_outlier_iqr']].sort_values('amount'))

    
Z-score-এর চেয়ে IQR সাধারণত বেশি sensitive — কারণ mean ও std outlier-এ নিজেই inflated হয়। IQR robust।

৯ · Isolation Forest — multivariate

Python · sklearn
import pandas as pd, numpy as np
from sklearn.ensemble import IsolationForest

np.random.seed(0)
n = 200
df = pd.DataFrame({
    'amount': np.concatenate([np.random.normal(5000, 1000, n-5), [50000, 60000, 100, 200, 300]]),
    'count': np.concatenate([np.random.poisson(10, n-5), [200, 300, 1, 2, 1]])
})

iso = IsolationForest(contamination=0.05, random_state=0)
df['outlier'] = iso.fit_predict(df[['amount','count']])
# -1 = outlier, 1 = inlier

print(f"Outlier count: {(df['outlier'] == -1).sum()}")
print("\nFlagged outliers (top by amount):")
print(df[df['outlier'] == -1].sort_values('amount', ascending=False).head())

    
Isolation Forest দু'টি column একসাথে ব্যবহার করে। "amount বড়" বা "count বড়" — যেকোনোটায় outlier flag।

১০ · Bangladesh-এ practical context

  • bKash fraud: "সাধারণ user-এর daily transaction ১-৫টি"। কেউ ১০০টি — outlier, fraud suspect।
  • Daraz return: "একই user ২০টি item return এক মাসে" — abuse pattern।
  • Pathao surge: "একটি rider-এর rating ৩.০-এর নিচে" — outlier driver, performance issue।
  • BBS census: "village-এর জনসংখ্যা ১০০,০০০" — likely data-entry typo (sample sized village ~৩০০)।
  • NID database: birth_date "০১-০১-১৯০০" placeholder — common Bangladesh administrative pattern।

১১ · Common pitfalls

  • Aggressive drop: "z > ৩ সব drop" — ৯৯.৭% data রাখলেন, কিন্তু important signal হারালেন।
  • Train-test contamination: outlier detector test set-এ train করলে — leakage।
  • Single threshold: "১.৫ × IQR" magic না — domain-specific tuning।
  • Scale-blind: IsoForest-এর আগে scaling বিবেচনা।

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

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

প্র ০১ আপনার boss বললেন "z > ৩ সব row drop দাও"। আপনি কী জবাব দেবেন? কী কী case-এ এটি ভুল?

Senior data scientist-দের একটি common rite of passage — naive outlier rule-এ আপত্তি জানানো। কিছু concrete reason:

(১) Z-score outlier-এ self-defeat

  • Mean ও std outlier-এ contaminated।
  • Outlier inflate করে → effective threshold higher → কম detection।
  • Robust alternative: median + MAD (Median Absolute Deviation)।

(২) Skewed distribution-এ Z-score অযোগ্য

  • Income, transaction amount — long right tail।
  • Genuine high-value (legitimate billionaire transaction) z > ৫ হবে।
  • Drop = real customer হারানো।
  • Better: log-transform-এর পর z-score।

(৩) Fraud/anomaly detection-এর বিপরীত

  • Fraud ML-এ outlier-ই target।
  • Drop করলে — মডেলের কাছে শেখার কিছু নেই।
  • Anomaly detection-এর পুরো paradigm এর বিরুদ্ধে।

(৪) Time-series-এ ভয়াবহ

  • Stock crash, COVID outbreak — z > ৩।
  • Drop করলে — historical event-ই ইতিহাস থেকে মুছে যায়।
  • মডেল future-এর crisis predict করতে পারে না।

(৫) Multivariate context miss

  • Height ১৭০cm normal, weight ৫০kg normal — কিন্তু ১৭০cm + weight ১২০kg combination আউটলায়ার।
  • Univariate z-score ধরে না।
  • Mahalanobis বা IsoForest দরকার।

(৬) Sample size sensitivity

  • n = ১,০০,০০০-এ ০.৩% = ৩০০ row drop। কিছুই না।
  • n = ১০০-এ ০.৩% = ০ — কিন্তু "ভুলে" আগে drop হয়ে যায় ১-২টি true point।

(৭) Train-test interaction

  • Train-এ outlier drop, test-এ আছে — production failure।
  • Pipeline-এ outlier handling consistent রাখুন।

আপনি কী reply দেবেন:

  • "Boss, প্রথমে cause investigate করি — error না signal?"
  • "Drop-এর বদলে — IQR cap বা log transform consider করি।"
  • "মডেলের performance with vs without outlier — A/B compare।"
  • "Indicator column রাখি — outlier flag predictive হতে পারে।"

Bangladesh-context example:

  • Eid-এর সপ্তাহে bKash transaction volume z > ৪। Drop করলে — seasonality-অজ্ঞ মডেল।
  • BTRC data-তে rural call-volume "outlier"-low — কিন্তু সেটা real connectivity issue।

মূল উপলব্ধি: "Outlier = drop" naive। Production-এ outlier-handling = nuanced decision per column, per use-case। Boss-কে educate করুন — diplomatically, with examples।

প্র ০২ Isolation Forest কীভাবে কাজ করে? কেন univariate method-এর চেয়ে multivariate-এ ভাল? কী সীমাবদ্ধতা?

Isolation Forest (Liu, Ting, Zhou, ২০০৮) — anomaly detection-এর আকর্ষণীয় idea। Random partitioning দিয়ে outlier "isolate"।

Algorithm:

  1. একটি random feature বাছুন।
  2. Random threshold-এ split (min, max-এর মধ্যে)।
  3. Recursively চালান — প্রতিটি leaf-এ একটি point।
  4. প্রতিটি point-এর depth (root-থেকে-leaf) measure।
  5. Outlier-এর depth কম (শীঘ্রই isolated)।
  6. Forest = অনেক tree; average depth।

Score formula:

$$s(x, n) = 2^{-\frac{E(h(x))}{c(n)}}$$

  • $E(h(x))$ — average path length।
  • $c(n)$ — average path length-এর normalization।
  • $s$ ১-এর কাছাকাছি = outlier; ০-এর কাছাকাছি = inlier।

কেন multivariate-এ shine:

  • Random feature pick — সব dimension-এ partition।
  • Combination outlier (height-OK, weight-OK, কিন্তু combo unusual) ধরে।
  • No assumption about distribution shape।
  • $O(n \log n)$ — million row-এ ঠিকঠাক।

Univariate-এর সাথে তুলনা:

  • Z-score: শুধু একটি column।
  • IQR: শুধু একটি column।
  • IsoForest: সব column joint।
  • উদাহরণ: bKash transaction "amount" এবং "hour" — দু'টোই individually normal, কিন্তু "100,000 BDT at 3am" combination outlier।

সুবিধা:

  • Distribution-free।
  • Scalable।
  • Categorical (encoded), numeric — both।
  • Sklearn-এ one-line integration।

সীমাবদ্ধতা:

  • Contamination parameter: "৫% outlier expected" — guess কঠিন।
  • Local outlier miss: dense cluster-এ একটু ভিন্ন point — IsoForest detect-এ দুর্বল। LOF (Local Outlier Factor) ভাল।
  • High-D-এ degraded: ১০০০-D-এ random split-এর meaning কম।
  • Categorical native না: encoding দরকার।
  • Interpretation কঠিন: "কেন এটা outlier" explain — black box।
  • Imbalanced learning: outlier rate <1%-এ noisy।

বিকল্প:

  • Local Outlier Factor (LOF): density-based, local context।
  • One-class SVM: boundary learn।
  • Autoencoder: reconstruction error দিয়ে anomaly।
  • DBSCAN: noise label।

Bangladesh fraud pipeline-এ usage:

  • bKash anomaly detection-এ IsoForest first-pass (fast scan)।
  • Flagged candidates তারপর rule-based + manual review।
  • Confirmed fraud — supervised model train data।
  • Iterative — IsoForest only baseline।

মূল উপলব্ধি: IsoForest fast, scalable baseline। Production-এ — IsoForest + LOF + domain-rules ensemble। কোনো single method magic না।

প্র ০৩ Winsorize (cap) vs log transform — কখন কোনটা? উদাহরণসহ ব্যাখ্যা।

দু'টোই outlier-এর effect দমন করে — কিন্তু পদ্ধতি ভিন্ন। Choice depends on data nature ও model।

Winsorizing:

  • Top/bottom k%-এ value cap। যেমন: ৯৯th percentile-এর উপরে সব value = ৯৯th percentile।
  • Distribution shape preserve, কিন্তু extreme tail truncate।
  • df['x'] = df['x'].clip(lower=df['x'].quantile(0.01), upper=df['x'].quantile(0.99))

Log transform:

  • df['x_log'] = np.log1p(df['x']) — extreme value compress।
  • Skewness reduce (log-normal → near-normal)।
  • Multiplicative relationship → additive।

কখন winsorize:

  • Outlier obvious error/spurious — cap-এ effect bound।
  • Distribution mostly normal, কয়েকটি extreme — cap minimal distortion।
  • Linear regression-এ — coefficient stable হয়।
  • Quick fix needed, exploration phase।

উদাহরণ winsorize:

  • Daraz product rating: scale 1-5; কিছু error ৬, ৭, ১০। Cap at 5।
  • Customer age: cap at 100 (১২০ likely error)।
  • Pathao ride duration: cap at 4-hour (longer = data error)।

কখন log transform:

  • Distribution genuinely right-skewed (income, transaction amount, population)।
  • Multiplicative relationship suspected (% growth)।
  • Linear model assumption (homoscedasticity) violated।
  • Statistical inference needed — log makes residuals more normal।

উদাহরণ log:

  • bKash transaction amount: lognormal natural। log(amount)।
  • Real-estate price: log-price → linear regression more stable।
  • City population: log-population symmetric distribution।

Combined approach:

  • প্রথমে obvious-error cap (winsorize at extremes)।
  • তারপর log transform skewness-এর জন্য।
  • Sequence: cap → log → standardize।

সাবধানতা:

  • Log-এ ০ ও negative: log(0) = -inf, log(-) = NaN। Use log1p = log(1+x); negative-এ shift।
  • Winsorize-এ thresholds train-test consistent: train-এর quantile-এই test-এ cap।
  • Tree models indifferent: log-transform tree-এ পার্থক্য করে না; linear model-এ বড় পার্থক্য।

Model-specific guidance:

  • Linear regression, logistic regression: log + winsorize highly recommended।
  • Tree (XGBoost, RF): outlier-resistant; cap optional।
  • Neural network: log + scale (StandardScaler) সাধারণত essential।
  • k-NN, k-Means: distance-based — outlier sensitive; winsorize must।

Box-Cox — generalization:

$$y(\lambda) = \begin{cases} \frac{y^\lambda - 1}{\lambda} & \text{if } \lambda \ne 0 \\ \log(y) & \text{if } \lambda = 0 \end{cases}$$

λ data থেকে estimate। positive value-এ কাজ করে। Yeo-Johnson — negative-এও।

Bangladesh data examples:

  • Census income → log + winsorize (top 1% extreme rich)।
  • Pathao ride distance → log (long-tail, multiplicative growth)।
  • BSEC stock return → winsorize (regulatory limit ±10%)।

মূল উপলব্ধি: Cap = surgical। Log = systemic। Distribution shape ও model-type বুঝে choose। সবসময় before/after distribution plot দেখুন — transformation-এর effect verify।

প্র ০৪ Bangladesh fraud-detection context-এ আপনি কীভাবে outlier detection setup করবেন? কোন method? কোন feature?

Real production fraud system-এ outlier detection ছাড়া অপূর্ণ। Bangladesh fintech-এ specifically — bKash, Nagad, Rocket, City Bank — সবাই এ ধরনের layered approach।

Layer 1 — Rule-based (instant)

  • "একটি SIM থেকে ১ ঘণ্টায় > ১০ transaction" — block।
  • "একটি বছর কম-active account থেকে ১ লক্ষ টাকা" — pause।
  • "Cross-border login attempt" — alert।
  • Hard threshold; rule database; latencyLatencyrequest থেকে response পর্যন্ত সময়। Real-time fraud-এ <100ms target। < ১০০ms।

Layer 2 — Univariate statistical

  • Per-user baseline: গড় amount, daily count।
  • Z-score (robust: median, MAD)।
  • "User-এর historical mean থেকে ৫σ বেশি" — flag।
  • Per-segment threshold (urban/rural, merchant/personal)।

Layer 3 — Multivariate ML

  • Isolation Forest — ১০-২০ feature input।
  • Features: amount, hour, location, velocity, device_change, network_distance।
  • Daily retrain — distribution drift accommodate।

Layer 4 — Graph-based

  • User-User network: who sends money to whom।
  • Money-mule pattern: A → B → C → A circular।
  • Community detection — fraud ring identify।
  • Graph centrality, clustering coefficient feature হিসেবে।

Layer 5 — Supervised ML

  • Confirmed fraud label থেকে train।
  • XGBoost বা LightGBM (imbalance-aware)।
  • Probability score → review queue priority।

Feature engineering specifics:

  • Velocity: "last 1h transaction count", "last 24h amount"।
  • Geographic: "transaction district vs SIM district", "IP geolocation distance"।
  • Behavioral baseline: "amount vs user's 30-day median"।
  • Network: "n unique recipients in past week", "graph distance to known fraud"।
  • Time pattern: "transaction hour z-score from user's typical pattern"।
  • Device: "n devices used", "new-device flag", "browser fingerprint match"।

Bangladesh-specific challenges:

  • SIM swap fraud: attacker SIM hijack করে — sudden behavior change। Velocity alarm।
  • OTP scam: social engineering — same phone, same SIM, কিন্তু behavior off।
  • Mule accounts: বেকার তরুণদের KYC ব্যবহার করে fraud run।
  • Cross-border: Hundi network detection।
  • Eid surge: seasonal — false-positive spike। Holiday-aware threshold।

Operational constraints:

  • Latency: <১০০ms — heavy ML ব্যবহার সীমিত।
  • False positive cost: legitimate user-এর transaction block — frustration, churn।
  • Cost: review team overhead — flag-rate too high impractical।
  • Adversarial: fraudster pattern আবিষ্কার করেন।

Metrics:

  • Precision @ top-K (review capacity)।
  • Recall (fraud catch rate)।
  • FPR (false alarm)।
  • Cost-weighted: each missed fraud = avg loss।
  • Time-to-detect (TTD)।

Regulatory:

  • Bangladesh Bank — large transaction reporting।
  • BFIU AML rules — pattern-based।
  • STR (Suspicious Transaction Report) submission।

Architecture:

  • Streaming: Kafka → Flink → ML scoring → block/allow/review।
  • Batch: nightly retrain, drift detection।
  • Feature store: Feast/Tecton — online + offline consistent।

মূল উপলব্ধি: Real fraud-detection একা outlier-detection না — defense-in-depth। Statistical, ML, graph, rule সব layer একসাথে। প্রতিটি layer-এ outlier detection alert source।

অনুশীলন

  1. IQR detection: $[10, 12, 14, 15, 18, 100]$ — Q1, Q3, IQR বের করুন; outlier কোনটা?

    Q1 = 12.5, Q3 = 17.25 (linear interpolation), IQR = 4.75।

    Upper fence = 17.25 + 1.5 × 4.75 = 24.4। 100 > 24.4 → outlier।

    Lower fence = 12.5 - 1.5 × 4.75 = 5.4। কিছুই lower-এ নেই।

  2. Winsorize practice: একটি Series-এ ৯৫% percentile-এ cap লাগান Pandas-এ।
    upper = df['x'].quantile(0.95)
    lower = df['x'].quantile(0.05)
    df['x_capped'] = df['x'].clip(lower=lower, upper=upper)

    Train data-তে quantile compute → save → test-এ same threshold ব্যবহার (data leakage এড়াতে)।

  3. IsoForest practice: Sklearn-এ ১০০০ row data বানান, ৫% inject anomaly, Isolation Forest দিয়ে detect-এর precision/recall measure করুন।
    import numpy as np
    from sklearn.ensemble import IsolationForest
    np.random.seed(0)
    X_normal = np.random.normal(0, 1, (950, 2))
    X_anom = np.random.uniform(-6, 6, (50, 2))
    X = np.vstack([X_normal, X_anom])
    y_true = np.array([0]*950 + [1]*50)
    
    iso = IsolationForest(contamination=0.05, random_state=0)
    y_pred = (iso.fit_predict(X) == -1).astype(int)
    
    from sklearn.metrics import precision_score, recall_score
    print(f"Precision: {precision_score(y_true, y_pred):.2f}")
    print(f"Recall: {recall_score(y_true, y_pred):.2f}")

    সাধারণত precision ও recall ০.৬-০.৮-এ আসে। Tuning: contamination, n_estimators।

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

কোড রানার কাজ না করলে? Google Colab ব্যবহার করুন।
পূর্ববর্তী পাঠ
পাঠ ১৭ · Missing data