Selecting the Most Relevant Features
Model-based feature selection uses a selector that is first fitted with fit(X_train, y_train) and then applied with transform(X_train) to produce a reduced feature matrix.
Predicting the Shape Before Running
This article follows a short feature selection exercise from start to finish. The exercise begins with a training set that has 80 features, and the selector reduces it to 40 features. The number of samples does not change. Before you read the explanation, try to work out what the shape of the reduced training matrix should be, and which part of the printed output would tell you that the selection worked.
What do you think happens?
A training matrix X_train has 284 samples and 80 features. After a model-based selector keeps 40 features, what is the shape of the reduced matrix X_train_l1?
Reveal answer
(284, 40)
The number of samples stays at 284, because the selector removes features, not rows. The feature count drops from 80 to 40, so the reduced matrix is 284 rows by 40 columns. Shapes are written rows first and then columns.
Fitting the Selector and Applying It
Model-based feature selection uses a selector that works in two distinct stages. First it is fitted with fit(X_train, y_train). Then it is applied with transform(X_train) to produce a reduced feature matrix. The two stages are separate, and the order between them matters.
The fit call is where the selector examines the training data. It receives both the feature matrix X_train and the target values y_train, because a model-based selector decides which features matter by using a model that is trained on those inputs and targets. The fit call changes the internal state of the selector object, but it does not return a new dataset. Nothing reduced has been produced yet at this point.
The transform call is where the decision made during fit is applied. It takes the feature matrix and returns a new array that contains only the features the selector kept. In the exercise, that result is stored in a new variable called X_train_l1, so the original X_train is left unchanged. Keeping the original and the reduced arrays in separate variables is useful when you debug, because you can compare them directly.
Reading the Shape Printouts
Shape is the most useful first check in this exercise, because it reports two facts at once: how many samples remain and how many features remain. The script prints the shape of X_train and then the shape of X_train_l1. Comparing the two printed pairs tells you exactly what the transform step did.
(284, 80)
(284, 40)- fit uses both the features and the targets, and changes the selector without returning data
- transform returns a new array and stores it in X_train_l1, leaving X_train untouched
- The two print statements are the evidence used to check the selection
X_train: 284 samples x 80 features
80 features per sample
X_train_l1: 284 samples x 40 features
40 features per sample
Checking whether a selection behaved as expected
A script prints (284, 80) for X_train and (284, 40) for X_train_l1. Did the selection behave as expected?
- 1Read the sample count
The first number is 284 in both printouts, so no rows were lost or added. The selector works on features, not on samples.
- 2Read the feature count
The second number drops from 80 to 40. That is the reduction the exercise expects.
- 3Compare with the expected result
The exercise states that the feature count drops from 80 to 40 while the 284 samples remain unchanged. The printed shapes match that expectation.
The selection behaved as expected. Samples stayed at 284 and features went from 80 to 40.
Reading the Feature Mask
After the reduced array has been checked, the exercise looks at which features were selected. The call select.get_support() returns a mask. The mask has one entry per original feature, and each entry records whether the selector kept that feature. A True entry means the feature was kept, and a False entry means it was dropped. Each cell therefore answers one question: was this feature kept?
The mask is then reshaped with mask.reshape(1, -1) before it is displayed. This turns the one-dimensional mask into a single row with one column per original feature. The matshow function draws that row as a strip of cells. The argument cmap='gray_r' selects a reversed grayscale palette in which True cells are black and False cells are white. The tick marks in the exercise run from 0 to 70 along the horizontal axis, which covers the positions of the features across the strip.
Locating a Faulty Step
When a selection script misbehaves, do not start by guessing at the cause. Compare each step's output with its expected output, beginning at the fit call and moving forward. The first step whose output differs from what you expected is where the problem starts. Later steps can only show symptoms of that earlier fault.
Mistakes Beginners Make With Selection
Common mistake Expecting fit to return the reduced dataset
Why it failsThe fit call changes the state of the selector object but does not return a new dataset.
Do this insteadStore the output of transform in a new variable, such as X_train_l1, and use that variable for the reduced data.
Common mistake Overwriting X_train with the transformed result
Why it failsThe exercise keeps the original matrix and the reduced matrix in separate variables. Overwriting X_train removes the reference point you need for comparing shapes.
Do this insteadKeep X_train unchanged and print both shapes side by side.
Common mistake Reading the mask plot's horizontal axis as sample numbers
Why it failsThe mask is a single row where each cell represents one feature, even though the source label says 'Sample index'.
Do this insteadRead the horizontal positions as feature positions and relabel the axis in your own version of the plot.
Common mistake Debugging the last printed output first
Why it failsA wrong plot may be a symptom of an earlier wrong shape or a wrong fit call.
Do this insteadCheck each step in order, beginning at fit, and stop at the first step whose output differs from what you expected.
Checking Your Reading of the Output
A selector is fitted on a training matrix with 284 samples and 80 features. The script then prints (284, 80) for X_train and (284, 40) for X_train_l1. Next, the script calls get_support() and displays the mask with matshow. Explain what changed between the two printed shapes, what stayed the same, and what a True cell in the displayed strip means.
Hints
- Compare the first number of each printed pair before comparing the second.
- Each cell of the mask corresponds to one original feature, not one sample.
- A True cell is a feature that the selector kept.
Suppose the script prints (284, 80) for X_train and (284, 80) for X_train_l1, but the mask shows some black cells and some white cells. Using the fit, transform, mask, and plot order, decide which step to check first and explain why.
Hints
- Start from the earliest step whose output might be wrong.
- Ask whether transform could have returned the full matrix.
Key Takeaways
- A model-based selector is fitted with
fit(X_train, y_train), which examines the training data and changes the selector's state without returning a dataset. transform(X_train)applies the fitted decision and returns a new reduced matrix, here X_train_l1, while the original X_train stays unchanged.- In the exercise, the sample count stays at 284 while the feature count drops from 80 to 40, so the shape printouts show whether the selection behaved as expected.
get_support()returns one True or False entry per original feature, and reshaping it into a single row lets matshow show which features were kept, with black for True and white for False.- When results are unexpected, compare each step's output with its expected output starting from fit, and stop at the first step that diverges.