0Pricing
Machine Learning Academy · บทเรียน

การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest

ผู้เรียนจะลบคุณลักษณะที่มีความแปรปรวนเกือบเป็นศูนย์ จากนั้นจัดอันดับคุณลักษณะที่เหลือด้วยการทดสอบทางสถิติแบบตัวแปรเดียว และเก็บไว้เฉพาะ K อันดับแรกที่ให้ข้อมูลมากที่สุด

การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest เป็นบทเรียน Machine Learning Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Machine Learning Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

Why Remove Features?

Adding more features is not always better. Irrelevant features add noise without signal, increasing the risk of overfitting, slowing training, and wasting memory. Redundant features provide duplicate information and can destabilise some models. Feature selection identifies and removes these unhelpful inputs, leaving a compact set of informative features. The result: faster training, lower memory usage, reduced overfitting, and often better generalisation — especially for models without built-in regularisation like KNN or Naive Bayes.

Variance Threshold: Remove Near-Constant Features

VarianceThreshold removes features whose variance falls below a specified threshold. A feature with zero variance is constant — it has the same value for every example and therefore provides no discriminative information. Near-constant features (very low variance) are almost as uninformative. Setting threshold=0 removes only perfectly constant features; threshold=0.01 removes any feature where 99%+ of values are the same. This is a fast, model-agnostic first pass at cleaning the feature set.

from sklearn.feature_selection import VarianceThreshold
import numpy as np

# Create feature matrix with some constant/near-constant columns
X = np.array([
    [1, 2, 1, 5],   # col 3: near constant (mostly 1)
    [2, 4, 1, 3],
    [3, 6, 1, 4],
    [4, 8, 2, 7],   # col 3 varied
    [5, 10, 1, 2]
], dtype=float)
print('Column variances:', X.var(axis=0).round(2))

vt = VarianceThreshold(threshold=0.5)  # remove columns with variance < 0.5
X_filtered = vt.fit_transform(X)
print('Features kept:', vt.get_support())
print('X shape before:', X.shape, '-> after:', X_filtered.shape)

Applying Variance Threshold to Real Data

Variance threshold is especially useful after one-hot encoding, when some categories may have very few examples (producing a near-zero-variance binary column) or when working with genomics, text, or sensor data where most features are near-zero. Set the threshold based on the expected proportion of zeros: if 95% of values are zero, the variance is at most 0.95 × 0.05 = 0.0475, so threshold=0.05 removes any feature that is at least 95% constant.

from sklearn.feature_selection import VarianceThreshold
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
print('Original n_features:', X.shape[1])
vt = VarianceThreshold(threshold=10.0)  # remove low-variance features
X_filtered = vt.fit_transform(X)
print('After threshold=10.0, n_features:', X_filtered.shape[1])
print('Removed features:', (~vt.get_support()).sum())

SelectKBest: Rank by Statistical Test

SelectKBest evaluates each feature independently using a univariate statistical test and keeps the top K features. For classification: use chi2 (chi-squared, for non-negative features) or f_classif (ANOVA F-statistic). For regression: use f_regression (linear correlation) or mutual_info_regression. The tests score how much each feature individually correlates with the target. Setting k='all' ranks all features by score rather than selecting a fixed number.

from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
skb = SelectKBest(score_func=f_classif, k=10)
X_new = skb.fit_transform(X, y)
print('Original shape:', X.shape)
print('After SelectKBest(k=10):', X_new.shape)
print('Top feature mask:', skb.get_support())
scores = skb.scores_
top5_idx = np.argsort(scores)[::-1][:5]
print('Top 5 feature indices:', top5_idx)
print('Top 5 F-scores:', np.round(scores[top5_idx], 2))

Mutual Information: Non-Linear Scoring

The F-test in f_classif only detects linear relationships between features and target. Mutual information (mutual_info_classif, mutual_info_regression) measures any statistical dependence — linear or non-linear. A feature with a non-linear relationship to the target will score zero with F-test but high with mutual information. Mutual information is slower to compute but more informative, especially for tree-based models where non-linear relationships matter.

from sklearn.feature_selection import SelectKBest, mutual_info_classif, f_classif
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
feature_names = load_breast_cancer().feature_names

# Compare F-test and mutual information rankings
f_scores = f_classif(X, y)[0]
mi_scores = mutual_info_classif(X, y, random_state=42)

import pandas as pd
df = pd.DataFrame({'feature': feature_names, 'f_score': f_scores, 'mi_score': mi_scores})
print('Top 5 by F-test:'); print(df.sort_values('f_score', ascending=False).head(5)['feature'].values)
print('Top 5 by MI:   '); print(df.sort_values('mi_score', ascending=False).head(5)['feature'].values)

Selecting K: Cross-Validation Over Feature Counts

How many features should you keep? The right way to choose K is to treat it as a hyperparameter and find the value that maximises cross-validation score. Use SelectKBest inside a Pipeline and add selectkbest__k to your grid search parameters. This avoids the common mistake of selecting K based on training performance (which always improves with more features) and instead finds the K that maximises generalisation.

from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)
pipe = Pipeline([('sel', SelectKBest(f_classif)), ('clf', LogisticRegression(max_iter=1000))])
param_grid = {'sel__k': [5, 10, 15, 20, 30]}
grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(X, y)
print('Best k:', grid.best_params_['sel__k'])
print('Best CV score:', round(grid.best_score_, 4))

SelectPercentile: Relative Feature Selection

SelectPercentile is a sibling of SelectKBest that keeps the top percentile% of features rather than a fixed count K. This is more robust when the number of features varies across datasets or when applying the same pipeline to different problems. For example, SelectPercentile(f_classif, percentile=20) keeps the best 20% of features regardless of how many there are. The trade-off: you get a relative budget rather than an absolute count.

from sklearn.feature_selection import SelectPercentile, f_classif
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)
for pct in [20, 50, 80]:
    sel = SelectPercentile(f_classif, percentile=pct)
    X_new = sel.fit_transform(X, y)
    print(f'percentile={pct}: kept {X_new.shape[1]} of {X.shape[1]} features')

Feature Selection vs Regularisation

Feature selection and regularisation are complementary but different approaches. Feature selection explicitly removes features before training, producing a sparser model with fewer inputs. Regularisation (L1/L2 penalty) keeps all features but shrinks unimportant coefficients toward zero — L1 (Lasso) even produces exact zeros. Feature selection is explicit and interpretable; regularisation is continuous and keeps more information. For interpretability, explicit feature selection is preferred. For predictive power, regularisation often wins by making soft, data-driven importance decisions.

Limitation: Features Are Not Independent

The key limitation of univariate selection (VarianceThreshold, SelectKBest) is that it evaluates each feature independently. A feature that has no marginal correlation with the target might still be very useful in combination with another feature (interaction). Two redundant features might each score high individually but add no value beyond the first one. These methods cannot detect such dependencies. Recursive Feature Elimination (RFECV), covered in the next lesson, addresses this by letting the model itself rank features based on their combined predictive contribution.

Practical Workflow for Feature Selection

A recommended feature selection workflow: (1) Start with VarianceThreshold to remove constant and near-constant features; (2) apply SelectKBest with mutual information for a quick ranking of remaining features; (3) plot CV score vs K to find the elbow; (4) incorporate the selected features in a full pipeline with cross-validation; (5) if the model has built-in importance (tree-based), use permutation importance for a second-pass check. Always embed selection inside a Pipeline to prevent leakage.

from sklearn.feature_selection import VarianceThreshold, SelectKBest, f_classif
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)
pipe = Pipeline([
    ('vt', VarianceThreshold(threshold=0.1)),   # step 1
    ('sel', SelectKBest(f_classif, k=15)),       # step 2
    ('clf', RandomForestClassifier(n_estimators=100, random_state=42))
])
scores = cross_val_score(pipe, X, y, cv=5)
print('Pipeline CV score:', round(scores.mean(), 4))

SelectFromModel: Let the Model Decide

SelectFromModel uses a trained model's feature importances (or coefficients) to select features above a threshold. After fitting a random forest or Lasso, pass it to SelectFromModel with a threshold such as 'mean' (keep features with importance above the mean) or 'median'. This is especially useful as a pipeline step before a secondary estimator — it embeds the importance-based selection directly into the cross-validation loop, preventing leakage.

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import Pipeline

X, y = load_breast_cancer(return_X_y=True)
pipe = Pipeline([
    ('sel', SelectFromModel(RandomForestClassifier(n_estimators=50, random_state=42), threshold='mean')),
    ('clf', RandomForestClassifier(n_estimators=100, random_state=42))
])
scores = cross_val_score(pipe, X, y, cv=5)
print('SelectFromModel CV:', round(scores.mean(), 4))

Quick Check

Test your understanding of VarianceThreshold and SelectKBest from this lesson.

Lesson Recap

In this lesson you learned: VarianceThreshold removes constant and near-constant features as a fast first pass, SelectKBest ranks features by univariate tests (F-test or mutual information) and keeps the top K, and always embed feature selection inside a Pipeline and cross-validate K as a hyperparameter. Next up we explore Recursive Feature Elimination with Cross-Validation (RFECV), which lets the model itself vote out the least useful features.

คำถามที่พบบ่อย

บทเรียน “การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Machine Learning Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest”

ผู้เรียนจะลบคุณลักษณะที่มีความแปรปรวนเกือบเป็นศูนย์ จากนั้นจัดอันดับคุณลักษณะที่เหลือด้วยการทดสอบทางสถิติแบบตัวแปรเดียว และเก็บไว้เฉพาะ K อันดับแรกที่ให้ข้อมูลมากที่สุด คุณปฏิบัติ Machine Learning Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Machine Learning Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Machine Learning Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Machine Learning Academy นี้ได้ไหม

ได้ บทเรียน Machine Learning Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างคุณลักษณะใหม่: การแปลงลอการิทึม การจัดกลุ่มช่วง และปฏิสัมพันธ์
  2. การสกัดคุณลักษณะจากวันที่และเวลา
  3. การคัดเลือกคุณลักษณะ: เกณฑ์ความแปรปรวนและ SelectKBest
  4. การตัดคุณลักษณะแบบวนซ้ำด้วยการตรวจสอบไขว้
← กลับไปที่ Machine Learning Academy