Feature Engineering 特征工程 4. Feature Selection
learn from
发布日期:2021-07-01 03:25:56
浏览次数:2
分类:技术文章
本文共 4761 字,大约阅读时间需要 15 分钟。
文章目录
上一篇:
经过各种编码和特征生成后,通常会拥有成百上千个特征。这可能导致两个问题:
- 首先,拥有的特征越多,就越有可能过拟合
- 其次,拥有的特征越多,训练模型和优化超参数所需的时间就越长。使用较少的特征可以加快预测速度,但会降低预测准确率
为了解决这些问题,使用特征选择技术来为模型保留最丰富的特征
1. Univariate Feature Selection 单变量特征选择
最简单,最快的方法是基于单变量
统计检验
- 统计
label
对每个单一特征的依赖程度 - 在
scikit-learn
特征选择模块中,feature_selection.SelectKBest
返回 K 个最佳特征 - 对于分类问题,该模块提供了三种不同的评分功能: χ 2 \chi^2 χ2,
ANOVA F-value
和mutual information score
F-value
测量特征变量和目标之间的线性相关性。这意味着如果是非线性关系,得分可能会低估特征与目标之间的关系mutual information score
是非参数的,可以捕获非线性关系
from sklearn.feature_selection import SelectKBest, f_classiffeature_cols = baseline_data.columns.drop('outcome')# Keep 5 features 保留5个最好的特征selector = SelectKBest(f_classif, k=5) # 评价函数, 保留特征数量X_new = selector.fit_transform(baseline_data[feature_cols], baseline_data['outcome']) # 特征, 标签X_new
array([[2015., 5., 9., 18., 1409.], [2017., 13., 22., 31., 957.], [2013., 13., 22., 31., 739.], ..., [2010., 13., 22., 31., 238.], [2016., 13., 22., 31., 1100.], [2011., 13., 22., 31., 542.]])
但是,上面犯了严重的错误,特征选择时fit
,把所有数据用进去了,会造成
fit
,选择特征 feature_cols = baseline_data.columns.drop('outcome')train, valid, _ = get_data_splits(baseline_data)# Keep 5 featuresselector = SelectKBest(f_classif, k=5)X_new = selector.fit_transform(train[feature_cols], train['outcome']) # 区别,仅用 训练集X_new
array([[2.015e+03, 5.000e+00, 9.000e+00, 1.800e+01, 1.409e+03], [2.017e+03, 1.300e+01, 2.200e+01, 3.100e+01, 9.570e+02], [2.013e+03, 1.300e+01, 2.200e+01, 3.100e+01, 7.390e+02], ..., [2.011e+03, 1.300e+01, 2.200e+01, 3.100e+01, 5.150e+02], [2.015e+03, 1.000e+00, 3.000e+00, 2.000e+00, 1.306e+03], [2.013e+03, 1.300e+01, 2.200e+01, 3.100e+01, 1.084e+03]])
- 可以看见,两种情况下,选择了不同的特征
- 现在,我们需要把得到的特征数值,转换回去,并丢弃其他未选择的特征
# Get back the features we've kept, zero out all other featuresselected_features = pd.DataFrame(selector.inverse_transform(X_new), index=train.index, columns=feature_cols)selected_features.head()
goal | hour | day | month | year | category | currency | country | category_currency | category_country | currency_country | count_7_days | time_since_last_project | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 0.0 | 2015.0 | 0.0 | 5.0 | 9.0 | 0.0 | 0.0 | 18.0 | 1409.0 | 0.0 |
1 | 0.0 | 0.0 | 0.0 | 0.0 | 2017.0 | 0.0 | 13.0 | 22.0 | 0.0 | 0.0 | 31.0 | 957.0 | 0.0 |
2 | 0.0 | 0.0 | 0.0 | 0.0 | 2013.0 | 0.0 | 13.0 | 22.0 | 0.0 | 0.0 | 31.0 | 739.0 | 0.0 |
3 | 0.0 | 0.0 | 0.0 | 0.0 | 2012.0 | 0.0 | 13.0 | 22.0 | 0.0 | 0.0 | 31.0 | 907.0 | 0.0 |
4 | 0.0 | 0.0 | 0.0 | 0.0 | 2015.0 | 0.0 | 13.0 | 22.0 | 0.0 | 0.0 | 31.0 | 1429.0 | 0.0 |
- 我们发现逆转换回去后,未被选择的特征都是
0.0
,需要丢弃它们
# Dropped columns have values of all 0s, so var is 0, drop them# 保留方差不为0的selected_columns = selected_features.columns[selected_features.var() != 0]# Get the valid dataset with the selected features.valid[selected_columns].head()
year | currency | country | currency_country | count_7_days | |
---|---|---|---|---|---|
302896 | 2015 | 13 | 22 | 31 | 1534.0 |
302897 | 2013 | 13 | 22 | 31 | 625.0 |
302898 | 2014 | 5 | 9 | 18 | 851.0 |
302899 | 2014 | 13 | 22 | 31 | 1973.0 |
302900 | 2014 | 5 | 9 | 18 | 2163.0 |
2. L1 regularization L1正则
单变量方法在做出选择决定时一次只考虑一个特征
相反,我们可以通过将所有特征包括在具有的线性模型中来使用所有特征进行特征筛选
与惩罚系数平方的 L2(Ridge)回归相比,这种类型的正则化(有时称为Lasso)会惩罚系数的绝对大小
随着L1正则化强度的提高
,对于预测目标而言次要的特征将设置为0
对于回归问题,可以使用sklearn.linear_model.Lasso
sklearn.linear_model.LogisticRegression
这些都可以跟sklearn.feature_selection.SelectFromModel
一起使用,来选择非零系数 from sklearn.linear_model import LogisticRegressionfrom sklearn.feature_selection import SelectFromModeltrain, valid, _ = get_data_splits(baseline_data)X, y = train[train.columns.drop("outcome")], train['outcome']# Set the regularization parameter C=1logistic = LogisticRegression(C=1, penalty="l1", random_state=7).fit(X, y)model = SelectFromModel(logistic, prefit=True)X_new = model.transform(X)X_new
array([[1.000e+03, 1.200e+01, 1.100e+01, ..., 1.900e+03, 1.800e+01, 1.409e+03], [3.000e+04, 4.000e+00, 2.000e+00, ..., 1.630e+03, 3.100e+01, 9.570e+02], [4.500e+04, 0.000e+00, 1.200e+01, ..., 1.630e+03, 3.100e+01, 7.390e+02], ..., [2.500e+03, 0.000e+00, 3.000e+00, ..., 1.830e+03, 3.100e+01, 5.150e+02], [2.600e+03, 2.100e+01, 2.300e+01, ..., 1.036e+03, 2.000e+00, 1.306e+03], [2.000e+04, 1.600e+01, 4.000e+00, ..., 9.200e+02, 3.100e+01, 1.084e+03]])
类似于单变量测试,返回具有选定特征的数组。我们要将它们转换为DataFrame,以便获得选定的特征列
# Get back the kept features as a DataFrame with dropped columns as all 0sselected_features = pd.DataFrame(model.inverse_transform(X_new), index=X.index, columns=X.columns)# Dropped columns have values of all 0s, keep other columns selected_columns = selected_features.columns[selected_features.var() != 0]
- 通常,使用L1正则化进行特征选择比单变量测试更强大
- 但是在具有大量数据和大量特征的情况下,L1正则化的特征选择速度也会很慢
- 在大型数据集上,单变量测试将更快,但预测性能可能会更差
完成课程和练习,获得,继续加油!🚀🚀🚀
上一篇:
转载地址:https://michael.blog.csdn.net/article/details/106246932 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月11日 23时26分38秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java并发编程(三)----线程的同步
2021-07-06
java并发编程(四)----(JUC)Lock锁初探
2021-07-06
java并发编程(五)----(JUC)ReentrantLock
2021-07-06
java并发编程(六)----(JUC)Semaphore
2021-07-06
java并发编程(七)----(JUC)ReadWriteLock
2021-07-06
java并发编程(八)----(JUC)CountDownLatch
2021-07-06
java并发编程(九)----(JUC)CyclicBarrier
2021-07-06
java并发编程(十)----JUC原子类介绍
2021-07-06
java并发编程(十一)----(JUC原子类)基本类型介绍
2021-07-06
java并发编程(十二)----(JUC原子类)数组类型介绍
2021-07-06
java并发编程(十三)----(JUC原子类)引用类型介绍(CAS和ABA的介绍)
2021-07-06
java并发编程(十四)----(JUC原子类)对象的属性修改类型介绍
2021-07-06
java并发编程(十五)----(线程池)java线程池简介
2021-07-06
java并发编程(十六)----(线程池)java线程池的使用
2021-07-06
java并发编程(十七)----(线程池)java线程池架构和原理
2021-07-06
java并发编程(十八)----(线程池)java线程池框架Fork-Join
2021-07-06
java并发编程(十九)----(JUC集合)总体框架介绍
2021-07-06
Netty学习(四)-TCP粘包和拆包
2021-07-06
Netty学习(五)-DelimiterBasedFrameDecoder
2021-07-06