iOS14iCloud云盘为何删除文稿和数据不好用_5个特征选择算法,让你的数据处理得心应手...

be73b20d1fbb69d262e52d93e87d7bd2.png
全文共 5462字,预计学习时长 11分钟

cbe7599779f3b08ca54812b575a7ba9f.png
图片来源:https://unsplash.com/@seefromthesky

数据科学是研究算法的学问。本文将会介绍一些处理数据时最常用的特征选择技术。

我们经常遇到这样的情况:在创建了大量特征后,又需要减少数量,最后再使用相关性或者基于树的方法来找出其中的重要特征。那么,如何让这些方法变得更有结构呢?

81a7d4bc2788dee21a32621056377be5.png

为何要进行特征选择?

在文章开始之前,先来回答这个问题:为什么不将所有的特征都交给机器学习算法,让它来决定哪些特征比较重要呢?

以下便是不能的三个原因:

1. 维数的诅咒——过拟合

e70980352e481dfb1115d64b9b205442.png

维数的诅咒:随着特征空间维数的增加,配置数量将会以指数级增长,因此观测量会下降

如果数据中的列数多于行数,就能完美匹配训练数据,但这却并不适用于新样本。因此这样什么也没学到。

2. 奥卡姆剃刀原理

模型应当简单易懂。如果特征太多,就失去了可解释性。

3. 无用输入和输出

很多时候会出现像名称或ID变量等非信息特征。劣质输入也会产生劣质输出。

此外,大量特征会使模型量大、耗时,更难落实生产。

81a7d4bc2788dee21a32621056377be5.png

那应该怎么做?

f5660084bd3a0fdfc34f000f1dc415aa.png

答案是:只选择有用特征。

幸运的是,Scikit-learn能便捷简单地选择特征。特性选择有很多种方法,但是大多可以分为三类:

• 过滤:列入一些筛选特征的标准,如相关性/卡方分布。

• 包装:包装法将特征选择看作是搜索问题。如回归特征消除。

• 嵌入:嵌入法使用内置了特征选择方法的算法。比如,Lasso和RF都有各自的特征选择方法。

理论已经讲够了,接下来开始说五个特征选择的方法。

本文将使用数据集来方便理解——用一个足球运动员的数据集来找到成为优秀足球运动员的秘诀。

90c61044f0043db3d167dfa25d4b5587.png

如果不理解足球术语也没关系,术语并不多。

Kaggle Kernel代码:https://www.kaggle.com/mlwhiz/feature-selection-using-football-data?source=post_page---------------------------

81a7d4bc2788dee21a32621056377be5.png

一些简单的数据预处理

此前已进行了一些基本的预处理,比如删除空值和一次热编码。将此问题转化为分类问题要用:

y = traindf['Overall']>=87

这里使用整体最高代指一个优秀球员。数据集(X)如下所示,有223列。

a1ca52da7594afc24ac3d6485058f707.png

train Data X

1. 皮尔逊相关系数

c9690dc4373497de5f4cc77c66d71bdd.png

这个是过滤法的一种。

检查数据集里目标和数值特征之间皮尔逊相关系数8的绝对值。根据这个准则保留前n个特征。

def cor_selector(X, y,num_feats):

    cor_list = []    feature_name = X.columns.tolist()    # calculate the correlation with y for each feature    for i in X.columns.tolist():        cor = np.corrcoef(X[i], y)[0, 1]        cor_list.append(cor)    # replace NaN with 0    cor_list = [0 if np.isnan(i) else i for i in cor_list]    # feature name    cor_feature = X.iloc[:,np.argsort(np.abs(cor_list))[-num_feats:]].columns.tolist()    # feature selection? 0 for not select, 1 for select    cor_support = [True if i in cor_feature else False for i in feature_name]    return cor_support, cor_featurecor_support, cor_feature = cor_selector(X, y,num_feats)print(str(len(cor_feature)), 'selected features')

2. 卡方分布

另一种过滤法。

该方法计算目标与数值变量之间的卡方度量分布,只选取卡方值最大的变量。

c39a36a6c8c48dfa3f03b7b4c3276929.png

举个小例子来说明如何计算样本的卡方统计量。

假设数据集中有75个右前锋和25个非右前锋。观察到其中40个右前锋好,35个不好。这是否意味着右前锋会影响整体表现呢?

2f162f629ee6f71c200549ec3ca522cc.png

5ef41b94887955794253afd33f67e400.png

观察和预期计数

计算卡方值:

要计算,首先要找出每个部分中的期望值,如果这两个分类变量之间确实独立的话。

很简单,将每个单元格的行和与列和相乘,并将其除以总观察值。

因此“好的”和“非右前锋的”期望值=25(行和)*60(列和)/100(总观察量)

为什么会这样?因为数据中有25%,所以预计在观察到的60名优秀球员中,有25%的人会是右前锋球员。因此是15个。

然后可以用下面的公式对所有4个单元格求和:

ad1489efd1df2eb65f5e5e63a9fc40e2.png

此处不会展示,但卡方统计量也有非负数值和分类特征。

数据集中可以得到如下卡方特征:

from sklearn.feature_selection import SelectKBestfrom sklearn.feature_selection import chi2from sklearn.preprocessing import MinMaxScalerX_norm = MinMaxScaler().fit_transform(X)chi_selector = SelectKBest(chi2, k=num_feats)chi_selector.fit(X_norm, y)chi_support = chi_selector.get_support()chi_feature = X.loc[:,chi_support].columns.tolist()print(str(len(chi_feature)), 'selected features')

3. 递归特征消除

这是一个包装法。如上所述,包装法将一组特性的选择视为搜索问题。

来自sklearn 文件:

递归特征消除(RFE)的目标是递归地考虑越来越小的特征集来选择特征。首先,用初始特征集训练估计器,通过 coef_或者feature_importances_属性可以获得特征的重要性。然后,从当前的一组特性中删除最不重要的。该过程在修剪集上递归地重复,直到最终达到所需的要选择的特性数量。

大家可能猜到了,这个方法可以用在任何估计器上。此处用的是 LogisticRegression ,而RFE观察了 LogisticRegression对象的coef_属性。

from sklearn.feature_selection import RFEfrom sklearn.linear_model import LogisticRegressionrfe_selector = RFE(estimator=LogisticRegression(), n_features_to_select=num_feats, step=10, verbose=5)rfe_selector.fit(X_norm, y)rfe_support = rfe_selector.get_support()rfe_feature = X.loc[:,rfe_support].columns.tolist()print(str(len(rfe_feature)), 'selected features')

4. 套索:SelectFromModel

473d757caf6a4d6e1ac3c6ae77786224.png

这个是嵌入法。如前所述,嵌入法使用有内置特征选择方法的算法。

例如,Lasso和RF都有自己的特征选择方法。Lasso正则化器强制许多特征权重为零。

这里用套索来选择变量。

from sklearn.feature_selection import SelectFromModelfrom sklearn.linear_model import LogisticRegression
embeded_lr_selector = SelectFromModel(LogisticRegression(penalty="l1"), max_features=num_feats)embeded_lr_selector.fit(X_norm, y)
embeded_lr_support = embeded_lr_selector.get_support()embeded_lr_feature = X.loc[:,embeded_lr_support].columns.tolist()print(str(len(embeded_lr_feature)), 'selected features')

5. 基于树形结构:SelectFromModel

8ca6d6e37f812e8aba83556284a9b976.png

这是嵌入法。如前所述,嵌入法使用有内置特征选择方法的算法。

还可以使用随机森林,根据特征的重要性来选择特征。

使用每个决策树中的节点杂质来计算特征的重要性。随机森林中,最终的特征重要性是所有决策树特征重要性的平均值。

from sklearn.feature_selection import SelectFromModelfrom sklearn.ensemble import RandomForestClassifier
embeded_rf_selector = SelectFromModel(RandomForestClassifier(n_estimators=100), max_features=num_feats)embeded_rf_selector.fit(X, y)
embeded_rf_support = embeded_rf_selector.get_support()embeded_rf_feature = X.loc[:,embeded_rf_support].columns.tolist()print(str(len(embeded_rf_feature)), 'selected features')

也可以使用 LightGBM或者XGBoost 对象,只要它有feature_importances_属性。

from sklearn.feature_selection import SelectFromModelfrom lightgbm import LGBMClassifier
lgbc=LGBMClassifier(n_estimators=500, learning_rate=0.05, num_leaves=32, colsample_bytree=0.2,            reg_alpha=3, reg_lambda=1, min_split_gain=0.01, min_child_weight=40)
embeded_lgb_selector = SelectFromModel(lgbc, max_features=num_feats)embeded_lgb_selector.fit(X, y)
embeded_lgb_support = embeded_lgb_selector.get_support()embeded_lgb_feature = X.loc[:,embeded_lgb_support].columns.tolist()print(str(len(embeded_lgb_feature)), 'selected features'

81a7d4bc2788dee21a32621056377be5.png

彩蛋

753b128964bc4a55c775afd8371438a2.png

既有森林,何须独木?

答案是,有时候数据太多、时间紧迫,全部使用是不可能的。

但只要有可能,为什么不这样做呢?

# put all selection togetherfeature_selection_df = pd.DataFrame({'Feature':feature_name, 'Pearson':cor_support, 'Chi-2':chi_support, 'RFE':rfe_support, 'Logistics':embeded_lr_support,                                    'Random Forest':embeded_rf_support, 'LightGBM':embeded_lgb_support})# count the selected times for each featurefeature_selection_df['Total'] = np.sum(feature_selection_df, axis=1)# display the top 100feature_selection_df = feature_selection_df.sort_values(['Total','Feature'] , ascending=False)feature_selection_df.index = range(1, len(feature_selection_df)+1)feature_selection_df.head(num_feats)
functionComputeSMA(data,window_size)

fa47499f4c8e83ee37607aaedc20764d.png

检查一下,用了以上所有方法后是否得到了特征。此处可以看到反应和长传是好评球员的优秀属性。和预期一样,控球和最后得分也占据了首位。

81a7d4bc2788dee21a32621056377be5.png

结论

特征工程和特征选择是所有机器学习分支的关键。

模型要力求精确,不一遍遍查看是不会获得良好精度的。

本文试图解释了一些最常用的特性选择技术,以及特性选择方面的工作流程,并且试图对这些方法提供一些直观认识。

a34c245025a816f0898f9c3a632ab10c.png

留言 点赞 关注

我们一起分享AI学习与发展的干货

编译组:李美欣、蒋馨怡相关链接:https://towardsdatascience.com/the-5-feature-selection-algorithms-every-data-scientist-need-to-know-3a6b566efd2

如需转载,请后台留言,遵守转载规范

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值