Ceci est un mémorandum parce que j'ai étudié la sélection des fonctionnalités en utilisant une importance nulle. Veuillez indiquer s'il y a quelque chose d'étrange. Référence: Sélection de fonctionnalités avec aucune importance nulle
Ceci est fait pour supprimer la quantité de caractéristiques qui provoque du bruit lors de la sélection de la quantité de caractéristiques et pour extraire la quantité de caractéristiques vraiment importante. L'importance de chaque caractéristique est mesurée à l'aide de données d'apprentissage dans lesquelles la variable objective est mélangée de manière aléatoire.
Importer les bibliothèques requises
import pandas as pd
import numpy as np
np.random.seed(123)
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import KFold
import time
import lightgbm as lgb
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import seaborn as sns
import warnings
warnings.simplefilter('ignore', UserWarning)
import gc
gc.enable()
import time
Préparation des données Cette fois, nous utiliserons les données du tutoriel House Price de kaggle. House Prices: Advanced Regression Techniques
#Lecture des données
data = pd.read_csv("./House_Price/train.csv")
target = data['SalePrice']
#Obtenir des variables catégorielles
cat_features = [
f for f in data.columns if data[f].dtype == 'object'
]
for feature in cat_features:
#Convertir des variables catégorielles en nombres
data[feature], _ = pd.factorize(data[feature])
#Convertir le type en catégorie
data[feature] = data[feature].astype('category')
#Pour le moment, la quantité de caractéristiques incluant la valeur manquante est supprimée.
drop_cols = [f for f in data.columns if data[f].isnull().any(axis=0) == True]
# drop_cols.append('SalePrice') #Supprimer la variable objectif
data = data.drop(drop_cols, axis=1)
Préparez une fonction qui renvoie l'importance de la quantité de caractéristiques. Cette fois, j'ai utilisé LightGBM comme dans l'article auquel j'ai fait référence.
def get_feature_importances(data, cat_features, shuffle, seed=None):
#Obtenir la quantité de fonctionnalités
train_features = [f for f in data if f not in 'SalePrice']
#Mélanger la variable d'objectif si nécessaire
y = data['SalePrice'].copy()
if shuffle:
y = data['SalePrice'].copy().sample(frac=1.0)
#Formation avec LightGBM
dtrain = lgb.Dataset(data[train_features], y, free_raw_data=False, silent=True)
params = {
'task': 'train',
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': {'l2'},
'num_leaves': 128,
'learning_rate': 0.01,
'num_iterations':100,
'feature_fraction': 0.38,
'bagging_fraction': 0.68,
'bagging_freq': 5,
'verbose': 0
}
clf = lgb.train(params=params, train_set=dtrain, num_boost_round=200, categorical_feature=cat_features)
#Acquérir l'importance de la quantité de caractéristiques
imp_df = pd.DataFrame()
imp_df["feature"] = list(train_features)
imp_df["importance"] = clf.feature_importance()
return imp_df
Créez une distribution d'importance nulle.
null_imp_df = pd.DataFrame()
nb_runs = 80
start = time.time()
for i in range(nb_runs):
imp_df = get_feature_importances(data=data, cat_features=cat_features, shuffle=True)
imp_df['run'] = i + 1
null_imp_df = pd.concat([null_imp_df, imp_df], axis=0)
actual_imp_df = get_feature_importances(data=data, cat_features=cat_features, shuffle=False)
Utiliser l'importance des entités normales divisée par le 75e centile de la distribution d'importance nulle
feature_scores = []
for _f in actual_imp_df['feature'].unique():
f_null_imps = null_imp_df.loc[null_imp_df['feature'] == _f, 'importance'].values
f_act_imps = actual_imp_df.loc[actual_imp_df['feature'] == _f, 'importance'].mean()
imp_score = np.log(1e-10 + f_act_imps / (1 + np.percentile(f_null_imps, 75)))
feature_scores.append((_f, imp_score))
scores_df = pd.DataFrame(feature_scores, columns=['feature', 'imp_score'])
Définissez un seuil approprié et sélectionnez le montant de la fonctionnalité. Cette fois, j'ai décidé d'utiliser celui avec un score de 0,5 ou plus.
sorted_features = scores_df.sort_values(by=['imp_score'], ascending=False).reset_index(drop=True)
new_features = sorted_features.loc[sorted_features.imp_score >= 0.5, 'feature'].values
print(new_features)
# ['CentralAir' 'GarageCars' 'OverallQual' 'HalfBath' 'OverallCond' 'BsmtFullBath']
Il a été utilisé par les meilleurs lauréats du concours auquel j'ai participé l'autre jour, alors je l'ai vérifié. Je pense qu'il existe diverses autres méthodes pour sélectionner les quantités de caractéristiques, je voudrais donc enquêter.
Recommended Posts