特征工程之特征选择----方差过滤
Posted iostreamzl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了特征工程之特征选择----方差过滤相关的知识,希望对你有一定的参考价值。
文章目录
特征工程概述
特征工程(feature engineering)是将原始数据转换为更能代表预测模型的潜在问题的特征的过程。
特征工程的三个步骤
- 特征提取:从文字、图形、声音等其他非结构化数据中提取信息作为新的特征,
比如从淘宝商品的名称中提取出产品类别,颜色,是否网红产品等 - 特征创造:把现有特征进行组合或计算,得到新的特征
比如有一个特征速度v,和一个特征距离s,可以通过s/v运算创造一个新的特征时间t - 特征选择:从所有特征中选择出有意义的,对模型有用的,避免必须将所有特征导入模型的情况
特征选择之前的注意事项
和数据提供者开会!和数据提供者开会!和数据提供者开会!
一定要抓住提供数据的人,尤其是理解业务和数据含义的人,跟他们多了解一下数据。
技术是模型起飞的保障,但是对数据的理解是模型的基础。
正常情况下特征选择的第一步就是根据我们的目标,用业务常识来选择特征。
在某些特殊情况下,我们对数据完全不了解,不知道每一个特征的意义
这样的情况下我们就不能通过我们的常识来进行特征选择。
这种情况下,我们有4种特征选择方法:过滤法,嵌入法,包装法,和降维算法
方差过滤法
通过特征本身的方差来筛选特征,
一个特征的方差越小,表明,该特征的变化越不明显,
变化越不明显的特征对我们区分标签没有太大的作用所以应该消除这些特征
示例
数据下载
本次采用的数据集是kaggle上的digit-recognizer数据集,原始数据下载地址
快捷下载。
导入相关模块
from sklearn.feature_selection import VarianceThreshold # 方差过滤
from sklearn.model_selection import cross_val_score # 交叉检验
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier as KNN
import pandas as pd
import numpy as np
加载数据
file_name = "E://anaconda/machine-learning/test1/data/digit-recognizer/train.csv"
df = pd.read_csv(file_name)
df.shape # (42000, 785)
df.head()
# 一共有784个特征,维度相当高,可以预见模型极其耗时
特征标签分离
# 取出特征
X = df.loc[:, df.columns != 'label']
# 取出标签
y = df['label'].values
删除方差为0的特征
# 删除方差为0的特征
vt0 = VarianceThreshold()
X_var0 = vt0.fit_transform(X)
X_var0.shape
# (42000, 708)
get_support()方法查看特征的删除情况
# get_support(indices=False)
# 用于查看每个属性被过滤的情况,
# indices=False默认返回一个boolean数组,表明每一个特征是否被过滤
# indices=True返回每个留下的特征的索引
vt0.get_support(indices=True).shape
# (708,)
设置阈值,删除特征
# 这里删除的特征还是太少了,我们可以考虑设置一个阈值
# 将方不高于于阈值的特征的都删除
# r比如要删除一半的特征,可以将阈值threshold设置为方差中位数
# X.var() 获得每一列的方差,返回series通过values转化为数组
var_median = np.median(X.var().values)
vt_median = VarianceThreshold(threshold=var_median)
X_var_median = vt_median.fit_transform(X)
X_var_median.shape
# (42000, 392)
方差过滤对模型的影响
模型创建
rfc = RandomForestClassifier(n_estimators=21, random_state=1)
对随机森林的影响
原始数据的运行时间与表现
jupyter的常用魔法方法戳这里
%time rf_score_raw = cross_val_score(rfc, X, y, cv=5).mean()
rf_score_raw
# Wall time: 22.3 s
# 0.9537144535447716
这里用时22秒,你可能会觉得有点长,但是见识到KNN的运行时间,你会觉得随机森林是多么的强大
过滤后的运行时间与表现
%time rf_score_var_median_filter = cross_val_score(rfc, X_var_median, y, cv=5).mean()
rf_score_var_median_filter
# Wall time: 19.3 s
# 0.9538102330776624
时间快了几秒钟,看起来提升不大,这是因为随机森林模型很优秀,下面KNN的提升一定会让你大吃一惊
对KNN模型的影响
模型的创建
knn = KNN()
原始数据的运行时间与表现
%time knn_score_raw = cross_val_score(knn, X, y, cv=5).mean()
knn_score_raw
# Wall time: 31min 25s
# 0.9658569700264943
啊,这个时间简直恐怖半个小时,这只是运行一次交叉检验的时间,有时间的小伙伴可以考虑%%timeit 这个魔法方法,运行多次语句求平均时间。大概也就花几个小时吧(卑微)。
过滤后的运行时间与表现
%time knn_score_var_median_filter = cross_val_score(knn, X_var_median, y, cv=5).mean()
knn_score_var_median_filter
# Wall time: 16min 11s
# 0.9659997478150573
效果还不错,几乎是少了一半的时间,但是也是好耗时,啊啊啊。
这里精确率上升了一点点,时间减半,看来过滤特征的操作取得了较大的成功的。
可以看到精确率与随机森林相差不是很大,但是这时间差距真的不忍直视啊,随机森林还是没有调参的情况。所以说选择什么模型心里有数了吧。
选取超参数threshold
我们怎样知道,方差过滤掉的到底时噪音还是有效特征呢?过滤后模型到底会变好还是会变坏呢?
答案是:每个数据集不一样,只能自己去尝试。这里的方差阈值,其实相当于是一个超参数,要选定最优的超参数,我们可以画学习曲线,找模型效果最好的点。但现实中,我们往往不会这样去做,因为这样会耗费大量的时间。我们只会使用阈值为0或者阈值很小的方差过滤,来为我们优先消除一些明显用不到的特征,然后我们会选择更优的特征选择方法继续削减特征数量
方差过滤的影响总结
阈值很小 | 阈值比较大 | |
---|---|---|
特征过滤情况 | 少 | 多 |
对模型表现的影响 | 没有太大影响 | 肯表现很好,表明被过滤的特征中大多数都是噪声 模型表现糟糕,表明过滤的特征中有很多都是必要的特征 |
运行时间 | 可能降低运行时间,基于被过滤掉特征的多少 | 一定能降低运行时间,算法计算越复杂,降低越明显 |
再一次感觉到了随机森林的强大。。。。。
以上是关于特征工程之特征选择----方差过滤的主要内容,如果未能解决你的问题,请参考以下文章
机器学习实战基础(十六):sklearn中的数据预处理和特征工程特征选择 之 Filter过滤法 总结
机器学习实战基础(十六):sklearn中的数据预处理和特征工程特征选择 之 Filter过滤法 总结