• 学习笔记——sklearn数据预处理和特征工程(过滤法、嵌入法、包装法)


    sklearn数据预处理和特征工程

    数据挖掘五大流程

    • 获取数据
    • 数据预处理
      • 目的:让数据适应模型,匹配模型的需求
    • 特征工程
      • 面对的问题:特征之间有相关性、特征和标签无关、特征太多或太少或无法展示数据的真实面貌。
      • 目的:降低计算成本;提升模型上限;
    • 建模,测试模型并预测出结果
    • 上线,验证模型效果

    数据预处理

    **模块preprocessing:**几乎包含数据预处理的所有内容
    **模块lmpute:**填补缺失值专用
    模块feature_ selection: 包含特征选择的各种方法的实践
    **模块decomposition:**包含降维算法

    数据无量纲化

    将不同规格的数据转换为同一规则,或不同分布的数据转换到某个特定分布的需求。

    以梯度和矩阵为核心的算法中,无量纲化可以加快求解速度;如逻辑回归、支持向量机、神经网络

    **以距离为核心的模型,**无量纲化可以帮助我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响;如K近邻、K-Means聚类

    决策树和树的集成算法,可以不“无量纲化”,树模型也可以将数据处理好;

    数据的无量纲化,可以时线性或非线性的。

    线性包括中心化和缩放处理。

    • 中心化:数据平移,所有记录加减一个值
    • 缩放处理:所有数据乘除一个值,将数据固定在某个范围内。

    归一化preprocessing.MinMaxScaler

    • scaler.inverse_transform(转换后的结果),可以返回归一化前的原始数据
    • 参数feature_range=[],可以指定归一化的范围
    • **partial_fit()**可以解决特征数量太多的问题
    from sklearn.preprocessing import MinMaxScaler
    import pandas as pd
    data=[[-1,2],[-0.5,6],[0,10],[1,18]]
    scaler=MinMaxScaler()
    scaler.fit(data)
    result=scaler.transform(data)
    '''array([[0.  , 0.  ],
           [0.25, 0.25],
           [0.5 , 0.5 ],
           [1.  , 1.  ]])'''
    
    result=scaler.fit_transform(data)
    '''array([[0.  , 0.  ],
           [0.25, 0.25],
           [0.5 , 0.5 ],
           [1.  , 1.  ]])'''
    
    scaler.inverse_transform(result)
    '''array([[-1. ,  2. ],
           [-0.5,  6. ],
           [ 0. , 10. ],
           [ 1. , 18. ]])'''
    
    scaler2=MinMaxScaler(feature_range=[5,10])
    result2=scaler2.fit_transform(data)
    result2
    '''
    array([[ 5.  ,  5.  ],
           [ 6.25,  6.25],
           [ 7.5 ,  7.5 ],
           [10.  , 10.  ]])'''
    
    #当x中的特征数量太多时,fit会报错,因为数据量太大了计算不了
    #可以使用partial_fit作为训练接口
    scaler3=MinMaxScaler()
    scaler3.partial_fit(data)
    result3=scaler3.transform(data)
    result3
    '''
    array([[0.  , 0.  ],
           [0.25, 0.25],
           [0.5 , 0.5 ],
           [1.  , 1.  ]])'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    标准化preprocessing.StandardScaler

    • scaler.inverse_transform(转换后的结果),可以返回归一化前的原始数据
    • .mean_属性可以查看原始数据的均值
    • .var_属性可以查看原始数据的方差
    from sklearn.preprocessing import StandardScaler
    data=[[-1,2],[-0.5,6],[0,10],[1,18]]
    scaler=StandardScaler()
    scaler.fit(data)
    scaler.mean_#查看原始数据均值
    # array([-0.125,  9.   ])
    scaler.var_#查看原始数据方差
    # array([ 0.546875, 35.      ])
    
    x_std=scaler.transform(data)
    '''
    array([[-1.18321596, -1.18321596],
           [-0.50709255, -0.50709255],
           [ 0.16903085,  0.16903085],
           [ 1.52127766,  1.52127766]])'''
    x_std.mean()#0.0
    x_std.std()#1.0
    
    scaler.inverse_transform(x_std)#逆转
    '''array([[-1. ,  2. ],
           [-0.5,  6. ],
           [ 0. , 10. ],
           [ 1. , 18. ]])'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    对于StandardScaler和MinMaxScaler来说,空值NaN会被当做是缺失值,在fit的时候忽略,在transform的时候保持缺失NaN的状态显示。

    在fit接口中,只允许导入至少二维数组,一维数组导入会报错。

    如何选择?

    大多数机器学习算法中,会选择StandardScaler来进行特征缩放

    MinMaxScaler对异常值非常敏感。

    在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。

    MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛,比如数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于[0,1]区间之中。

    建议先试试看StandardScaler,效果不好换MinMaxScaler。

    缺失值处理

    sklearn.impute.SimpleImputer()

    参数含义
    missing_values告诉SimpleImputer,数据中的缺失值长什么样,默认空值np.nan
    strategy我们填补缺失值的策略,默认均值。
    输入“mean”使用均值填补(仅对数值型特征可用)
    输入“median"用中值填补(仅对数值型特征可用)
    输入"most_frequent”用众数填补(对数值型和字符型特征都可用)
    输入“constant"表示请参考参数“fill_value"中的值(对数值型和字符型特征都可用)
    fill_value当参数startegy为”constant"的时候可用,可输入字符串或数字表示要填充的值,常用0
    copy默认为True,将创建特征矩阵的副本,反之则会将缺失值填补到原本的特征矩阵中去。
    import pandas as pd
    data = pd.read_csv("Narrativedata.csv",index_col=0)
    data.info()
    '''
    ----------------填补之前---------------
    
    Int64Index: 891 entries, 0 to 890
    Data columns (total 4 columns):
     #   Column    Non-Null Count  Dtype  
    ---  ------    --------------  -----  
     0   Age       714 non-null    float64
     1   Sex       891 non-null    object 
     2   Embarked  889 non-null    object 
     3   Survived  891 non-null    object 
    dtypes: float64(1), object(3)
    memory usage: 34.8+ KB
    '''
    
    #填补年龄
    Age=data.loc[:,'Age'].values.reshape(-1,1)
    # Dataframe无法直接reshape
    # data.loc[:,'Age'].values的类型是numpy.ndarray
    from sklearn.impute import SimpleImputer
    imp_mean=SimpleImputer()#实例化,默认为均值填补
    imp_median=SimpleImputer(strategy='median')
    imp_0=SimpleImputer(strategy='constant',fill_value=0)
    
    imp_mean=imp_mean.fit_transform(Age)
    imp_median=imp_median.fit_transform(Age)
    imp_0=imp_0.fit_transform(Age)
    
    
    #这里我们用中位数填补Age
    data.loc[:,"Age"]=imp_median
    
    #使用众数填补Embarked
    Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)
    imp_mode=SimpleImputer(strategy='most_frequent')
    data.loc[:,"Embarked"]=imp_mode.fit_transform(Embarked)
    data.info()
    
    '''
    ----------------填补之后---------------
    
    Int64Index: 891 entries, 0 to 890
    Data columns (total 4 columns):
     #   Column    Non-Null Count  Dtype  
    ---  ------    --------------  -----  
     0   Age       891 non-null    float64
     1   Sex       891 non-null    object 
     2   Embarked  891 non-null    object 
     3   Survived  891 non-null    object 
    dtypes: float64(1), object(3)
    memory usage: 34.8+ KB'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    直接处理

    data.loc[:,"Age"]=data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())
    #EM=data.loc[:,"Embarked"].fillna(data.loc[:,"Embarked"].mode())
    data.dropna(axis=0,inplace=True)#axis等于0,删除行;=1,删除列
    data.info()
    '''
    ----------填充之后-------------
    
    Int64Index: 889 entries, 0 to 890
    Data columns (total 4 columns):
     #   Column    Non-Null Count  Dtype  
    ---  ------    --------------  -----  
     0   Age       889 non-null    float64
     1   Sex       889 non-null    object 
     2   Embarked  889 non-null    object 
     3   Survived  889 non-null    object 
    dtypes: float64(1), object(3)
    memory usage: 34.7+ KB'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    处理分类型特征

    preprocessing.LabelEncoder

    标签专用,能够将分类转换为分类数值

    • .**classes_**属性查看标签中有多少类别
    • .inverse_transform可以逆转
    • 允许一维数据
    from sklearn.preprocessing import LabelEncoder
    data.iloc[:,-1]=LabelEncoder().fit_transform(data.iloc[:,-1])
    data.head()
    '''	Age	Sex	Embarked	Survived
    0	22.0	male	S	0
    1	38.0	female	C	2
    2	26.0	female	S	2
    3	35.0	female	S	2
    4	35.0	male	S	0'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    preprocessing.OrdinalEncoder

    特征专用,与LabelEncoder用法类似

    • 输入数据是二维的
    • fit之后的属性**categories_**查看特征中的类别
    from sklearn.preprocessing import OrdinalEncoder
    OrdinalEncoder().fit(data.iloc[:,1:-1]).categories_
    #[array(['female', 'male'], dtype=object), array(['C', 'Q', 'S'], dtype=object)]
    
    • 1
    • 2
    • 3

    preprocessing.OneHotEncoder

    • fit之后的属性**get_feature_names()**返回每一列的名字
    • .inverse_transform可以逆转
    from sklearn.preprocessing import OneHotEncoder
    X=data.iloc[:,1:-1]
    enc=OneHotEncoder(categories='auto').fit(X)
    # pd.DataFrame(enc.inverse_transform(result)) #逆转,返回原始数据
    enc.get_feature_names()#返回每一列的名字
    # array(['x0_female', 'x0_male', 'x1_C', 'x1_Q', 'x1_S'], dtype=object)
    
    result=OneHotEncoder(categories='auto').fit_transform(X).toarray()
    #要转成数组,.fit_transform(X)之后得到的是一个稀疏矩阵对象
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    axis=1

    • 删除列
    • 合并列
    • 队列求均值
    • concat把不同列合在一起

    处理连续性特征

    二值化sklearn.preprocessing.Binarize

    将特征值化成0和1

    from sklearn.preprocessing import Binarizer
    X = data.iloc[:,0].values.reshape(-1,1)
    #类为特征专用,所以不能使用一维数组
    transformer = Binarizer(threshold=30).fit_transform(X)
    transformer
    
    • 1
    • 2
    • 3
    • 4
    • 5

    分箱

    参数含义&输入
    n_bins每个特征中分箱的个数,默认5,一次会被运用到所有导入的特征
    encode编码的方式,默认“onehot”
    “onehot”:做哑变量,之后返回一个稀疏矩阵,每一列是一个特征中的一个类别,含有该类别的样本表示为1,不含的表示为0
    “ordinal”:每个特征的每个箱都被编码为一个整数,返回每一列是一个特征.类似OrdinalEncoder每个特征下含有不同整数编码的箱的矩阵"onehot-dense":做哑变量,之后返回一个密集数组。
    strategy用来定义箱宽的方式,默认"quantile"
    “uniform”:表示等宽分箱,即每个特征中的每个箱的最大值之间的差为(特征.max() -特征.min())/(n_bins)
    “quantile”:表示等位分箱,即每个特征中的每个箱内的样本数量都相同
    “kmeans”:表示按聚类分箱,每个箱中的值到最近的一维k均值聚类的簇心得距离都相同
    from sklearn.preprocessing import KBinsDiscretizer
    X = data.iloc[:,0].values.reshape(-1,1)
    est = KBinsDiscretizer(n_bins=3, encode='ordinal',strategy='uniform')
    est.fit_transform(X)
    #查看转换后分的箱:变成了一列中的三箱
    set(est.fit_transform(X).ravel())#{0.0, 1.0, 2.0}
    est = KBinsDiscretizer(n_bins=3, encode='onehot',strategy='uniform')
    #查看转换后分的箱:变成了哑变量
    est.fit_transform(X).toarray()
    '''array([[1., 0., 0.],
           [0., 1., 0.],
           [1., 0., 0.],
           ...,
           [0., 1., 0.],
           [1., 0., 0.],
           [0., 1., 0.]])'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    也可以用pandas中的qcut\cut

    2特征工程

    2.1过滤法

    通常用于预处理,过滤法是独立于机器学习算法的,依据各种统计检验中分数以及相关性的各种指标来选择特征。

    2.1.1方差过滤

    即通过特征本身的方差来选择特征,方差特别小的特征对于样本区分没有什么作用。

    sklearn.feature_selection.VarianceThreshold

    • 重要参数:threshold:方差的阈值,舍弃所有方差小于threshold的特征,不填默认为0
    • 一般都要消除方差为0的特征
    #导入数据
    import pandas as pd
    data=pd.read_csv('digit recognizor.csv')
    X=data.iloc[:,1:]
    y=data.iloc[:,0]
    X.shape#(42000, 784)
    #本质是维度太高
    #如果用支持向量机和神经网络,可能直接跑不出来,(这两个特征本质是升维)
    
    #阈值为0
    from sklearn.feature_selection import VarianceThreshold
    selector=VarianceThreshold()#默认为零,删除方差为0的特征
    X_var0=selector.fit_transform(X)
    X_var0.shape#(42000, 708)
    
    #阈值设为所有方差中位数
    import numpy as np
    # X.var()#查看方差的中位数,得到的是pandas.core.series.Series类型
    # np.median(X.var().values)所有特征方差的中值1352.286703180131
    X_fsvar=VarianceThreshold(np.median(X.var().values)).fit_transform(X)
    X_fsvar.shape#(42000, 392)
    
    #当特征式二分类问题时,方差=p(1-p); 若特征是伯努利随机变量,假设p=0.8,即二分类特种中某种分类占到80%以上时删除特征
    X_vbar=VarianceThreshold(0.8*0.2).fit_transform(X)#删除特征中,某一分类占到0.8以上的
    X_vbar.shape#(42000, 685)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    方差过滤前后模型效果对比

    from sklearn.ensemble import RandomForestClassifier
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.model_selection import cross_val_score
    X=data.iloc[:,1:]
    y=data.iloc[:,0]
    X_fsvar=VarianceThreshold(np.median(X.var().values)).fit_transform(X)#默
    #KNN_方差过滤前
    cross_val_score(KNeighborsClassifier(),X,y,cv=5).mean()
    # 0.965857142857143
    #KNN_方差过滤后
    cross_val_score(KNeighborsClassifier(),X_fsvar,y,cv=5).mean()
    #0.966
    
    #随机森林-方差过滤前
    cross_val_score(RandomForestClassifier(n_estimators=100,random_state=0),X,y,cv=5).mean()
    #0.9642142857142856
    #随机森林-方差过滤后
    cross_val_score(RandomForestClassifier(n_estimators=100,random_state=0),X_fsvar,y,cv=5).mean()
    #0.9637142857142857
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 方差过滤后,删除了一半的特征(392),KNN效果提高了0.0002,随机森林效果降低了0.0005;

    • 对于KNN、单棵决策树、SVM、神经网络、回归算法,需要遍历特征或升维进行计算。本身的计算量很大,方差过滤这样的特征选择的效果比较好

    • 对于随机森林,它随机选取特征进行分枝,本身速度较快(n_estimators不高的情况),方差过滤对其影响不大。

    • 虽然随机森林和单棵决策树都是随机选择特征,但是决策树选的特征要比随机森林中每棵树随机选的特征多得多,所以特征数量对决策树运行快慢也有一定影响。

    • 如果过滤后,结果变好了,说明对于该模型,方差过滤舍弃的特征是噪音;否之,舍弃的特征中含有有效特征。

    • 过滤法的主要对象是:需要遍历特征或升维的算法

    • 过滤法的主要目的是:在维持算法表现的前提下,降低计算成本。

    • 一般过滤法用于预处理,我们会先用阈值为0或很小的的方差过滤,再用更优的特征选择模仿继续削减特征数量。

    2.1.2相关性过滤

    卡方过滤

    • 针对分类问题的(标签是离散的)
    • 要求特征非负
    • feature_selection.chi2+feature_selection.SelectKBest:chi2是评分标准,用来选取前k个分数最高的特征。

    这里我们用轻量级(n_estimators=10)的随机森林来实践。

    #随机森林-方差过滤前
    cross_val_score(RandomForestClassifier(c,random_state=0),X,y,cv=5).mean()
    #0.9373571428571429
    
    #随机森林-方差过滤后
    cross_val_score(RandomForestClassifier(n_estimators=10,random_state=0),X_fsvar,y,cv=5).mean()
    #0.9390476190476191
    
    #由于方差过滤后的效果变好了,就直接用方差过滤后的数据
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import cross_val_score
    from sklearn.feature_selection import SelectKBest,chi2
    
    x_fschi=SelectKBest(chi2,k=300).fit_transform(X_fsvar,y)
    x_fschi.shape#(42000, 300)
    cross_val_score(RandomForestClassifier(n_estimators=10,random_state=0),X_fsvar,y,cv=5).mean()#0.9390476190476191
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里的k要根据实际情况来做调整。k值可以通过学习曲线或者p值来确定

    学习曲线
    • 学习曲线花费计算量较大
    import matplotlib.pyplot as plt
    
    score=[]
    for i in range(350,200,-10):
        x_fschi =SelectKBest(chi2,k=i).fit_transform(X_fsvar,y)
        once=cross_val_score(RandomForestClassifier(n_estimators=10,random_state=0),x_fschi,y,cv=5).mean()
        score.append(once)
    plt.plot(range(350,200,-10),score)
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iR6ygd7S-1660645683500)(C:\Users\章ky\AppData\Roaming\Typora\typora-user-images\image-20220814142027328.png)]

    p值

    卡方检验的本质是推测两组数据之间的差异,原假设是“两组数据是相互独立的”。

    • p值<=0.05或0.01:拒绝原假设,两组数据是相关的
    • p值<=0.05或0.01:接受原假设,两组数据不相关。
    #看p值
    chivalue,pvalue_chi=chi2(X_fsvar,y)
    chivalue#返回所有特征对标签的卡方值
    k=chivalue.shape[0]-(pvalue_chi>0.05).sum()#392,与标签相关的特征数量
    #也就是(pvalue_chi<=0.05).sum()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    F检验

    • 又称方差齐性检验,捕捉每个特征与标签之间的线性关系
    • 可以做回归也可以做分类
    • SelectKBest+feature_selection.f_classif/feature_selection.f_regression
    • F检验在数据服从正态分布时会非常稳定,最好先做预处理

    F检验的本质是寻找两组数据之间的线性关系,原假设是“数据不存在线性的线性关系”。

    • p值<=0.05或0.01:拒绝原假设,两组数据显著线性相关
    • p值<=0.05或0.01:接受原假设,两组数据没有显著线性相关。
    from sklearn.feature_selection import f_classif
    F,pvalues_f=f_classif(X_fsvar,y)
    k=(pvalues_f<=0.5).sum()
    k#392
    
    • 1
    • 2
    • 3
    • 4

    互信息法

    • 用于捕捉特征与标签之间的任何关系,包括线性和非线性
    • feature_selection.mutual_info_classif/feature_selection.mutual_info_regression
    • 不返回统计量,只返回“每个特征与目标之间的互信息量的估计”,这个估计在[0,1]之间。0表示相互独立,1表示完全相关
    • 不能用于稀疏矩阵
    from sklearn.feature_selection import mutual_info_classif as MIC
    result=MIC(X_fsvar,y)
    k=(result>=0).sum()
    k#392
    
    • 1
    • 2
    • 3
    • 4

    2.2嵌入法SelectFromModel

    • 特征选择与算法训练同时进行
    • 每次从全部特征中选择特征子集进行训练和模型评估
    • 得到各个特征的权值系数
    • 优点:结果会更加精确到模型的效用本身,对提高模型效用有更好的效果;无关的特征和无区分度的特征也为被过滤掉,是过滤法的进化版
    • 缺点:①嵌入法的权值系数无法人为界定一个有效值,需要借助学习曲线或对模型的深入理解。②计算量很大,计算缓慢的算法时非常耗时

    class sklearn.feature_selection.SelectFromModel (estimator, threshold=None, prefifit=False, norm_order=1,max_features=None)

    SelectFromModel是一个元变换器,可以与任何在拟合后具有coef_,feature_importances_属性或参数中可选惩罚项的评估器一起使用(比如随机森林和树模型就具有属性feature_importances_逻辑回归就带有l1和l2惩罚项,线性支持向量机也支持l2惩罚项)。

    参数解释
    estimator使用的模型评估器,只要是带feature_importances_或者coef_属性,或带有l1和l2惩罚项的模型都可以使用
    threshold特征重要性的阈值,重要性低于这个阈值的特征都将被删除
    prefit默认False,判断是否将实例化后的模型直接传递给构造函数。如果为True,则必须直接调用fit和transform,不能使用fit_transform,并且SelectFromModel不能与cross_val_score,GridSearchCV和克隆估计器的类似实用程序一起使用。
    norm_orderk可输入非零整数,正无穷,负无穷,默认值为1 在评估器的coef_属性高于一维的情况下,用于过滤低于阈值的系数的向量的范数的阶数。
    max_features在阈值设定下,要选择的最大特征数。要禁用阈值并仅根据max_features选择,请设置threshold = -np.inf
    from sklearn.feature_selection import SelectFromModel
    from sklearn.ensemble import RandomForestClassifier as RFC
    RFC_ = RFC(n_estimators =10,random_state=0)
    X_embedded = SelectFromModel(RFC_,threshold=0.00067).fit_transform(X,y) #具体K值,可以通过学习曲线来查找
    X_embedded.shape#(42000, 324)
    cross_val_score(RFC_,X_embedded,y,cv=5).mean()#0.9391190476190475
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3包装法RFE

    包装法与嵌入法类似,不同的是

    • 包装法使用目标函数来选取特征,典型的目标函数是递归特征消除法RFE
    • 包装法的特征是在上一组特征修剪之后留下来的特征中选取的,以递归的方式直到最终达到所需数量的要选择的特征
    • 计算成本低于嵌入法
    • 包装法的效果是所有特征选择方法中最有利于提升模型表现的,可以利用很少的特征达到优秀的效果。

    class sklearn.feature_selection.RFE (estimator, n_features_to_select=None, step=1, verbose=0)

    参数estimator是需要填写的实例化后的评估器,n_features_to_select是想要选择的特征个数,step表示每次迭代中希望移除的特征个数。

    RFE类有两个很重要的属性

    .support_:返回所有的特征的是否最后被选中的布尔矩阵

    .ranking_:返回特征的按数次迭代中综合重要性的排名。

    类feature_selection.RFECV会在交叉验证循环中执行RFE以找到最佳数量的特征,增加参数cv,其他用法都和RFE一模一样。

    from sklearn.feature_selection import RFE
    RFC_=RFC(n_estimators =10,random_state=0)
    selector=RFE(RFC_,n_features_to_select=340,step=50).fit(X,y)
    X_wrapper=selector.transform(X)
    cross_val_score(RFC_,X_wrapper,y,cv=5).mean()#0.9379761904761905
    #selector.support_#返回所有的特征的是否最后被选中的布尔矩阵
    #selector.ranking_#返回特征的按数次迭代中综合重要性的排名。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    RFE类有两个很重要的属性

    .support_:返回所有的特征的是否最后被选中的布尔矩阵

    .ranking_:返回特征的按数次迭代中综合重要性的排名。

    类feature_selection.RFECV会在交叉验证循环中执行RFE以找到最佳数量的特征,增加参数cv,其他用法都和RFE一模一样。

    from sklearn.feature_selection import RFE
    RFC_=RFC(n_estimators =10,random_state=0)
    selector=RFE(RFC_,n_features_to_select=340,step=50).fit(X,y)
    X_wrapper=selector.transform(X)
    cross_val_score(RFC_,X_wrapper,y,cv=5).mean()#0.9379761904761905
    #selector.support_#返回所有的特征的是否最后被选中的布尔矩阵
    #selector.ranking_#返回特征的按数次迭代中综合重要性的排名。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.4总结

    • 当数据量很大的时候,优先使用方差过滤和互信息法调整,再上其他特征选择方法。
    • 使用逻辑回归时,优先使用嵌入法。
    • 使用支持向量机时,优先使用包装法。
    • 迷茫的时候,从过滤法走起,具体数据具体分析

    注:本文内容是本人在学习“菜菜的机器学习课程”网课过程中的记录、总结和整理,将重点部分整理出来的笔记。侵删。

  • 相关阅读:
    实现gitlab+jenkins+ansible自动化部署代码
    P1220 关路灯 ( 区间dp
    WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(6)
    思维模型 棘轮效应
    本科行政管理毕业论文什么题目好写点?
    SpringBoot
    【图像处理】基于双目视觉的物体体积测量算法研究(Matlab代码实现)
    君正X2000/X1600主控CPU方案有哪些场景?行业迈向人机交互智能时代来啦!
    WPF控件库(四)
    UML软件建模软件StarUML mac中文版软件介绍
  • 原文地址:https://blog.csdn.net/weixin_55730631/article/details/126371983