<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【數(shù)據(jù)競賽】99%情況下都有效的特征篩選策略--Null Importance。

          共 13081字,需瀏覽 27分鐘

           ·

          2021-08-05 09:50

          作者:杰少


          Null Importance特征篩選

          簡介

          目前數(shù)據(jù)量越來越大,數(shù)據(jù)特征維度也越來越高,這不僅對我們的計算存儲帶來了較大的挑戰(zhàn),與此同時,還會對模型的效果帶來較大的損益。

          • 如何既能節(jié)省內(nèi)存計算資源,同時能拿到模型的提效是我們非常關(guān)心的一個問題。

          本文我們介紹一種特征篩選策略 -- Null Importance 特征篩選策略,該策略在95%的數(shù)據(jù)競賽中基本都可以拿到效果,帶來不錯的提升。

          Null Importance

          1. 核心思想

          Null Importance的核心思想在于:

          1. 計算不靠譜的特征重要性;

            • 我們對標簽進行隨機shuffle,并計算特征重要性,這些特征重要性是“錯誤的”;
          2. 計算靠譜的特征重要性;

          • 對原始數(shù)據(jù)進行訓(xùn)練并得到特征重要性,這些特征重要性是“正確的”;
          1. 計算靠譜的特征重要性和不靠譜的特征重要性的差距/偏離度(自行設(shè)計Score函數(shù));

          2. 按照計算得到的Score進行批量的特征篩選,并計算線下驗證分數(shù);

          3. 選用線下分數(shù)最好的一些特征作為最終的特征;

          2. 實現(xiàn)步驟

          Null Importance算法的實現(xiàn)步驟為:

          1. 在原始數(shù)據(jù)集上運行模型并且記錄每個特征重要性。以此作為基準;
          2. 構(gòu)建Null importances分布:對我們的標簽進行隨機Shuffle,并且計算shuffle之后的特征的重要性;
          3. 對2進行多循環(huán)操作,得到多個不同shuffle之后的特征重要性;
          4. 設(shè)計score函數(shù),得到未shuffle的特征重要性與shuffle之后特征重要性的偏離度,并以此設(shè)計特征篩選策略;
          5. 計算不同篩選情況下的模型的分數(shù),并進行記錄;
          6. 將分數(shù)最好的幾個分數(shù)對應(yīng)的特征進行返回。
          代碼

          代碼摘自:https://www.kaggle.com/ogrellier/feature-selection-with-null-importances。

          1. 特征重要性獲取函數(shù)

          def get_feature_importances(data, shuffle, seed=None):
              # Gather real features
              train_features = [f for f in data if f not in ['TARGET''SK_ID_CURR']]
              # Go over fold and keep track of CV score (train and valid) and feature importances
              
              # Shuffle target if required
              y = data['TARGET'].copy()
              if shuffle:
                  # Here you could as well use a binomial distribution
                  y = data['TARGET'].copy().sample(frac=1.0)
              
              # Fit LightGBM in RF mode, yes it's quicker than sklearn RandomForest
              dtrain = lgb.Dataset(data[train_features], y, free_raw_data=False, silent=True)
              lgb_params = {
                  'objective''binary',
                  'boosting_type''rf',
                  'subsample'0.623,
                  'colsample_bytree'0.7,
                  'num_leaves'127,
                  'max_depth'8,
                  'seed': seed,
                  'bagging_freq'1,
                  'n_jobs'4
              }
              
              # Fit the model
              clf = lgb.train(params=lgb_params, train_set=dtrain, num_boost_round=200, categorical_feature=categorical_feats)

              # Get feature importances
              imp_df = pd.DataFrame()
              imp_df["feature"] = list(train_features)
              imp_df["importance_gain"] = clf.feature_importance(importance_type='gain')
              imp_df["importance_split"] = clf.feature_importance(importance_type='split')
              imp_df['trn_score'] = roc_auc_score(y, clf.predict(data[train_features]))
              
              return imp_df

          2.獲取原始版本的特征重要性

          # Seed the unexpected randomness of this world
          np.random.seed(123)
          # Get the actual importance, i.e. without shuffling
          actual_imp_df = get_feature_importances(data=data, shuffle=False

          3.獲取多個target shuffle版本的特征重要性

          null_imp_df = pd.DataFrame()
          nb_runs = 80
          import time
          start = time.time()
          dsp = ''
          for i in range(nb_runs):
              # Get current run importances
              imp_df = get_feature_importances(data=data, shuffle=True)
              imp_df['run'] = i + 1 
              # Concat the latest importances with the old ones
              null_imp_df = pd.concat([null_imp_df, imp_df], axis=0)
              # Erase previous message
              for l in range(len(dsp)):
                  print('\b', end='', flush=True)
              # Display current run and time used
              spent = (time.time() - start) / 60
              dsp = 'Done with %4d of %4d (Spent %5.1f min)' % (i + 1, nb_runs, spent)
              print(dsp, end='', flush=True)

          4.計算Score

          4.1 Score計算方式1

          • 以未進行特征shuffle的特征重要性除以shuffle之后的0.75分位數(shù)作為我們的score;
          feature_scores = []
          for _f in actual_imp_df['feature'].unique():
              f_null_imps_gain = null_imp_df.loc[null_imp_df['feature'] == _f, 'importance_gain'].values
              f_act_imps_gain = actual_imp_df.loc[actual_imp_df['feature'] == _f, 'importance_gain'].mean()
              gain_score = np.log(1e-10 + f_act_imps_gain / (1 + np.percentile(f_null_imps_gain, 75)))  # Avoid didvide by zero
              
              f_null_imps_split = null_imp_df.loc[null_imp_df['feature'] == _f, 'importance_split'].values
              f_act_imps_split = actual_imp_df.loc[actual_imp_df['feature'] == _f, 'importance_split'].mean()
              split_score = np.log(1e-10 + f_act_imps_split / (1 + np.percentile(f_null_imps_split, 75)))  # Avoid didvide by zero
              
              feature_scores.append((_f, split_score, gain_score))

          scores_df = pd.DataFrame(feature_scores, columns=['feature''split_score''gain_score'])

          4.2 計算方式2

          • shuffle target之后特征重要性低于實際target對應(yīng)特征的重要性0.25分位數(shù)的次數(shù)百分比。
          correlation_scores = []
          for _f in actual_imp_df['feature'].unique():
              f_null_imps = null_imp_df.loc[null_imp_df['feature'] == _f, 'importance_gain'].values
              f_act_imps = actual_imp_df.loc[actual_imp_df['feature'] == _f, 'importance_gain'].values
              gain_score = 100 * (f_null_imps < np.percentile(f_act_imps, 25)).sum() / f_null_imps.size
              
              f_null_imps = null_imp_df.loc[null_imp_df['feature'] == _f, 'importance_split'].values
              f_act_imps = actual_imp_df.loc[actual_imp_df['feature'] == _f, 'importance_split'].values
              split_score = 100 * (f_null_imps < np.percentile(f_act_imps, 25)).sum() / f_null_imps.size
              correlation_scores.append((_f, split_score, gain_score))

          corr_scores_df = pd.DataFrame(correlation_scores, columns=['feature''split_score''gain_score'])

          5. 計算特征篩選之后的最佳分數(shù)并記錄相應(yīng)特征

          • 選用篩選之后分數(shù)最好的特征作為最終特征即可。
          def score_feature_selection(df=None, train_features=None, cat_feats=None, target=None):
              # Fit LightGBM 
              dtrain = lgb.Dataset(df[train_features], target, free_raw_data=False, silent=True)
              lgb_params = {
                  'objective''binary',
                  'boosting_type''gbdt',
                  'learning_rate'.1,
                  'subsample'0.8,
                  'colsample_bytree'0.8,
                  'num_leaves'31,
                  'max_depth'-1,
                  'seed'13,
                  'n_jobs'4,
                  'min_split_gain'.00001,
                  'reg_alpha'.00001,
                  'reg_lambda'.00001,
                  'metric''auc'
              }
              
              # Fit the model
              hist = lgb.cv(
                  params=lgb_params, 
                  train_set=dtrain, 
                  num_boost_round=2000,
                  categorical_feature=cat_feats,
                  nfold=5,
                  stratified=True,
                  shuffle=True,
                  early_stopping_rounds=50,
                  verbose_eval=0,
                  seed=17
              )
              # Return the last mean / std values 
              return hist['auc-mean'][-1], hist['auc-stdv'][-1]

          # features = [f for f in data.columns if f not in ['SK_ID_CURR', 'TARGET']]
          # score_feature_selection(df=data[features], train_features=features, target=data['TARGET'])

          for threshold in [0102030 , 4050 ,60 , 7080 , 909599]:
              split_feats     = [_f for _f, _score, _ in correlation_scores if _score >= threshold]
              split_cat_feats = [_f for _f, _score, _ in correlation_scores if (_score >= threshold) & (_f in categorical_feats)]
              
              gain_feats     = [_f for _f, _, _score in correlation_scores if _score >= threshold]
              gain_cat_feats = [_f for _f, _, _score in correlation_scores if (_score >= threshold) & (_f in categorical_feats)]
                                                                                                       
              print('Results for threshold %3d' % threshold)
              split_results = score_feature_selection(df=data, train_features=split_feats, cat_feats=split_cat_feats, target=data['TARGET'])
              print('\t SPLIT : %.6f +/- %.6f' % (split_results[0], split_results[1]))
              gain_results = score_feature_selection(df=data, train_features=gain_feats, cat_feats=gain_cat_feats, target=data['TARGET'])
              print('\t GAIN  : %.6f +/- %.6f' % (gain_results[0], gain_results[1]))
          適用問題

          Null Importance特征篩選策略是數(shù)據(jù)實踐中必備的技能之一,該方法基本可以在95%以上的數(shù)據(jù)競賽或者實踐項目中都能取得一定的收益。

          參考文獻
          1. https://www.kaggle.com/ogrellier/feature-selection-with-null-importances
          2. https://academic.oup.com/bioinformatics/article/26/10/1340/193348
          往期精彩回顧




          本站qq群851320808,加入微信群請掃碼:
          瀏覽 96
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲成人无码视频 | 亚洲天堂一区二区三区 | 艹逼胖子网站免费视频 | 一级a一级a爱片免费免会永久 | 天堂网在线最新版www中文网 |