趋近智
过滤方法提供了一种计算成本较低的方式,在将特征输入机器学习模型之前对其进行修剪。它们评估特征的固有属性,通常使用统计度量,而不考虑最终将使用的预测模型。最简单的过滤技术之一是基于特征方差的。
方差阈值处理的核心思想直观明了:在数据集中变化很小的特征不太可能提供有效信息。如果一个特征对于几乎所有样本都具有相同的值,那么它提供的用于区分样本的信息将非常少。在极端情况下,方差为零的特征在所有样本中都是恒定的,显然无法帮助模型进行预测。
移除低方差特征是一个基本的数据清理步骤。通过消除恒定或接近恒定的特征,我们可以降低数据集的维度,可能加快模型训练并降低复杂性,而不会显著影响性能。
回想一下,特征 X 的方差衡量其值相对于均值 (μ) 的离散程度。其计算方式如下:
方差(X)=N1∑i=1N(xi−μ)2
这里 N 是样本数量,而 xi 是第 i 个样本的特征值。方差接近零表明数据点紧密地聚集在均值附近。
对于二元特征(取值 0 或 1),方差计算为 p(1−p),这里 p 是取值为 1 的样本比例。如果 p 接近 0 或 1(这意味着特征几乎总是 0 或几乎总是 1),方差将接近 0。
Scikit-learn 在其 feature_selection 模块中提供了 VarianceThreshold 转换器以实现此目的。
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
# 包含低方差特征的样本数据
data = {
'feat1': [0.1, 0.12, 0.09, 0.11, 0.1], # 低方差数值特征
'feat2': [10, 12, 9, 110, 50], # 高方差数值特征
'feat3': [0, 0, 0, 0, 0], # 零方差(常数)
'feat4': [1, 1, 1, 1, 0], # 低方差二元特征(大多为1)
'feat5': [0, 1, 0, 1, 0] # 较高方差二元特征
}
df = pd.DataFrame(data)
print("原始 DataFrame:")
print(df)
print("\n方差:")
print(df.var())
# 1. 移除零方差特征(默认阈值=0)
selector_zero = VarianceThreshold(threshold=0.0)
df_zero_removed = selector_zero.fit_transform(df)
# 获取选定列的名称
cols_zero_removed = selector_zero.get_feature_names_out(input_features=df.columns)
df_zero_removed = pd.DataFrame(df_zero_removed, columns=cols_zero_removed)
print("\n移除零方差特征后的 DataFrame:")
print(df_zero_removed)
# 2. 移除方差低于特定阈值(例如,0.1)的特征
# 注意:对于非布尔特征,如果它们处于不同的尺度上,请先考虑进行缩放。
# 这里,我们直接应用它作为演示。
selector_low = VarianceThreshold(threshold=0.1) # 示例阈值
df_low_removed = selector_low.fit_transform(df)
cols_low_removed = selector_low.get_feature_names_out(input_features=df.columns)
df_low_removed = pd.DataFrame(df_low_removed, columns=cols_low_removed)
print("\n移除方差 < 0.1 的特征后的 DataFrame:")
print(df_low_removed)
输出:
Original DataFrame:
feat1 feat2 feat3 feat4 feat5
0 0.10 10 0 1 0
1 0.12 12 0 1 1
2 0.09 9 0 1 0
3 0.11 110 0 1 1
4 0.10 50 0 0 0
Variances:
feat1 0.000130
feat2 1813.200000
feat3 0.000000
feat4 0.160000
feat5 0.240000
dtype: float64
DataFrame after removing zero-variance features:
feat1 feat2 feat4 feat5
0 0.10 10.0 1.0 0.0
1 0.12 12.0 1.0 1.0
2 0.09 9.0 1.0 0.0
3 0.11 110.0 1.0 1.0
4 0.10 50.0 0.0 0.0
DataFrame after removing features with variance < 0.1:
feat2 feat4 feat5
0 10.0 1.0 0.0
1 12.0 1.0 1.0
2 9.0 1.0 0.0
3 110.0 1.0 1.0
4 50.0 0.0 0.0
在第一步中,使用默认 threshold=0.0,VarianceThreshold 找到并移除了 feat3,因为它是一个常数特征。
在第二步中,将 threshold 设置为 0.1,它移除了 feat1(方差约 0.00013)和 feat3(方差 0),保留了 feat2、feat4 和 feat5,因为它们的方差高于 0.1。
VarianceThreshold 之前,先对特征进行缩放(例如,使用 StandardScaler 或 MinMaxScaler)。 否则,你可能会因为特征单位导致数值较小而错误地舍弃它们。默认的阈值 0(移除常数特征)不需要事先缩放。VarianceThreshold 只查看特征 (X) 本身的方差;它不考虑特征与目标变量 (y) 之间的任何关系。在少数情况下,低方差特征仍可能具有预测性。反之,高方差特征可能与目标完全无关。方差阈值处理作为一种基本的合理性检查和预处理步骤,对于快速移除明显无信息量的特征(尤其是常数特征)很有用。它通常用作在应用更复杂的特征选择技术之前的初步筛选。
这部分内容有帮助吗?
VarianceThreshold 转换器的官方文档,提供使用示例和参数详细信息。© 2026 ApX Machine Learning用心打造