Importanza delle funzionalità con variabili fittizie


17

Sto cercando di capire come posso ottenere l'importanza di una variabile categoriale che è stata suddivisa in variabili fittizie. Sto usando scikit-learn che non gestisce le variabili categoriali per te come fanno R o h2o.

Se suddivido una variabile categoriale in variabili fittizie, ottengo importazioni di funzionalità separate per classe in quella variabile.

La mia domanda è: ha senso ricombinare quelle fittizie importazioni di variabili in un valore di importanza per una variabile categoriale semplicemente sommandole?

Da pagina 368 di The Elements of Statistical Learning:

L'importanza relativa al quadrato della variabile X è la somma di tali miglioramenti al quadrato su tutti i nodi interni per i quali è stata scelta come variabile di divisione

Questo mi fa pensare che, poiché il valore di importanza è già stato creato sommando una metrica in ciascun nodo, la variabile è selezionata, dovrei essere in grado di combinare i valori di importanza variabile delle variabili fittizie per "recuperare" l'importanza per la variabile categoriale. Naturalmente non mi aspetto che sia esattamente corretto, ma questi valori sono comunque valori esatti in quanto vengono trovati attraverso un processo casuale.

Ho scritto il seguente codice Python (in jupyter) come un'indagine:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from sklearn.datasets import load_diabetes
from sklearn.ensemble import RandomForestClassifier
import re

#%matplotlib inline
from IPython.display import HTML
from IPython.display import set_matplotlib_formats

plt.rcParams['figure.autolayout'] = False
plt.rcParams['figure.figsize'] = 10, 6
plt.rcParams['axes.labelsize'] = 18
plt.rcParams['axes.titlesize'] = 20
plt.rcParams['font.size'] = 14
plt.rcParams['lines.linewidth'] = 2.0
plt.rcParams['lines.markersize'] = 8
plt.rcParams['legend.fontsize'] = 14

# Get some data, I could not easily find a free data set with actual categorical variables, so I just created some from continuous variables
data = load_diabetes()
df = pd.DataFrame(data.data, columns=[data.feature_names])
df = df.assign(target=pd.Series(data.target))

# Functions to plot the variable importances
def autolabel(rects, ax):
    """
    Attach a text label above each bar displaying its height
    """
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width()/2.,
                1.05*height,
                f'{round(height,3)}',
                ha='center',
                va='bottom')

def plot_feature_importance(X,y,dummy_prefixes=None, ax=None, feats_to_highlight=None):

    # Find the feature importances by fitting a random forest
    forest = RandomForestClassifier(n_estimators=100)
    forest.fit(X,y)
    importances_dummy = forest.feature_importances_

    # If there are specified dummy variables, combing them into a single categorical 
    # variable by summing the importances. This code assumes the dummy variables were
    # created using pandas get_dummies() method names the dummy variables as
    # featurename_categoryvalue
    if dummy_prefixes is None:
        importances_categorical = importances_dummy
        labels = X.columns
    else:
        dummy_idx = np.repeat(False,len(X.columns))
        importances_categorical = []
        labels = []

        for feat in dummy_prefixes:
            feat_idx = np.array([re.match(f'^{feat}_', col) is not None for col in X.columns])
            importances_categorical = np.append(importances_categorical,
                                                sum(importances_dummy[feat_idx]))
            labels = np.append(labels,feat)
            dummy_idx = dummy_idx | feat_idx
        importances_categorical = np.concatenate((importances_dummy[~dummy_idx],
                                                  importances_categorical))
        labels = np.concatenate((X.columns[~dummy_idx], labels))

    importances_categorical /= max(importances_categorical)
    indices = np.argsort(importances_categorical)[::-1]

    # Plotting

    if ax is None:
        fig, ax = plt.subplots()

    plt.title("Feature importances")
    rects = ax.bar(range(len(importances_categorical)),
                   importances_categorical[indices],
                   tick_label=labels[indices],
                   align="center")
    autolabel(rects, ax)

    if feats_to_highlight is not None:
        highlight = [feat in feats_to_highlight for feat in labels[indices]]
        rects2 = ax.bar(range(len(importances_categorical)),
                       importances_categorical[indices]*highlight,
                       tick_label=labels[indices],
                       color='r',
                       align="center")
        rects = [rects,rects2]
    plt.xlim([-0.6, len(importances_categorical)-0.4])
    ax.set_ylim((0, 1.125))
    return rects

# Create importance plots leaving everything as categorical variables. I'm highlighting bmi and age as I will convert those into categorical variables later
X = df.drop('target',axis=1)
y = df['target'] > 140.5

plot_feature_importance(X,y, feats_to_highlight=['bmi', 'age'])
plt.title('Feature importance with bmi and age left as continuous variables')

#Create an animation of what happens to variable importance when I split bmi and age into n (n equals 2 - 25) different classes
# %%capture

fig, ax = plt.subplots()

def animate(i):
    ax.clear()

    # Split one of the continuous variables up into a categorical variable with i balanced classes
    X_test = X.copy()
    n_categories = i+2
    X_test['bmi'] = pd.cut(X_test['bmi'],
                           np.percentile(X['bmi'], np.linspace(0,100,n_categories+1)),
                           labels=[chr(num+65) for num in range(n_categories)])
    X_test['age'] = pd.cut(X_test['age'],
                           np.percentile(X['age'], np.linspace(0,100,n_categories+1)),
                           labels=[chr(num+65) for num in range(n_categories)])
    X_test = pd.get_dummies(X_test, drop_first=True)

    # Plot the feature importances
    rects = plot_feature_importance(X_test,y,dummy_prefixes=['bmi', 'age'],ax=ax, feats_to_highlight=['bmi', 'age'])
    plt.title(f'Feature importances for {n_categories} bmi and age categories')
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.spines['left'].set_visible(False)

    return [rects,]

anim = animation.FuncAnimation(fig, animate, frames=24, interval=1000)

HTML(anim.to_html5_video())

Ecco alcuni dei risultati:

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Possiamo osservare che l'importanza variabile dipende principalmente dal numero di categorie, il che mi porta a mettere in discussione l'utilità di questi grafici in generale. Soprattutto l'importanza di age raggiungere valori molto più alti rispetto alla sua controparte continua.

E, infine, un esempio se li lascio come variabili fittizie (solo bmi):

# Split one of the continuous variables up into a categorical variable with i balanced classes
X_test = X.copy()
n_categories = 5
X_test['bmi'] = pd.cut(X_test['bmi'],
                       np.percentile(X['bmi'], np.linspace(0,100,n_categories+1)),
                       labels=[chr(num+65) for num in range(n_categories)])
X_test = pd.get_dummies(X_test, drop_first=True)

# Plot the feature importances
rects = plot_feature_importance(X_test,y, feats_to_highlight=['bmi_B','bmi_C','bmi_D', 'bmi_E'])
plt.title(f"Feature importances for {n_categories} bmi categories")

inserisci qui la descrizione dell'immagine

Risposte:


8

Quando si lavora sull'importanza delle funzionalità in generale, è utile ricordare che nella maggior parte dei casi un approccio di regolarizzazione è spesso una buona alternativa. "Seleziona automaticamente le funzionalità più importanti" per il problema in questione. Ora, se non vogliamo seguire la nozione di regolarizzazione (di solito nel contesto della regressione), i classificatori di foreste casuali e la nozione di test di permutazione danno naturalmente una soluzione per presentare l'importanza di un gruppo di variabili. In realtà questo è stato chiesto prima qui: " L'importanza relativa di un insieme di predittori in una classificazione casuale delle foreste in R " qualche anno fa. Approcci più rigorosi come quelli di Gregorutti et al.: " Raggruppata importanza variabile con foreste casuali e applicazione all'analisi di dati funzionali multivariati". La selezione di utili gruppi di funzionalità di Chakraborty & Pal in un framework connessionista esamina questo compito nel contesto di un Perceptron multistrato. Tornando al documento di Gregorutti et al. La loro metodologia è direttamente applicabile a qualsiasi tipo di algoritmo di classificazione / regressione In breve, utilizziamo una versione casualmente permutata in ogni campione out-of-bag utilizzato durante l'allenamento.

Avendo affermato quanto sopra, mentre i test di permutazione sono in ultima analisi euristici, ciò che è stato risolto accuratamente in passato è la penalizzazione delle variabili fittizie nel contesto della regressione regolarizzata. La risposta a questa domanda è Group-LASSO , Group-LARS e Group-Garotte . Articoli fondamentali in quel lavoro sono Yuan e Lin: " Selezione del modello e stima nella regressione con variabili raggruppate " (2006) e Meier et al.: " Il lazo di gruppo per la regressione logistica " (2008). Questa metodologia ci consente di lavorare in situazioni in cui: " ogni fattore può avere diversi livelli e può essere espresso attraverso un gruppo di variabili fittizie " (Y&L 2006). L'effetto è tale che "l1Kjj={1,...,J}Jpyglmnetregolarizzazione lazo raggruppata .]

Tutto sommato, non ha senso semplicemente "sommare" l'importanza della variabile dalle singole variabili fittizie perché non catturerebbe l'associazione tra loro e porterebbe a risultati potenzialmente privi di significato. Detto questo, sia i metodi penalizzati dal gruppo che i metodi di importanza variabile di permutazione forniscono un quadro coerente e (soprattutto nel caso delle procedure di importanza di permutazione) generalmente applicabile per farlo.

Finalmente per affermare l'ovvio: non bin dati continui . È una cattiva pratica, c'è un ottimo filo su questo argomento qui (e qui ). Il fatto che osserviamo risultati spuri dopo la discretizzazione di variabili continue age, non è sorprendente. Frank Harrell ha anche scritto di estendere i problemi causati dalla categorizzazione delle variabili continue .


Colleghi L'importanza relativa di un insieme di predittori in una classificazione di foreste casuali in R risponde direttamente alla domanda. Sarei felice di accettare se sposti il ​​riferimento a quel link all'inizio poiché non penso che il resto sia direttamente pertinente e che il link possa facilmente perdersi nella risposta.
Dan,

Nessun problema. Ho apportato alcune modifiche pertinenti. Non respingere il concetto di regressione regolarizzata, come ho già detto nel testo, gli approcci alla regolarizzazione offrono un'alternativa perfettamente valida alla caratteristica importanza / classifica.
usεr11852 dice Reinstate Monic il

La regressione regolarizzata non è una risposta a questa domanda, può rispondere a una domanda diversa, vale a dire alternative all'importanza delle caratteristiche, ma questa domanda riguarda l'aggregazione delle caratteristiche in una singola caratteristica categoriale all'interno di un diagramma dell'importanza delle caratteristiche. Penso davvero che dovresti spostare il link che in realtà risponde alla domanda all'inizio.
Dan

2

La domanda è:

ha senso ricombinare le finte variabili variabili in un valore di importanza per una variabile categoriale semplicemente sommandole?

La breve risposta:

iomportun'nce(Xl)=io
(io)2=Σt=1J-1io2io(v(t)=)
io=Σt=1J-1io2io(v(t)=)

La risposta più lunga e più pratica.

Non puoi semplicemente sommare i singoli valori di importanza delle variabili per variabili fittizie perché rischi

il mascheramento di variabili importanti da parte di terzi con i quali sono altamente correlati. (pagina 368)

Problemi come la possibile multicollinearità possono distorcere i valori e le classifiche di importanza variabile.

In realtà è un problema molto interessante capire come l'importanza variabile sia influenzata da problemi come la multicollinearità. L'articolo che determina l'importanza dei predittori nella regressione multipla in varie condizioni di correlazione e distribuzione discute vari metodi per calcolare l'importanza delle variabili e confronta le prestazioni per i dati che violano i presupposti statistici tipici. Gli autori lo hanno scoperto

Sebbene la multicollinearità abbia influito sulle prestazioni dei metodi di importanza relativa, la non anomalia multivariata non ha influito. (WHITTAKER p366)


Non credo che la tua seconda citazione sia pertinente. Queste non sono variabili altamente correlate, sono la stessa variabile e una buona implementazione di un albero decisionale non richiederebbe OHE ma le tratterà come un'unica variabile. Semmai, la multicolinearità viene introdotta artificialmente da OHE.
Dan

Per quanto riguarda il tuo primo punto, mi fa male come il numero di importanza relativa proposto da Breiman sia il valore al quadrato. Quindi non sono convinto che sklearn abbia prima le radici quadrate come hai suggerito. Inoltre, in caso affermativo, non dovrei prima quadrare i valori, aggiungerli e quindi radicare al quadrato la somma? Non sono sicuro di aver capito il tuo suggerimento di prendere prima la radice quadrata.
Dan

@ecedavis Cosa intendi per libro di testo? Potete fornire un link o una citazione più completa per favore.
vedi24

Ciao, grazie per le critiche e per il mio primo voto come nuovo membro. I tuoi commenti indicano dettagli specifici che affronterò nella mia revisione, ma posso anche avere la tua opinione sulla qualità generale della mia risposta? Questo è il mio primo post e ho intenzione di diventare un collaboratore regolare. Spero almeno che la mia risposta sia generalmente utile e di buon stile. Quali sono i tuoi pensieri?
ecedavis,

Lo stile della tua risposta è buono ma alcune informazioni e contenuti non sembrano completamente corretti. L'articolo a cui ti colleghi riguarda l'importanza del predittore nella regressione multipla mentre la domanda riguarda l'importanza nella foresta casuale. Trovo anche che la tua estrazione della citazione sia problematica poiché l'intera frase è "Inoltre, a causa del restringimento (Sezione 10.12.1) il mascheramento di variabili importanti da parte di altri con i quali sono altamente correlati è molto meno un problema". che ha un significato molto diverso.
vedi24
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.