数据预处理之方差过滤
在机器学习的数据预处理的过程中常常会是使用到过滤法,而方差过滤是过滤法之一。所谓的方差过滤就是过滤掉那些特征方差较小的特征。比如一个特征本身的方差很小,就表示样本在这个特征上基本没有差异,可能特征中的大多数值都一样,甚至整个特征的取值都相同,那这个特征对于样本区分没有什么作用。所以可以设置一个过滤的阈值,过滤掉那些方差小的特征,从而达到特征筛选的目的。
在 sklearn中可以调用from sklearn.feature_selection import VarianceThreshold 类实现方差过滤。
这里要重点介绍一下方差过滤的坑,如果不假思索的就是随随便便的使用方差过滤进行特征的筛选,可能将重要的特征过滤掉 ,由于,每个特征的取值的范围与取值的大小是不一样,这样的话就会使得各个特征的方差差距很大(因为这样算的是特征的绝对方差)。例如特征X1代表收入(元),那么范围可能是[0,10000亿],是一个巨大取值的范围,特征X2代表人的年龄(岁),那么范围可能是[0,150],取值范围X1的小很多, 那么X2的方差可能要比X1小很多,但是这并不能代表X2的重要性就比X1要小。所以,使用方差过滤会使得重要的特征被误删。
接下来,举例说明:
这里使用sklearn自带的boston数据集做一个回归问题。
from sklearn.decomposition import PCA
from sklearn.datasets import load_boston
from sklearn.feature_selection import VarianceThreshold
from xgboost import XGBRegressor
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
import joblib
bc = load_boston()
X = pd.DataFrame(bc.data)
X.columns = bc.feature_names
y = bc.target
boston 数据的部分数据展示,一共有13个特征变量。
以 方差阈值为 0.5进行特征筛选。
vt = VarianceThreshold(threshold=0.5)
X_vt = pd.DataFrame(vt.fit_transform(X),columns=X.columns[vt.get_support()] )
方差过滤后的特征变量
对比一下,可以发现 “CHAS”、“NOX”、 “RM”特征变量被过滤掉了,但是
这些特征的并不一定是不重要的。接下来我们看看,这13个特征的重要性排序,来验证一下,刚才被删除的3个特征是不是应该被删除。
我们这里是 树模型的feature_importances_属性,对特征进行排序。
model = XGBRegressor()
model.fit(X,y)
fea_imp = pd.DataFrame(zip(X.columns,xgbr.feature_importances_),columns=["feature","importances_"])
fea_imp.sort_values(by="importances_",ascending=False)
对特征重要性排序之后,发现“RM”是第二重要的特征变量,但是在方差过滤的时候却被删除了,很显然这是有问题的。
总结
那么,我们应该如何使用方差过滤。我得建议是 方差过滤可以使用在巨大的稀疏矩阵中,稀疏矩阵中可以考虑将方差的过滤阈值设置为0,这样就会将稀疏矩阵中大量特征值为0的特征过滤掉,比如著名的手写数据集里面是一个巨大的稀疏矩阵,可以使用方差过滤做一个初步的过滤。对于本文的boston数据集,一共才13个特征就最好不要使用方差过滤了。