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

Categorical encoding

Categorical encoding
৭ মিনিট পড়া মাঝারি · Intermediate One-hot, target, embedding

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

  • One-hot, label, ordinal encoding — সরল technique
  • Target/mean encoding — high-cardinality-এ powerful
  • Frequency encoding — দ্রুত baseline
  • Embedding encoding — DL-এর সাথে
  • "Cardinality cliff" — কখন কোন method

১ · কেন encoding দরকার

ML algorithm — linear regression থেকে neural network পর্যন্ত — সব input number-এ চায়। কিন্তু বাস্তব ডেটায় column-এ "Dhaka", "merchant", "iPhone" — strings। এদের কে number-এ রূপান্তর করতে হয়। এটাই categorical encodingCategorical Encodingcategory-type column-কে numeric representation-এ রূপান্তর — যাতে ML model input হিসেবে ব্যবহার করতে পারে। Method-ভেদে accuracy ও interpretability বদলায়।।

সরল উদাহরণ: Daraz delivery district — "Dhaka", "Chattogram", "Sylhet"। Linear regression-এ এই string সরাসরি দিতে পারবেন না।

২ · Categorical-এর দু'ধরন

  • Nominal (no order): "Dhaka", "Chattogram" — কোন rank নেই।
  • Ordinal (order আছে): "low", "medium", "high" — rank meaningful।

Method-এর choice এই distinction-এর উপর নির্ভর করে।

৩ · One-hot encoding

প্রতিটি unique category-র জন্য একটি new binary column। সবচেয়ে common technique।

Example: "district" = ["Dhaka", "Chattogram", "Sylhet"] → তিনটি column:

  • district_Dhaka: 0/1
  • district_Chattogram: 0/1
  • district_Sylhet: 0/1

Pandas: pd.get_dummies(df, columns=['district'])।

সুবিধা: no false ordering; linear model-এ natural।
অসুবিধা: high-cardinality-এ explosion (১০০ category = ১০০ column); sparsity।

drop_first=True — multicollinearity এড়াতে এক column drop। Linear regression-এ standard; tree-এ optional।

৪ · Label encoding

প্রতিটি category-কে একটি integer। "Dhaka" = ০, "Chattogram" = ১, "Sylhet" = ২।

সুবিধা: single column; tree model-এ ভাল।
অসুবিধা: false ordering imply। Linear model "Sylhet (২) > Dhaka (০)" ভাবতে পারে।

কখন: tree-based model (XGBoost, RF, LightGBM) এবং nominal data-তে।

৫ · Ordinal encoding

Order জানা থাকলে — সেই order-এ integer assign।

Example: "education" = ["primary", "secondary", "graduate", "post-grad"] → ০, ১, ২, ৩।

Sklearn: OrdinalEncoder(categories=[['primary', 'secondary', ...]]) — manual order।

Linear ও tree উভয়ে কাজ করে। কিন্তু এক step difference সব level-এ equal — সেটা ground truth-এ true কি না, প্রশ্ন।

৬ · Target (mean) encoding

Target encodingTarget Encodingcategory-কে সেই category-র সাথে target variable-এর mean দিয়ে replace। যেমন: "Dhaka" → Dhaka-র customer-দের গড় churn rate। High-cardinality-এ powerful, কিন্তু leakage risk। — প্রতিটি category-কে সেই category-র target-এর mean দিয়ে replace।

Example: Daraz churn prediction। District by churn rate:

  • Dhaka — ১৫% churn → "Dhaka" replace = ০.১৫
  • Chattogram — ১২% → ০.১২
  • Sylhet — ১৮% → ০.১৮

সুবিধা:

  • High cardinality-এ effective (১০০০ city → ১ column)।
  • Target-এর সাথে relationship explicit।
  • Tree ও linear উভয়ে ভাল।

সমস্যা — leakage:

  • Train data-তে target দেখে encoding বানান — overfitting।
  • সমাধান: K-fold target encoding (out-of-fold mean)।
  • Smoothing: (count*mean + smooth*global_mean) / (count + smooth) — rare category-তে global gravitate।
Target encoding-এর সবচেয়ে বড় ভুল — train ও test একসাথে fit। Test-এর target দেখা leakage-এর সবচেয়ে severe form। সবসময় train-এ fit, test-এ transform।

৭ · Frequency encoding

প্রতিটি category-কে তার count (বা proportion) দিয়ে replace।

  • "Dhaka" — ৫০,০০০ row → 50000 (বা ০.৫)।
  • "Sylhet" — ১০,০০০ → 10000।

সুবিধা: simple, no target leakage, single column।
সীমা: দু'টি ভিন্ন category-র same frequency হলে — collision।

৮ · Embedding encoding (DL)

Deep learning-এ — categorical column-কে dense vector-এ map। NLP-র word embedding-এর সাধারণীকরণ।

Architecture: Embedding(num_categories, dim) layer — প্রতিটি category একটি $d$-dim vector।

$$\text{embed}(c) = E[c] \in \mathbb{R}^d$$

  • $d$ usually $\sqrt[4]{n}$ থেকে $50$।
  • Trained jointly with model।
  • Similar category কাছাকাছি vector।

Tabular DL (TabNet, FT-Transformer)-এ standard। Production: large e-commerce, RecSys।

৯ · Cardinality cliff — কখন কোন method

  • ২-৩ category: one-hot (drop_first=True) বা label।
  • ৪-১০ category: one-hot।
  • ১০-৫০: target encoding বা frequency।
  • ৫০-৫০০: target encoding (smoothed)।
  • ৫০০+: embedding (DL) বা hash encoding।

"Cardinality cliff" = যেখানে one-hot impractical হয়ে যায়। সাধারণত ~৫০ category।

ভাবুন Bangladesh-এর ৬৪ জেলা। One-hot করলে ৬৪ column — বেশ। কিন্তু ৪৫০ upazila? ৬৪,০০০ village? One-hot impossible। target বা frequency encoding অপরিহার্য।
Categorical encoding — decision Cardinality + nature → method Categorical column how many unique? ≤ ১০ One-hot encoding ১০-১০০ Target / frequency ১০০+ Embedding / hash যদি ordinal থাকে — ordinal encoding Tree model label/target OK Linear model one-hot preferred Neural network embedding Train-এ fit, test-এ transform — leakage এড়ান
Cardinality + model-type → encoding method।

১০ · Pandas + Sklearn কোড

Python · pandas
import pandas as pd
import numpy as np

df = pd.DataFrame({
    'district': ['Dhaka','Chattogram','Sylhet','Dhaka','Khulna','Sylhet','Dhaka'],
    'education': ['primary','graduate','secondary','post-grad','primary','graduate','secondary'],
    'churn': [1, 0, 1, 0, 1, 0, 1]
})

# 1) One-hot
oh = pd.get_dummies(df['district'], prefix='dist')
print("One-hot:\n", oh)

# 2) Ordinal
edu_order = {'primary': 0, 'secondary': 1, 'graduate': 2, 'post-grad': 3}
df['edu_ord'] = df['education'].map(edu_order)
print("\nOrdinal:\n", df[['education','edu_ord']])

# 3) Frequency
freq = df['district'].value_counts(normalize=True)
df['dist_freq'] = df['district'].map(freq)
print("\nFrequency:\n", df[['district','dist_freq']])

# 4) Target encoding (simple, no smoothing)
target_map = df.groupby('district')['churn'].mean()
df['dist_target'] = df['district'].map(target_map)
print("\nTarget:\n", df[['district','dist_target']])

    
চারটি method একসাথে compare। Production-এ target encoding-এ K-fold আবশ্যক — এখানে demonstration।

১১ · Sklearn pipeline

Python · sklearn
import pandas as pd, numpy as np
from sklearn.preprocessing import OneHotEncoder, OrdinalEncoder
from sklearn.compose import ColumnTransformer

df = pd.DataFrame({
    'district': ['Dhaka','Chattogram','Sylhet','Dhaka','Khulna'],
    'education': ['primary','graduate','secondary','post-grad','primary'],
    'income': [25000, 60000, 30000, 80000, 22000]
})

ct = ColumnTransformer([
    ('district_oh', OneHotEncoder(sparse_output=False), ['district']),
    ('edu_ord', OrdinalEncoder(categories=[['primary','secondary','graduate','post-grad']]), ['education']),
], remainder='passthrough')

X = ct.fit_transform(df)
feature_names = ct.get_feature_names_out()
print("Feature names:", feature_names)
print("\nEncoded matrix:\n", X)

    
ColumnTransformer — production-grade pattern। Train-এ fit, test-এ transform — leakage-free।

১২ · Bangladesh-context tips

  • Bengali category names: "ঢাকা", "চট্টগ্রাম" — encoding affect করে না কিন্তু consistency রাখুন (Unicode normalization)।
  • Mobile operator (3 categories): GP, Robi, Banglalink → one-hot perfect।
  • Upazila (~৪৫০): target বা frequency।
  • Product SKU (১,০০,০০০+): embedding (DL recommender)।
  • Bank account type: "savings", "current", "DPS", "FDR" — ordinal arguable; one-hot safer।

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

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

প্র ০১ একটি product_id column-এ ৫০,০০০ unique value। One-hot করলে কী সমস্যা? কী strategy?

৫০,০০০ unique product — Daraz, Amazon-এর মতো বড় e-commerce-এ realistic। One-hot এই situation-এ disaster।

One-hot-এর সমস্যা:

  • Memory explosion: ১০ লাখ row × ৫০,০০০ col = ৫×১০¹⁰ cells। Even sparse — RAM-এ ১০-৫০ GB।
  • Curse of dimensionality: linear model-এ — সব weight-এ data সামান্য, generalization poor।
  • Train time: matrix multiplication exponentially slow।
  • Overfitting: rare product-এ specific weight — noise।
  • Cold start: নতুন product test-এ — train-এ ছিল না — encoder fail।

Strategy alternatives:

(১) Target encoding

  • প্রতিটি product-কে তার গড় target দিয়ে replace।
  • "product_X-এর গড় conversion rate ০.০৩"।
  • ৫০,০০০ category → ১ column।
  • K-fold mean-এ leakage-free।

(২) Frequency encoding

  • "product popularity" implicit।
  • Rare product → low value।
  • Simple, no leakage।

(৩) Hash encoding

  • $h(product\_id) \mod K$ — fixed K bins।
  • Collision আছে কিন্তু acceptable।
  • Stateless — নতুন product handle।
  • Sklearn FeatureHasher।

(৪) Embedding (DL)

  • nn.Embedding(50000, 32) — ৩২-D vector per product।
  • Trained jointly with task model।
  • Best for recommendation, search।
  • Memory efficient: ৫০,০০০ × ৩২ = ১.৬M floats।

(৫) Aggregate features

  • Product-এর numeric stats: avg_rating, price, n_orders, n_returns।
  • Categorical bucket: category_top, brand।
  • raw product_id discard করে এই aggregates use।

(৬) Frequency-based grouping

  • Top-1000 product-এ one-hot, rest "other"।
  • Power-law assumption: top sellers cover ৮০% volume।
  • Hybrid approach।

Comparison-এ accuracy:

  • Embedding usually best (DL, large data)।
  • Target encoding strong baseline।
  • Hash encoding slight degradation কিন্তু infra-friendly।
  • One-hot impractical।

Production architecture (Daraz-like):

  • RecSys: Two-tower model — user embedding × product embedding।
  • Click prediction: gradient boosting + target-encoded features।
  • Search: pre-trained embedding (BERT for product description)।
  • Cold start: content-based embedding (image, text)।

Bangladesh e-commerce realities:

  • Daraz: ১০M+ SKU।
  • Pickaboo, Evaly (now-defunct): ৫০K-১০০K SKU।
  • Local "ekShop": small inventory, one-hot OK।
  • Cross-border: international SKU expansion challenge।

মূল উপলব্ধি: "One-hot সব encoding"-এর myth — high-cardinality-এ break। Embedding ও target encoding production-এ অপরিহার্য। Architecture decision data scale-এ বদলায়।

প্র ০২ "Target encoding-এ leakage" বলতে কী বোঝায়? K-fold target encoding কীভাবে এটা solve করে?

Target encoding সবচেয়ে effective high-cardinality method — কিন্তু leakage-এর সবচেয়ে subtle source। বহু Kaggle competitor public LB-এ overfitted টিতে।

Leakage কী:

  • Train data দেখে encoding compute — সেই encoding আবার train data-তে apply।
  • প্রতিটি row নিজের target নিজের encoded value-তে contribute করছে।
  • Model "শিখে": "encoded_value = target" — perfect train accuracy, terrible test।

Concrete example:

  • "Dhaka" rows: target = [1, 0, 1, 1] → mean = 0.75।
  • প্রতিটি Dhaka row "Dhaka" → 0.75 encoded।
  • Linear model "0.75 = positive case" শিখে।
  • Test-এ একটি rare district যা train-এ ছিল না — encoder ভেঙে পড়ে।

Test-time problem:

  • Test "Sylhet" row — train-এ Sylhet-এর mean ০.৩।
  • Train-এর encoding apply OK।
  • কিন্তু training-এ model-এর leakage আগেই হয়েছে — accuracy inflated।

K-fold target encoding solution:

  1. Train data K folds-এ split (যেমন K=5)।
  2. প্রতিটি fold-এর জন্য — অন্য K-1 folds থেকে mean compute।
  3. সেই mean current fold-এ apply।
  4. প্রতিটি train row "out-of-fold" mean পায় — own contribution না।

Pseudocode:

from sklearn.model_selection import KFold
kf = KFold(n_splits=5, shuffle=True)
df['cat_enc'] = 0.0
for train_idx, val_idx in kf.split(df):
    means = df.iloc[train_idx].groupby('cat')['target'].mean()
    df.loc[val_idx, 'cat_enc'] = df.iloc[val_idx]['cat'].map(means)

Smoothing — additional protection:

$$\text{enc}(c) = \frac{n_c \cdot \bar{y}_c + m \cdot \bar{y}_{global}}{n_c + m}$$

  • $n_c$ — count of category $c$।
  • $\bar{y}_c$ — category-specific mean।
  • $m$ — smoothing parameter (typically ১০-১০০)।
  • Rare category → global mean দিকে pull।

Why smoothing:

  • "Sylhet" only ৫টি row — mean noisy।
  • Without smoothing — overfitting।
  • Bayesian interpretation: prior = global, data = category।

Library options:

  • category_encoders.TargetEncoder — sklearn-compatible।
  • CatBoost — built-in target encoding (ordered)।
  • H2O AutoML — automatic।

Production gotchas:

  • Train-এ encoding fit, save mapping → test apply।
  • New category test-এ → use global mean fallback।
  • Time-series — "future leakage": K-fold-এর বদলে time-aware fold।
  • Multi-class — per-class encoding (binary target থেকে আলাদা)।

CatBoost-এর "Ordered Boosting":

  • Random permutation।
  • Row $i$-এর encoding শুধু row $1...i-1$-এর target থেকে।
  • Strict no-leakage by construction।

Bangladesh ML competition context:

  • BUET Datathon-এ অনেক participant naive target encoding-এ overfit।
  • Kaggle Bangladesh competition — leakage detection essential review point।
  • Production ML team-এ — encoding pipeline সবসময় Pipeline-এ wrap।

মূল উপলব্ধি: Target encoding power-tool — কিন্তু sharp। K-fold + smoothing without compromise। CatBoost-এর built-in ordered encoding সবচেয়ে safe। Leakage detection — model-এর train ও test accuracy gap বড় হলে suspicion।

প্র ০৩ "Education" column-এ "primary, secondary, graduate, post-grad" — ordinal। কেন ০, ১, ২, ৩-এর বদলে ০, ৫, ১০, ১৫ ভাল হতে পারে? কিভাবে decide করবেন?

এটি subtle data-science question। Default ordinal (০-১-২-৩) "equal step" assume করে — অনেক সময় false।

Default ordinal-এর সমস্যা:

  • "primary → secondary" এক unit।
  • "graduate → post-grad" এক unit।
  • মডেল ভাবে gap সমান।
  • বাস্তব: post-grad-এ পৌঁছাতে অনেক বেশি effort, salary jump আরও বড়।

কেন ০, ৫, ১০, ১৫ better হতে পারে:

  • Standard schooling years approximate (primary ৫, secondary ১০, graduate ১৫, post-grad ১৭)।
  • Real-world quantity reflect — "years of education"।
  • Linear model এই scale-এ accurate fit।

Decision framework:

(১) Domain knowledge

  • Bangladesh-এ:
  • Primary = class 5 = ৫ years
  • Secondary = SSC = ১০ years
  • Higher Secondary = HSC = ১২ years
  • Graduate = ১৫-১৬ years
  • Post-grad = ১৭-১৮ years
  • PhD = ২২+ years

(২) Target relationship

  • Plot target vs ordinal value।
  • Non-linear — gap unequal।
  • Equal-spaced ordinal → tree model handle, linear model misfit।

(৩) Model type

  • Tree (XGBoost, RF) — order matters; spacing not。 ০-১-২-৩ ও ০-৫-১০-১৫ same।
  • Linear/NN — spacing matters। Real-world unit better।
  • NN with embedding — ordering even ignored, learn from data।

(৪) Empirical test

  • Encoding ১: ০-১-২-৩।
  • Encoding ২: ০-৫-১০-১৫।
  • Encoding ৩: target encoding।
  • Cross-validate, compare RMSE/AUC।

আরও sophisticated approach:

(ক) Optimal ordinal

  • Target-vs-category mean থেকে ordering ও spacing infer।
  • Isotonic regression।

(খ) Splines/binning

  • Education-এর exact value-এর বদলে — বিন (yrs ০-৫, ৫-১০, ১০+)।
  • Tree-friendly।

(গ) Multiple representation

  • Both: ordinal_simple ও ordinal_years।
  • Model দু'টি signal use।

Feature engineering checklist:

  • Domain expert interview — "এই category-গুলোর মধ্যে gap কত?"
  • Visualization — target vs category mean।
  • A/B test — ভিন্ন encoding।
  • Regularization-এ confirm — overfit থেকে protect।

Bangladesh-specific examples:

  • NID type: "smart, old, tin, none" → ordinal-এ smart=3, none=0; কিন্তু none ও smart-এর gap unequal।
  • Income bracket: "< 10K, 10-30K, 30-100K, 100K+" — log-scale spacing logical।
  • Mobile plan: "basic, standard, premium" → ordinal default OK।

Common mistake:

  • ML competition-এ default ০-১-২-৩ accept — never tune।
  • Top kagglers customize spacing।
  • Marginal gain — কিন্তু compound হয়।

মূল উপলব্ধি: Ordinal encoding "lazy" approach common। Domain-aware spacing model accuracy boost করে — especially linear models। Tree-এ ordering enough, কিন্তু feature engineering thoughtful — সবসময় better।

প্র ০৪ Tree-based model (XGBoost) ও linear model (Logistic Regression) — categorical encoding-এ requirement-এ কেন পার্থক্য? এর behind কী?

এটি ML interview-এর classic প্রশ্ন। Underlying mechanism বুঝলে — encoding choice intuitive।

Linear model (Logistic Regression):

  • Equation: $y = w_1 x_1 + w_2 x_2 + ... + b$।
  • প্রতিটি feature-এ একটি weight assign।
  • Linear combination।
  • Numeric encoding-এ value-এর actual magnitude meaningful।

Linear-এ label encoding-এর সমস্যা:

  • "Dhaka=0, Chattogram=1, Sylhet=2"।
  • Model: $y = w \cdot district$।
  • $w > 0$ — Sylhet (২) prediction Dhaka-র চেয়ে $2w$ বেশি।
  • "Sylhet = 2 × Chattogram" implies — false!
  • Order ও magnitude both encode — nominal-এ অর্থহীন।

One-hot ভাল কেন:

  • প্রতিটি category-র own weight: $w_{Dhaka}, w_{Chattogram}, w_{Sylhet}$।
  • Independent estimation।
  • No false ordering imposed।

Tree-based model (XGBoost, RF):

  • Decision: "feature ≤ threshold?" — true/false split।
  • Threshold value-এর only ordering matters, magnitude না।
  • "district ≤ 0.5" — Dhaka one branch, others another।
  • Tree label encoding-এ category 1 vs 2 vs 3 — split point একই কাজ করে।

Tree-এ label encoding-এর caveat:

  • Tree-এর depth অনেক — প্রতিটি category ভাল-ভাবে separate করতে।
  • "Dhaka, Chattogram, Sylhet, Khulna" ৪ category — ৩টি split দরকার।
  • One-hot-এ ১টি split-এ একটি category isolate।
  • Categorical-aware tree (LightGBM-এর native categorical, CatBoost) — direct categorical handle।

Theoretical reason — invariance:

  • Tree split monotonic transformation-এর প্রতি invariant।
  • Linear monotonic transformation-এ sensitive।
  • $x \to \log(x), \sqrt{x}, x^2$ — tree-এ same model; linear-এ ভিন্ন।

Why XGBoost ভাল categorical handle:

  • Modern XGBoost (1.5+) — enable_categorical=True।
  • LightGBM — categorical_feature=['col']।
  • CatBoost — built-in ordered target encoding।
  • Internal: optimal split for category set (Fisher's exact, etc.)।

Neural network:

  • Embedding layer — category → dense vector।
  • Vector trained jointly।
  • Similar category কাছাকাছি vector।
  • One-hot-এর "lookup table version" — but learned।

Practical guidance:

  • Logistic/Linear regression: one-hot (low card), target encoding (high card)।
  • XGBoost/RF: label encoding fine; native categorical even better।
  • LightGBM/CatBoost: categorical feature flag — automatic।
  • Neural network: embedding layer।
  • k-NN, k-Means: distance-based — one-hot must (label encoding distorts distance)।

Empirical observation:

  • Tree model with label encoding ~ one-hot — small gap।
  • Linear model: one-hot >> label encoding (significant gap)।
  • Distance-based: one-hot mandatory।

Hybrid approach:

  • Production gradient boosting + neural network ensemble।
  • Boosting: target encoded।
  • NN: embedding।
  • Different encodings — different signal।

Bangladesh ML production examples:

  • Daraz click prediction: LightGBM + native categorical।
  • bKash fraud: XGBoost + target encoding।
  • Pathao surge: linear model + one-hot district।
  • Recommender (any large platform): NN with embedding।

মূল উপলব্ধি: "Encoding × Model" interaction — ML practitioner-এর core skill। Tree-এর invariance ও linear-এর sensitivity-র underlying math মাথায় থাকলে — encoding decision intuitive। প্রতিটি model-এ optimal encoding ভিন্ন।

অনুশীলন

  1. One-hot practice: ["GP", "Robi", "Banglalink", "GP", "Teletalk"] — Pandas-এ one-hot করুন এবং ৫×৪ matrix output verify।
    import pandas as pd
    s = pd.Series(["GP","Robi","Banglalink","GP","Teletalk"])
    oh = pd.get_dummies(s)
    print(oh)

    ৫ rows × ৪ unique = ৪ binary column। প্রতিটি row-তে exactly একটি 1।

  2. Target encoding-এ leakage: ১০০ row-এর ছোট DataFrame-এ "city" ও "target" আছে। Naive (full data fit) ও K-fold target encoding দু'টিতে train accuracy compare করুন। কোনটায় inflated?
    import pandas as pd, numpy as np
    from sklearn.model_selection import KFold
    
    np.random.seed(0)
    df = pd.DataFrame({
        'city': np.random.choice(['A','B','C','D'], 100),
        'target': np.random.binomial(1, 0.3, 100)
    })
    
    # Naive (leak)
    naive = df.groupby('city')['target'].mean()
    df['naive_enc'] = df['city'].map(naive)
    
    # K-fold (proper)
    df['kfold_enc'] = 0.0
    for tr, va in KFold(n_splits=5, shuffle=True, random_state=0).split(df):
        means = df.iloc[tr].groupby('city')['target'].mean()
        df.loc[df.index[va], 'kfold_enc'] = df.iloc[va]['city'].map(means)
    
    print(df[['city','target','naive_enc','kfold_enc']].head(10))

    Naive-এ encoded value target-এর সাথে artificially correlated (leakage); K-fold version cleaner।

  3. Ordinal spacing: Bangladesh-এ "education" column "primary, SSC, HSC, graduate, post-grad" — কোন numeric value সবচেয়ে domain-realistic? Log-spaced কেন বিবেচনা?

    Years of education-এ: primary=5, SSC=10, HSC=12, graduate=16, post-grad=18।

    Log-spacing — যদি income-target হয় (log-relationship): post-grad income graduate-এর ১.৫-২× — exponential effect ধরা।

    Empirical: cross-validate দু'টি encoding — best select।

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

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