Feature Engineering 特征工程 4. Feature Selection
发布日期:2021-07-01 03:25:56 浏览次数:3 分类:技术文章

本文共 4761 字,大约阅读时间需要 15 分钟。

文章目录

learn from

上一篇:


经过各种编码和特征生成后,通常会拥有成百上千个特征。这可能导致两个问题:

  • 首先,拥有的特征越多,就越有可能过拟合
  • 其次,拥有的特征越多,训练模型和优化超参数所需的时间就越长。使用较少的特征可以加快预测速度,但会降低预测准确率

为了解决这些问题,使用特征选择技术来为模型保留最丰富的特征

1. Univariate Feature Selection 单变量特征选择

最简单,最快的方法是基于单变量统计检验

  • 统计label对每个单一特征的依赖程度
  • scikit-learn特征选择模块中,feature_selection.SelectKBest返回 K 个最佳特征
  • 对于分类问题,该模块提供了三种不同的评分功能: χ 2 \chi^2 χ2ANOVA F-valuemutual 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:LeetCode 662. 二叉树最大宽度(递归)
下一篇:Feature Engineering 特征工程 3. Feature Generation

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年05月06日 17时02分36秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章