机器学习特征工程之特征选择

 

    在做数据分析的时候,数据预处理之后的特征选择尤为重要,特征选择做好之后对后面的优化尤为重要。特征选择的来源一般可以分为两块,第一就是根据业务实际需求已经整理好的特征数据,第二就是根据数据驱动来选择的高级特征。

    那我们如果在成百上千的特征中选择合适的特征呢,第一我们可以请教相关领域的专家,让专家根据经验给出相关的建议;第二就是根据数据统计进行特征选择。  

    根据数据特征缺失率选择

    一般选择首先会选择数据缺失较少的特征,数据缺失过多,进行数据预处理插补时,插补数据较多,如果选择的插补方法不合适,会造成数据准确度严重降低,进而影响到后面的的数据训练和测试时的结果。

    删除低方差特征

 VarianceThreshold是特征选择的简单基线方法。它删除方差不符合某个阈值的所有特征。默认情况下,它会删除所有零差异特征,即所有样本中具有相同值的特征。

例如,假设我们有一个具有布尔特征的数据集,并且我们要删除超过80%的样本中的一个或零(开或关)的所有特征。布尔特征是伯努利随机变量,这些变量的方差由下式给出

所以我们可以选择使用阈值:0.8 * (1 - 0.8)

>>> from sklearn.feature_selection import VarianceThreshold
>>> X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
>>> sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
>>> sel.fit_transform(X)
array([[0, 1],
       [1, 0],
       [0, 0],
       [1, 1],
       [1, 0],
       [1, 1]]) 

    如预期的那样,VarianceThreshold已经删除了第一列,其具有包含零的概率。

  单变量特征选择

    通过选择基于单变量统计测试的最佳特征来进行单变量特征选择。它可以被看作是估计器的预处理步骤。Scikit学习将特征选择例程公开为实现该transform方法的对象:

    SelectKBest除去ķ最高得分功能之外的所有功能
    SelectPercentile 删除除用户指定的最高得分百分比的功能之外的所有内容
    对每个特征使用常见的单变量统计检验:假阳性率SelectFpr,假发现率 SelectFdr或家族误差SelectFwe。
    GenericUnivariateSelect允许使用可配置策略执行单变量特征选择。这允许使用超参数搜索估计器来选择最佳的单变量选择策略。

    我们可以对样本执行测试,以仅检索两个最佳特征,如下所示:

>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectKBest
>>> from sklearn.feature_selection import chi2
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2) 

  递归特征消除

    给定一个向特征分配权重(例如,线性模型的系数)的外部估计器,递归特征消除(RFE)是通过递归地考虑更小和更小的特征集来选择特征。首先,对初始的特征集进行训练,并将权重分配给它们中的每一个。然后,从当前设置的特征修剪绝对权重最小的特征。在修剪的集合上递归地重复该过程,直到最终达到期望的要选择的要素数量。

RFECV 在交叉验证循环中执行RFE以找到最佳数量的特征。

例子:

递归特征消除:递归特征消除示例,显示数字分类任务中像素的相关性。
递归功能消除与交叉验证:递归功能消除示例,自动调整通过交叉验证选择的功能数量。


使用SelectFromModel功能选择

 

    SelectFromModel是一种元变压器,可以与任何在拟合后具有coef_或feature_importances_属性的估计器一起使用。如果相应的coef_或feature_importances_值低于提供的 threshold参数,则这些特征被认为是不重要和被去除的 。除了在数值上指定阈值之外,还有内置的启发式方法用于使用字符串参数来查找阈值。可用的启发式是“平均值”,“中位数”和浮点倍数,如“0.1 * mean”。
    使用SelectFromModel和LassoCV进行功能选择:从波士顿数据集中选择两个最重要的功能,而不必事先知道阈值。

基于L1-特征选择

 用L1范数惩罚的线性模型具有稀疏解:他们的许多估计系数为零。当目标是降低与另一个分类器一起使用的数据的维度时,它们可以与feature_selection.SelectFromModel 选择非零系数一起使用。特别是对于这个目的有用的稀疏估计是linear_model.Lasso用于回归linear_model.LogisticRegressionsvm.LinearSVC 归类和分类:

    

>>> from sklearn.svm import LinearSVC
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
>>> model = SelectFromModel(lsvc, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape
(150, 3) 

    使用SVM和逻辑回归,参数C控制稀疏度:较小的C选择的功能越少。使用Lasso,Alpha参数越高,所选的功能越少。

    例子:

  基于树的特征选择

   基于树的估计器(参见sklearn.tree模块中树的模块和森林sklearn.ensemble)可以用于计算特征重要性,而后者又可用于丢弃不相关的特征(与sklearn.feature_selection.SelectFromModel 元变换器耦合时):

>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> clf = ExtraTreesClassifier()
>>> clf = clf.fit(X, y)
>>> clf.feature_importances_ 
array([ 0.04...,  0.05...,  0.4...,  0.4...])
>>> model = SelectFromModel(clf, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape              
(150, 2)

 

随机森林库做特征选择

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier

#导入数据
df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)
df_wine.columns=['Class label','Alcohol','Malic acid','Ash','Alcalinity of ash','Magnesium','Total phenols','Flavanoids','Nonflavanoid phenols','Proanthocyanins','Color intensity','Hue','OD280/OD315 of diluted wines','Proline']
print ('class labels:',np.unique(df_wine['Class label']))
#分割训练集合测试集
X,y=df_wine.iloc[:,1:].values,df_wine.iloc[:,0].values
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=0)

# 随机森林评估特征重要性
feat_labels = df_wine.columns[1:]
forest = RandomForestClassifier(n_estimators=10000, n_jobs=-1, random_state=0)
forest.fit(X_train, y_train)
importances = forest.feature_importances_
print(importances)
indices = np.argsort(importances)[::-1]
print(indices)
for f in range(X_train.shape[1]):
    print(f)
    # 给予10000颗决策树平均不纯度衰减的计算来评估特征重要性
    print("%2d) %-*s %f" % (f + 1, 30, feat_labels[f], importances[indices[f]]))
# 可视化特征重要性-依据平均不纯度衰减
plt.title('Feature Importance-RandomForest')
plt.bar(range(X_train.shape[1]), importances[indices], color='lightblue', align='center')
plt.xticks(range(X_train.shape[1]), feat_labels, rotation=90)
plt.xlim([-1, X_train.shape[1]])
plt.tight_layout()
plt.show()

# 在这个基础上,随机森林海可以通过阈值压缩数据集
X_selected = forest.transform(X_train, threshold=0.15)  # 大于0.15只有三个特征
print(X_selected.shape)

[0.10658906 0.02539968 0.01391619 0.03203319 0.02207807 0.0607176
 0.15094795 0.01464516 0.02235112 0.18248262 0.07824279 0.1319868
 0.15860977]
 1) Alcohol                        0.182483
 2) Malic acid                     0.158610
 3) Ash                            0.150948
 4) Alcalinity of ash              0.131987
 5) Magnesium                      0.106589
 6) Total phenols                  0.078243
 7) Flavanoids                     0.060718
 8) Nonflavanoid phenols           0.032033
 9) Proanthocyanins                0.025400
10) Color intensity                0.022351
11) Hue                            0.022078
12) OD280/OD315 of diluted wines   0.014645
13) Proline                        0.013916

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值