文章目录
1. Univariate Feature Selection 单变量特征选择2. L1 regularization L1正则learn from /learn/feature-engineering
上一篇:Feature Engineering 特征工程 3. Feature Generation
经过各种编码和特征生成后,通常会拥有成百上千个特征。这可能导致两个问题:
首先,拥有的特征越多,就越有可能过拟合其次,拥有的特征越多,训练模型和优化超参数所需的时间就越长。使用较少的特征可以加快预测速度,但会降低预测准确率
为了解决这些问题,使用特征选择技术来为模型保留最丰富的特征
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([[., 5., 9., 18., 1409.],[., 13., 22., 31., 957.],[., 13., 22., 31., 739.],...,[., 13., 22., 31., 238.],[., 13., 22., 31., 1100.],[., 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()
我们发现逆转换回去后,未被选择的特征都是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()
2. L1 regularization L1正则
单变量方法在做出选择决定时一次只考虑一个特征
相反,我们可以通过将所有特征包括在具有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正则化的特征选择速度也会很慢在大型数据集上,单变量测试将更快,但预测性能可能会更差
完成课程和练习,获得证书一张,继续加油!🚀🚀🚀
上一篇:Feature Engineering 特征工程 3. Feature Generation