• 特征工程(三)特征选择


    经过“数据清理”和“特征变换”后的数据集,已经满足了数据科学项目中算法对数值的基本要求。但是, 不呢止步于此,数据集的特征数量、质量会影响计算效率和最终模型的预测、分类效果。所以要对特征进行选择,即根据具体的项目选择适合的特征。

    特征选择

    3.1 特征选择简述

    是不是维度越大的数据越好?是不是所有的维度都是必须的?

    import pandas as pd
    df_wine = pd.read_csv("datasets/wine_data.csv")
    df_wine.head()
    
    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
    0 1 14.23 1.71 2.43 15.6 127 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065
    1 1 13.20 1.78 2.14 11.2 100 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050
    2 1 13.16 2.36 2.67 18.6 101 2.80 3.24 0.30 2.81 5.68 1.03 3.17 1185
    3 1 14.37 1.95 2.50 16.8 113 3.85 3.49 0.24 2.18 7.80 0.86 3.45 1480
    4 1 13.24 2.59 2.87 21.0 118 2.80 2.69 0.39 1.82 4.32 1.04 2.93 735

    依据机器学习的一般流程,把数据集划分为训练集和测试集,并且对测试集和训练集分别实现特征标准化。

    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    X, y = df_wine.iloc[:, 1:], 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, stratify=y)
    
    std = StandardScaler()
    X_train_std = std.fit_transform(X_train)
    X_test_std = std.fit_transform(X_test)
    

    以Class_label为标签,建立对数回归模型,寻找另外13个特征与标签之间的关系。

    from sklearn.linear_model import LogisticRegression
    lr = LogisticRegression(penalty='l1', C=1.0 , solver='liblinear') 
    lr.fit(X_train_std, y_train)
    

    LogisticRegression(penalty='l1', solver='liblinear')

    在创建对数概率回归模型时候,使用了参数penalty='l1', C=1.0,这意味着在本模型中遵照此规则增加了惩罚项,其意图是避免训练得到的模型过拟合,也正是出于这个原因,模型舍弃了部分特性——表现出来就是系数为0

    lr.coef_
    
    array([[ 1.24568008,  0.18066268,  0.74500129, -1.16270324,  0.        ,
             0.        ,  1.16473536,  0.        ,  0.        ,  0.        ,
             0.        ,  0.55281296,  2.50976773],
           [-1.53710813, -0.38760504, -0.99525286,  0.36504305, -0.05948103,
             0.        ,  0.66797894,  0.        ,  0.        , -1.93413502,
             1.23360251,  0.        , -2.23189735],
           [ 0.13448113,  0.16969503,  0.35805173,  0.        ,  0.        ,
             0.        , -2.43221807,  0.        ,  0.        ,  1.56308975,
            -0.81943572, -0.49548102,  0.        ]])
    
    lr.intercept_
    

    array([-1.26347923, -1.21597948, -2.36926979])

    在机器学习中,过拟合是比较常见的现象,通常采用如下避免方法:

    • 训练集和测试集五五开
    • 在模型中增加惩罚项,简化模型
    • 尽可能选用参数少的模型
    • 降低数据集的维度

    特征选择,是指去除数据集中的冗余和无关的特征,从数据集中找出主要特征,最终得到得到的是原有特征的子集。因此,特征选择也称为“特征子集选择”

    为实现特征选择,这里介绍三类方法:封装器法、过滤器法和嵌入法。

    3.2 封装器法

    封装器法的基本思路是:

    1. 选用一个特征子集训练模型,此处的模型通常是一种机器学习算法,也称为目标函数。
    2. 用验证数据集对模型进行评估。
    3. 依据某种搜索方式,对不同的特征子集进行上述操作,
    4. 依据评估结果,选出相对最佳的特征子集。

    image-20220609191735736

    这种方式属于贪心搜索算法,计算量较大。针对特征子集的组合搜索问题,封装法有下述三种常见的选择方式。

    循序特征选择

    包括 循环向前(SFS)和循环向后(SBS)

    基础知识

    以SFS为例:

    (1)创建一个空的集合X,作为特征子集
    (2)从原特征集合中“一次挑选一个”——这就是“循序”的含义,与特征子集X中的特征组合,并使得目标函数(选定的某个机器学习模型)结果最佳(模型预测的误差最小)
    (3)将挑选出来的特征从原特征中移除,同时将其追加到X中。
    (4)重复(2)、(3)步骤,直到集合X的特征数量达到规定的数量为止,中止上述循环。

    显然,SFS不是把所有可能都实现一遍,而是找到一种可能最优解即中止寻找,这样就大大降低了计算量。
    mlxtend的第三库提供了实现包含SFS的多种循环特征选择方法

    pip install mlxtend
    

    mlxtend中集成了几个数据集,这里使用关于葡萄酒的数据。X有13个特征178个样本,y是每个样本的标签,即每种葡萄酒的等级(共有3级,用0,1,2表示)。其中,X的13特征依次对应的名称是:

    1. Alcohol
    2. Malic acid
    3. Ash
    4. Alcalinity of ash
    5. Magnesium
    6. Total phenols
    7. Flavanoids
    8. Nonflavanoid phenols
    9. Proanthocyanins
    10. Color intensity
    11. Hue
    12. OD280/OD315 of diluted wines
    13. Proline

    https://archive.ics.uci.edu/ml/datasets/Wine

    from mlxtend.feature_selection import SequentialFeatureSelector as SFS
    from sklearn.neighbors import KNeighborsClassifier
    from mlxtend.data import wine_data
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    
    X, y = wine_data()
    X.shape
    

    (178, 13)

    X_train, X_test, y_train, y_test= train_test_split(X, y, 
                                                       stratify=y,
                                                       test_size=0.3,
                                                       random_state=1)
    std = StandardScaler() #标准化
    X_train_std = std.fit_transform(X_train)
    
    knn = KNeighborsClassifier(n_neighbors=3)    # knn作为SFS的目标函数
    sfs = SFS(estimator=knn,     # SFS封装器
               k_features=4,     # 选择4个最佳特征
               forward=True, 
               floating=False, 
               verbose=2,         # 2输出训练过程的全部日志信息
               scoring='accuracy',#模型评估方法
               cv=0)              # 0 表示不进行交叉验证
    sfs.fit(X_train_std, y_train)
    
    [Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
    [Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
    [Parallel(n_jobs=1)]: Done  13 out of  13 | elapsed:    0.0s finished
    
    [2022-06-09 19:28:12] Features: 1/4 -- score: 0.8548387096774194[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
    [Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
    [Parallel(n_jobs=1)]: Done  12 out of  12 | elapsed:    0.0s finished
    
    [2022-06-09 19:28:12] Features: 2/4 -- score: 0.9596774193548387[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
    [Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
    [Parallel(n_jobs=1)]: Done  11 out of  11 | elapsed:    0.0s finished
    
    [2022-06-09 19:28:12] Features: 3/4 -- score: 0.9919354838709677[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
    [Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
    [Parallel(n_jobs=1)]: Done  10 out of  10 | elapsed:    0.0s finished
    
    [2022-06-09 19:28:12] Features: 4/4 -- score: 0.9838709677419355
    

    从输出的日志信息可以很明确地看出,当选择3个特征的时候,模型knn表现最好

    sfs.subsets_
    
    {1: {'feature_idx': (6,),
      'cv_scores': array([0.85483871]),
      'avg_score': 0.8548387096774194,
      'feature_names': ('6',)},
     2: {'feature_idx': (6, 9),
      'cv_scores': array([0.95967742]),
      'avg_score': 0.9596774193548387,
      'feature_names': ('6', '9')},
     3: {'feature_idx': (6, 9, 11),
      'cv_scores': array([0.99193548]),
      'avg_score': 0.9919354838709677,
      'feature_names': ('6', '9', '11')},
     4: {'feature_idx': (6, 8, 9, 11),
      'cv_scores': array([0.98387097]),
      'avg_score': 0.9838709677419355,
      'feature_names': ('6', '8', '9', '11')}}
    

    利用SFS的属性subsets_得到了每次选择出来的特征及其相应的评估分数,feature_names表示特征名称。

    项目案例

    使用随机森林回归作为目标函数,从房价数据集中,选择出10佳特征

    import pandas as pd
    from sklearn.ensemble import RandomForestRegressor
    
    df = pd.read_csv("datasets/housprice.csv")
    cols = list(df.select_dtypes(include=['int64', 'float64']).columns)  
    data = df[cols]
    
    X_train,X_test,y_train,y_test= train_test_split(
                data.drop('SalePrice',axis=1),
                data['SalePrice'],
                test_size=.2,
                random_state=1#随机数生成器使用的种子
    )
    
    X_train.fillna(0, inplace=True)    # 用0填充缺失值
    
    sfs3 = SFS(RandomForestRegressor(),    
               k_features=10,
               forward=True,
               verbose=0,
               cv=5,
               n_jobs=-1,
               scoring='r2')
    sfs3.fit(X_train,y_train)
    sfs3.k_feature_names_
    

    ('MSSubClass',
    'OverallQual',
    'OverallCond',
    'YearRemodAdd',
    'BsmtFinSF1',
    'TotalBsmtSF',
    'GrLivArea',
    'Fireplaces',
    'GarageCars',
    '3SsnPorch')

    穷举特征选择

    指封装器中的搜索算法先将所有特征组合都实现一遍,然后通过比较各种特征组合后的模型表现,从中选择出最佳得到特征子集。
    显然穷举特征选择必然浪费更大的计算量。

    # 对上面SFS练习题中的10个特征的数据集,对它使用穷举法,从10佳中选出5强
    mini_data = X_train[X_train.columns[list(sfs3.k_feature_idx_)]]    
    mini_data.shape
    

    (1168, 10)

    import numpy as np
    from mlxtend.feature_selection import ExhaustiveFeatureSelector as EFS
    efs = EFS(RandomForestRegressor(),
              min_features=1,
              max_features=5,
              scoring='r2',
              n_jobs=-1)    
    efs.fit(np.array(mini_data),y_train)
    mini_data.columns[list(efs.best_idx_)]
    

    Index(['MSSubClass', 'OverallQual', 'YearRemodAdd', 'BsmtFinSF1', 'GrLivArea'], dtype='object')

    很显然,穷举特征选择也是构建了一个封装器,在封装器里使用了一种机器学习算法作为目标函数。

    递归特征消除

    递归特征消除RFE也是封装器法的一种具体实施,其主要思想是利用训练集数据生成模型,再根据模型的特征权重,对特征进行取舍,消除权重不同的特征,从而得到数据集的特征子集。然后,对这个特征子集重复上述过程,直到特征数量达到规定值为止。显然,这种寻找最优特征子集的方法依然是贪心搜索算法。

    from sklearn.feature_selection import RFE
    # 为避免大规模计算,还是从10佳中选择5强,
    mini_data = X_train[X_train.columns[list(sfs3.k_feature_idx_)]]  
    
    rfe = RFE(RandomForestRegressor(), #依旧使用随机森林回归
              n_features_to_select=5)     
    rfe.fit(np.array(mini_data),y_train)
    rfe.ranking_
    

    array([4, 1, 3, 2, 1, 1, 1, 5, 1, 6])

    对mini_data的各个特征的权重从高到低排序之后,表示顺序的序号,1表示相应索引的特征权重最靠前,也就是权重最高。

    mini_data.columns[rfe.ranking_==1]
    

    Index(['OverallQual', 'BsmtFinSF1', 'TotalBsmtSF', 'GrLivArea', 'GarageCars'], dtype='object')

    对比发现,使用不同的方法选出的5强不完全一致,因此不同的特征方法会训练出不同效果的模型

    3.3 过滤器法

    过滤器法不评估子集的预测误差,而是使用某些统计指标,比如相关系数、互信息等——目标函数不同,根据这些统计指标,对各特征进行排序,以确定特征的取舍。

    image-20220609194319468

    下面用卡方检验(皮尔森卡方检验)作为统计指标选择特征

    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
    skb = SelectKBest(chi2, k=2)    #k为2表示特征子集中的特征数量
    result = skb.fit(X, y)    # 根据从大到小的排序取2个特征
    print("X^2 is: ", result.scores_)
    print("P-values is: ", result.pvalues_)
    
    X^2 is:  [ 10.81782088   3.7107283  116.31261309  67.0483602 ]
    P-values is:  [4.47651499e-03 1.56395980e-01 5.53397228e-26 2.75824965e-15]
    
    • 卡方检验是统计学上的假设检验方法。值越大,两个变量之间的偏差越大;反之,偏差越小。
    • P值是统计学中用于判断假设检验结果的参数。P值越小,原假设发生的概率就越小。

    利用训练得到的模型对数据集X进行特征选择,得到含有两个特征的新数据集

    X_new = skb.transform(X) 
    X_new.shape
    

    (150, 2)

    显示数据对应的特征名称

    import numpy as np
    [iris.feature_names[np.where(X[0, :]==i)[0][0]] for i in X_new[0, :]]
    

    ['petal length (cm)', 'petal width (cm)']

    过滤法中利用统计指标对特征排序,然后依据特征排序结果选择特征

    iris.feature_names
    

    ['sepal length (cm)',
    'sepal width (cm)',
    'petal length (cm)',
    'petal width (cm)']

    过滤器的实现路径可以表示为:

    过滤器法和封装器法对比:

    • 过滤器法通常不对数据集执行迭代计算,因此计算速度比封装器法要快
    • 封装器的目标函数是某个机器学习算法,过滤器的函数则是通用的统计函数,这样使得过滤器法所得到的特征更具有通用性,非专门针对某个算法有良好表现
    • 利用过滤器法进行特征选择时,用户需要武断地输入阈值,这可能会导致一定的选择成本。
    • 如果特征数量过少,过滤器可能无法找到最佳的特征子集,而封装器总能返回特征子集
    • 因为过滤器所得特征子集与某种算法无关,所以一般不会出现过拟合现象,而经由封装器法所得特征子集训练的模型,会出现过拟合现象。

    在项目中,应依据具体数据和项目要求,确定特征选择的实施方法。

    3.4 嵌入法

    在3.1节中曾用对数概率回归模型研究了葡萄酒的等级与特征的关系。因为在模型中使用了L1惩罚项,从而得到了特征系数的稀疏解,某些特征的系数为0。如此,可以对系数排序——特征权重,然后依据某个阈值选择部分特征。

    这种特性选择的实现方法显然不是封装法,也不是过滤器法,而是在训练模型的同时,得到了特征权重,并完成特征选择。像这样将特征选择过程与训练模型融为一体,在模型训练过程中自动进行特征选择,被称为嵌入法特征选择。

    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.feature_selection import SelectFromModel
    from sklearn.linear_model import LogisticRegression
    
    df_wine = pd.read_csv("datasets/wine_data.csv")
    X, y = df_wine.iloc[:, 1:], 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, stratify=y)
    
    std = StandardScaler()
    X_train_std = std.fit_transform(X_train)
    X_test_std = std.fit_transform(X_test)
    # 创建对数概率回归模型,采用L1惩罚项
    lr = LogisticRegression(C=1.0, penalty='l1', solver='liblinear')  
    # 规定选择特征的阈值--特征权重的中位数
    # 能够用的机器学习模型还有随机森林模型、决策树模型、LASSO回归模型、岭回归模型等
    model = SelectFromModel(lr, threshold='median')   
    X_new = model.fit_transform(X_train_std, y_train)
    
    X_new.shape
    

    (124, 7)

    X_train_std.shape
    

    (124, 13)

    3.5 综合练习

    import pandas as pd
    df = pd.read_csv("datasets/app_small.csv")
    df.drop('Unnamed: 0', axis=1, inplace=True) # 删除第一列
    df.shape
    

    (30751, 122)

    df.columns
    

    Index(['SK_ID_CURR', 'TARGET', 'NAME_CONTRACT_TYPE', 'CODE_GENDER',
    'FLAG_OWN_CAR', 'FLAG_OWN_REALTY', 'CNT_CHILDREN', 'AMT_INCOME_TOTAL',
    'AMT_CREDIT', 'AMT_ANNUITY',
    ...
    'FLAG_DOCUMENT_18', 'FLAG_DOCUMENT_19', 'FLAG_DOCUMENT_20',
    'FLAG_DOCUMENT_21', 'AMT_REQ_CREDIT_BUREAU_HOUR',
    'AMT_REQ_CREDIT_BUREAU_DAY', 'AMT_REQ_CREDIT_BUREAU_WEEK',
    'AMT_REQ_CREDIT_BUREAU_MON', 'AMT_REQ_CREDIT_BUREAU_QRT',
    'AMT_REQ_CREDIT_BUREAU_YEAR'],
    dtype='object', length=122)

    共有122个特征

    数字类型的特征和非数字类型的特征分别保存到不同的列表中

    categorical_list = []
    numerical_list = []
    for i in df.columns.tolist():
        if df[i].dtype=='object':
            categorical_list.append(i)
        else:
            numerical_list.append(i)
    print('Number of categorical features:', str(len(categorical_list)))
    print('Number of numerical features:', str(len(numerical_list)))
    

    Number of categorical features: 16
    Number of numerical features: 106

    将数值类型和分类型分别查出来共有16个分类型,106个数值类型

    df[numerical_list].isna().any()
    

    SK_ID_CURR False
    TARGET False
    CNT_CHILDREN False
    AMT_INCOME_TOTAL False
    AMT_CREDIT False
    ...
    AMT_REQ_CREDIT_BUREAU_DAY True
    AMT_REQ_CREDIT_BUREAU_WEEK True
    AMT_REQ_CREDIT_BUREAU_MON True
    AMT_REQ_CREDIT_BUREAU_QRT True
    AMT_REQ_CREDIT_BUREAU_YEAR True
    Length: 106, dtype: bool

    检查numerical_list中的特征是否有缺失值,如果有缺失值,则用中位数填补

    from sklearn.impute  import SimpleImputer
    df[numerical_list] = SimpleImputer(strategy='median').fit_transform(df[numerical_list])
    

    categorical_list中的特征都是分类型特征,于是乎进行OneHot编码(创建虚拟变量)

    df = pd.get_dummies(df, drop_first=True)
    df.shape
    

    (30751, 228)

    df
    
    SK_ID_CURR TARGET CNT_CHILDREN AMT_INCOME_TOTAL AMT_CREDIT AMT_ANNUITY AMT_GOODS_PRICE REGION_POPULATION_RELATIVE DAYS_BIRTH DAYS_EMPLOYED ... FONDKAPREMONT_MODE_reg oper spec account HOUSETYPE_MODE_specific housing HOUSETYPE_MODE_terraced house WALLSMATERIAL_MODE_Mixed WALLSMATERIAL_MODE_Monolithic WALLSMATERIAL_MODE_Others WALLSMATERIAL_MODE_Panel WALLSMATERIAL_MODE_Stone, brick WALLSMATERIAL_MODE_Wooden EMERGENCYSTATE_MODE_Yes
    0 100003.0 0.0 0.0 270000.000 1293502.5 35698.5 1129500.0 0.003541 -16765.0 -1188.0 ... 0 0 0 0 0 0 0 0 0 0
    1 100015.0 0.0 0.0 38419.155 148365.0 10678.5 135000.0 0.015221 -20417.0 365243.0 ... 0 0 0 0 0 0 0 0 0 0
    2 100051.0 0.0 0.0 202500.000 661702.5 48280.5 598500.0 0.007114 -9827.0 -758.0 ... 0 0 0 0 0 0 0 0 0 0
    3 100054.0 0.0 0.0 99000.000 260640.0 26838.0 225000.0 0.022625 -20121.0 -5332.0 ... 0 0 0 0 0 0 0 0 0 0
    4 100069.0 0.0 1.0 360000.000 640458.0 27265.5 517500.0 0.007330 -14186.0 -1743.0 ... 0 0 0 0 0 0 0 0 0 0
    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
    30746 456195.0 0.0 0.0 94500.000 270000.0 15075.0 270000.0 0.028663 -20246.0 -5452.0 ... 0 0 0 0 0 0 0 1 0 0
    30747 456212.0 0.0 1.0 135000.000 808650.0 23773.5 675000.0 0.009657 -18042.0 -186.0 ... 0 0 0 0 0 0 0 0 0 0
    30748 456219.0 0.0 1.0 112500.000 521280.0 31630.5 450000.0 0.006207 -13346.0 -1972.0 ... 0 0 0 0 0 0 0 0 0 0
    30749 456237.0 0.0 0.0 135000.000 946764.0 37678.5 765000.0 0.019689 -17533.0 -2306.0 ... 0 0 0 0 0 0 0 0 0 0
    30750 456253.0 0.0 0.0 153000.000 677664.0 29979.0 585000.0 0.005002 -14966.0 -7921.0 ... 0 0 0 0 0 0 1 0 0 0

    30751 rows × 228 columns

    X = df.drop(['SK_ID_CURR', 'TARGET'], axis=1)
    y = df['TARGET']
    feature_name = X.columns.tolist()
    

    先对X进行特征规范化操作,而后利用卡方检验选择50个特征

    from sklearn.feature_selection import SelectKBest
    from sklearn.feature_selection import chi2
    from sklearn.preprocessing import MinMaxScaler
    
    X_norm = MinMaxScaler().fit_transform(X)    # MinMax区间化
    chi_selector = SelectKBest(chi2, k=50)    # 过滤器法
    chi_selector.fit(X_norm, y)
    

    SelectKBest(k=50, score_func=<function chi2 at 0x000001C74C48F310>)

    chi_support = chi_selector.get_support()
    chi_feature = X.loc[:,chi_support].columns.tolist()  
    

    使用封装器,选50个特征

    from sklearn.feature_selection import RFE    
    from sklearn.linear_model import LogisticRegression
    rfe_selector = RFE(estimator=LogisticRegression(penalty="l1",solver='liblinear'), n_features_to_select=50, step=10, verbose=5)   
    rfe_selector.fit(X_norm, y)    
    rfe_support = rfe_selector.get_support()
    rfe_feature = X.loc[:,rfe_support].columns.tolist()
    

    用嵌入法选择特征

    from sklearn.feature_selection import SelectFromModel
    from sklearn.linear_model import LogisticRegression    #使用logistic回归模型
    
    embeded_lr_selector = SelectFromModel(LogisticRegression(penalty="l1",solver='liblinear'),threshold= '1.25*median')
    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')
    

    105 selected features

    不用对数几率回归模型,改为随机森林分类

    from sklearn.feature_selection import SelectFromModel
    from sklearn.ensemble import RandomForestClassifier    #相对上面,模型换了
    
    embeded_rf_selector = SelectFromModel(RandomForestClassifier(n_estimators=50), threshold='1.25*median')
    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')
    

    98 selected features

    # 下把特征按照被选择的次数从高到低列出来
    feature_selection_df = pd.DataFrame({'Feature':feature_name, 
                                         'Chi-2':chi_support, 
                                         'RFE':rfe_support, 
                                         'Logistics':embeded_lr_support,
                                         'Random Forest':embeded_rf_support})
    # 每个特征在不同方式中被选择的次数总和
    feature_selection_df['Total'] = np.sum(feature_selection_df, axis=1)
    # 按照次数大小,显示前50个
    feature_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(50)
    
    Feature Chi-2 RFE Logistics Random Forest Total
    1 REGION_RATING_CLIENT_W_CITY True True True True 4
    2 ORGANIZATION_TYPE_Self-employed True True True True 4
    3 ORGANIZATION_TYPE_Construction True True True True 4
    4 ORGANIZATION_TYPE_Business Entity Type 3 True True True True 4
    5 FLAG_OWN_CAR_Y True True True True 4
    6 EXT_SOURCE_3 True True True True 4
    7 EXT_SOURCE_2 True True True True 4
    8 EXT_SOURCE_1 True True True True 4
    9 DAYS_ID_PUBLISH True True True True 4
    10 CODE_GENDER_M True True True True 4
    11 WALLSMATERIAL_MODE_Monolithic True True True False 3
    12 ORGANIZATION_TYPE_Transport: type 3 True True True False 3
    13 ORGANIZATION_TYPE_Police True True True False 3
    14 ORGANIZATION_TYPE_Military True True True False 3
    15 ORGANIZATION_TYPE_Industry: type 9 True True True False 3
    16 OCCUPATION_TYPE_Low-skill Laborers True True True False 3
    17 OCCUPATION_TYPE_Laborers True False True True 3
    18 OCCUPATION_TYPE_High skill tech staff True True True False 3
    19 OCCUPATION_TYPE_Drivers True False True True 3
    20 NONLIVINGAPARTMENTS_MODE False True True True 3
    21 NAME_FAMILY_STATUS_Married True False True True 3
    22 NAME_EDUCATION_TYPE_Higher education True False True True 3
    23 LIVINGAREA_MEDI False True True True 3
    24 FLOORSMIN_MEDI False True True True 3
    25 FLOORSMAX_MODE False True True True 3
    26 FLAG_WORK_PHONE True False True True 3
    27 FLAG_DOCUMENT_3 True False True True 3
    28 ENTRANCES_AVG False True True True 3
    29 DEF_60_CNT_SOCIAL_CIRCLE False True True True 3
    30 DEF_30_CNT_SOCIAL_CIRCLE False True True True 3
    31 BASEMENTAREA_AVG False True True True 3
    32 APARTMENTS_MEDI False True True True 3
    33 AMT_REQ_CREDIT_BUREAU_MON False True True True 3
    34 AMT_GOODS_PRICE False True True True 3
    35 AMT_CREDIT False True True True 3
    36 AMT_ANNUITY False True True True 3
    37 YEARS_BEGINEXPLUATATION_MODE False False True True 2
    38 YEARS_BEGINEXPLUATATION_MEDI False False True True 2
    39 WEEKDAY_APPR_PROCESS_START_TUESDAY False False True True 2
    40 WALLSMATERIAL_MODE_Wooden False True True False 2
    41 REG_CITY_NOT_WORK_CITY True False False True 2
    42 REG_CITY_NOT_LIVE_CITY True False False True 2
    43 REGION_RATING_CLIENT True False False True 2
    44 ORGANIZATION_TYPE_Transport: type 1 False True True False 2
    45 ORGANIZATION_TYPE_Realtor False True True False 2
    46 ORGANIZATION_TYPE_Other False False True True 2
    47 ORGANIZATION_TYPE_Insurance False True True False 2
    48 ORGANIZATION_TYPE_Industry: type 3 False True True False 2
    49 ORGANIZATION_TYPE_Industry: type 2 False True True False 2
    50 ORGANIZATION_TYPE_Industry: type 12 False True True False 2
  • 相关阅读:
    如何在腾讯云上安装Cloud Foundry
    Chrome浏览器扩展程序的本地备份
    如何在Kubernetes里创建一个Nginx service
    如何在Kubernetes里创建一个Nginx应用
    在Mac里给Terminal终端自定义颜色
    linux sed命令详解
    跟我一起写Makefile--- 变量(嵌套变量+追加变量+overrid+多行变量+环境变量+目标变量+模式变量)
    makefile详解 嵌套执行make,定义命令包
    makefile学习笔记(多目录嵌套调用、变量使用)
    Makefile所有内嵌函数
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/16361023.html
Copyright © 2020-2023  润新知