方差过滤,是机器学习特征选择的一种方法。所谓的特征选择,就是从所有特征中,选择出有意义,对模型有帮助的特征,避免将所有特征都导入模型去训练。本文以Kaggle上的手写数字识别训练集为例,来演示特征选择对模型训练时间和准确率的影响。

代码示例

1、导入数据

原始数据集共42000条数据,784个特征(原图28x28,共784个像素点),原始数据集过大,为了节省演示时间,本文对数据集做了精简,只截取前1000条数据。

import pandas as pd

data = pd.read_csv('./datas/digit_recognizor_simple.csv')
x = data.iloc[:, 1:]
y = data.iloc[:, 0]
print(x.shape, y.shape)  # (1000, 784) (1000,)

2、方差过滤

from sklearn.feature_selection import VarianceThreshold
# 默认消除方差为0的特征
x_var0 = VarianceThreshold().fit_transform(x)
print(x_var0.shape)  # (1000, 612)

# 方差中位数过滤,可以消掉大约一半的特征
import numpy as np

x_varmd = VarianceThreshold(np.median(x.var().values)).fit_transform(x)
print(x_varmd.shape)  # (1000, 391)

# 当特征为二分类时,特征的取值就是伯努利随机变量,方差var[x] = p(1-p)
# 假设p=0.8,即二分类特征中某种分类占到80%以上的时候删除特征
x_varb = VarianceThreshold(0.8 * (1 - 0.8)).fit_transform(x)
print(x_varb.shape)

3、KNN算法过滤前后比较

from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn.model_selection import cross_val_score

score = cross_val_score(KNN(), x, y, cv=5).mean()
print(score)  # 0.837  2.522 seconds

score = cross_val_score(KNN(), x_varmd, y, cv=5).mean()
print(score)  # 0.839  1.504 seconds

4、随机森林过滤前后比较

from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.model_selection import cross_val_score

score = cross_val_score(RFC(), x, y, cv=5).mean()
print(score)  # 0.880  3.795 seconds

score = cross_val_score(RFC(n_estimators=10), x_varmd, y, cv=5).mean()
print(score)  # 0.798  1.843 seconds

总结

通过以上实验可以看出,特征过滤并不一定能使预测的结果变好,如果过滤掉的是噪音,可能会变好,但如果过滤的是有效特征,结果可能会变糟糕。但特征过滤一定能降低模型的运行时间,而且算法再遍历特征时的计算越复杂,运行时间下降的越多。

KNN、决策树、支持向量机SVM、神经网络、回归算法,都需要遍历特征或者升维计算,计算量很大,所以特征过滤就尤为重要。但对于不需要遍历特征的算法,比如随机森林,其本身就会对特征进行随机选取,特征提取的作用不大。

本文为 陈华 原创,欢迎转载,但请注明出处:http://www.ichenhua.cn/read/267