Quando dovremmo discretizzare / binare variabili / caratteristiche indipendenti continue e quando no?


21

Quando dovremmo discretizzare / binare variabili / caratteristiche indipendenti e quando no?

I miei tentativi di rispondere alla domanda:

  • In generale, non dovremmo fare il bin, perché il binning perderà informazioni.
  • Il binning sta effettivamente aumentando il grado di libertà del modello, quindi è possibile causare un eccesso di adattamento dopo il binning. Se disponiamo di un modello "bias elevato", il binning potrebbe non essere male, ma se abbiamo un modello "varianza elevata", dovremmo evitare il binning.
  • Dipende dal modello che stiamo usando. Se si tratta di una modalità lineare e i dati hanno molte probabilità di binning "anomali" è migliore. Se abbiamo un modello ad albero, allora, outlier e binning faranno troppa differenza.

Ho ragione? e che altro?


Ho pensato che questa domanda dovesse essere posta molte volte, ma non riesco a trovarla nel CV solo in questi post

Dovremmo binare variabili continue?

Qual è il vantaggio di spezzare una variabile predittiva continua?


Non penso che questa domanda sia un duplicato perché la risposta in realtà non affronta questo problema ("dovremmo farlo").
Firebug

8
Gli approcci CART / foresta casuale sono più o meno variabili binning continue (adattando funzioni costanti a tratti), ma lo stanno facendo in un modo molto migliore. Se pre-bin, stai negando al tuo algoritmo di costruzione degli alberi la flessibilità di mettere le pause in un posto ottimale ...
Ben Bolker

Risposte:


16

Sembra che tu stia anche cercando una risposta dal punto di vista predittivo, quindi ho messo insieme una breve dimostrazione di due approcci in R

  • Binning di una variabile in fattori di uguali dimensioni.
  • Spline cubiche naturali.

Di seguito, ho fornito il codice per una funzione che confronterà automaticamente i due metodi per una data funzione di segnale reale

test_cuts_vs_splines <- function(signal, N, noise,
                                 range=c(0, 1), 
                                 max_parameters=50,
                                 seed=154)

Questa funzione creerà set di dati di addestramento e test rumorosi da un determinato segnale, quindi inserirà una serie di regressioni lineari sui dati di allenamento di due tipi

  • Il cutsmodello include predittori integrati, formati segmentando l'intervallo di dati in intervalli di mezza apertura di uguale dimensione e quindi creando predittori binari che indicano a quale intervallo appartiene ciascun punto di allenamento.
  • Il splinesmodello include un'espansione di base spline cubica naturale, con nodi equidistanti su tutta la gamma del predittore.

Gli argomenti sono

  • signal: Una funzione con una variabile che rappresenta la verità da stimare.
  • N: Il numero di campioni da includere sia nei dati di addestramento che di test.
  • noise: L'abbondanza di rumore gaussiano casuale da aggiungere al segnale di allenamento e test.
  • range: La gamma dei xdati di addestramento e test , i dati sono generati in modo uniforme all'interno di questo intervallo.
  • max_paramters: Il numero massimo di parametri da stimare in un modello. Questo è sia il numero massimo di segmenti nel cutsmodello sia il numero massimo di nodi nel splinesmodello.

Si noti che il numero di parametri stimati nel splinesmodello è uguale al numero di nodi, quindi i due modelli sono equamente confrontati.

L'oggetto return dalla funzione ha alcuni componenti

  • signal_plot: Un grafico della funzione del segnale.
  • data_plot: Un diagramma a dispersione dei dati di addestramento e test.
  • errors_comparison_plot: Un diagramma che mostra l'evoluzione della somma del tasso di errore al quadrato per entrambi i modelli su un intervallo del numero di parametri stimati.

Dimostrerò con due funzioni di segnale. La prima è un'onda sin con una tendenza lineare crescente sovrapposta

true_signal_sin <- function(x) {
  x + 1.5*sin(3*2*pi*x)
}

obj <- test_cuts_vs_splines(true_signal_sin, 250, 1)

Ecco come si evolvono i tassi di errore

raggruppamento vs spline allenano e testano le prestazioni con diverso grado di libertà per aumentare l'onda sin

Il secondo esempio è una funzione folle che tengo in giro solo per questo genere di cose, trama e vedo

true_signal_weird <- function(x) {
  x*x*x*(x-1) + 2*(1/(1+exp(-.5*(x-.5)))) - 3.5*(x > .2)*(x < .5)*(x - .2)*(x - .5)
}

obj <- test_cuts_vs_splines(true_signal_weird, 250, .05)

raggruppamento vs spline allenano e testano le prestazioni con diverso grado di libertà per aumentare la funzione bizarro

E per divertimento, ecco una noiosa funzione lineare

obj <- test_cuts_vs_splines(function(x) {x}, 250, .2)

raggruppamento vs spline allenano e testano le prestazioni con diverso grado di libertà per la funzione lineare

Potete vederlo:

  • Le spline offrono prestazioni complessive di prova complessivamente migliori quando la complessità del modello è sintonizzata correttamente per entrambi.
  • Le spline offrono prestazioni di prova ottimali con molti meno parametri stimati .
  • Nel complesso, le prestazioni delle spline sono molto più stabili poiché il numero di parametri stimati è variato.

Quindi le spline devono essere sempre preferite da un punto di vista predittivo.

Codice

Ecco il codice che ho usato per produrre questi confronti. Ho racchiuso tutto in una funzione in modo che tu possa provarlo con le tue funzioni di segnale. Dovrai importare le librerie ggplot2e splinesR.

test_cuts_vs_splines <- function(signal, N, noise,
                                 range=c(0, 1), 
                                 max_parameters=50,
                                 seed=154) {

  if(max_parameters < 8) {
    stop("Please pass max_parameters >= 8, otherwise the plots look kinda bad.")
  }

  out_obj <- list()

  set.seed(seed)

  x_train <- runif(N, range[1], range[2])
  x_test <- runif(N, range[1], range[2])

  y_train <- signal(x_train) + rnorm(N, 0, noise)
  y_test <- signal(x_test) + rnorm(N, 0, noise)

  # A plot of the true signals
  df <- data.frame(
    x = seq(range[1], range[2], length.out = 100)
  )
  df$y <- signal(df$x)
  out_obj$signal_plot <- ggplot(data = df) +
    geom_line(aes(x = x, y = y)) +
    labs(title = "True Signal")

  # A plot of the training and testing data
  df <- data.frame(
    x = c(x_train, x_test),
    y = c(y_train, y_test),
    id = c(rep("train", N), rep("test", N))
  )
  out_obj$data_plot <- ggplot(data = df) + 
    geom_point(aes(x=x, y=y)) + 
    facet_wrap(~ id) +
    labs(title = "Training and Testing Data")

  #----- lm with various groupings -------------   
  models_with_groupings <- list()
  train_errors_cuts <- rep(NULL, length(models_with_groupings))
  test_errors_cuts <- rep(NULL, length(models_with_groupings))

  for (n_groups in 3:max_parameters) {
    cut_points <- seq(range[1], range[2], length.out = n_groups + 1)
    x_train_factor <- cut(x_train, cut_points)
    factor_train_data <- data.frame(x = x_train_factor, y = y_train)
    models_with_groupings[[n_groups]] <- lm(y ~ x, data = factor_train_data)

    # Training error rate
    train_preds <- predict(models_with_groupings[[n_groups]], factor_train_data)
    soses <- (1/N) * sum( (y_train - train_preds)**2)
    train_errors_cuts[n_groups - 2] <- soses

    # Testing error rate
    x_test_factor <- cut(x_test, cut_points)
    factor_test_data <- data.frame(x = x_test_factor, y = y_test)
    test_preds <- predict(models_with_groupings[[n_groups]], factor_test_data)
    soses <- (1/N) * sum( (y_test - test_preds)**2)
    test_errors_cuts[n_groups - 2] <- soses
  }

  # We are overfitting
  error_df_cuts <- data.frame(
    x = rep(3:max_parameters, 2),
    e = c(train_errors_cuts, test_errors_cuts),
    id = c(rep("train", length(train_errors_cuts)),
           rep("test", length(test_errors_cuts))),
    type = "cuts"
  )
  out_obj$errors_cuts_plot <- ggplot(data = error_df_cuts) +
    geom_line(aes(x = x, y = e)) +
    facet_wrap(~ id) +
    labs(title = "Error Rates with Grouping Transformations",
         x = ("Number of Estimated Parameters"),
         y = ("Average Squared Error"))

  #----- lm with natural splines -------------  
  models_with_splines <- list()
  train_errors_splines <- rep(NULL, length(models_with_groupings))
  test_errors_splines <- rep(NULL, length(models_with_groupings))

  for (deg_freedom in 3:max_parameters) {
    knots <- seq(range[1], range[2], length.out = deg_freedom + 1)[2:deg_freedom]

    train_data <- data.frame(x = x_train, y = y_train)
    models_with_splines[[deg_freedom]] <- lm(y ~ ns(x, knots=knots), data = train_data)

    # Training error rate
    train_preds <- predict(models_with_splines[[deg_freedom]], train_data)
    soses <- (1/N) * sum( (y_train - train_preds)**2)
    train_errors_splines[deg_freedom - 2] <- soses

    # Testing error rate
    test_data <- data.frame(x = x_test, y = y_test)  
    test_preds <- predict(models_with_splines[[deg_freedom]], test_data)
    soses <- (1/N) * sum( (y_test - test_preds)**2)
    test_errors_splines[deg_freedom - 2] <- soses
  }

  error_df_splines <- data.frame(
    x = rep(3:max_parameters, 2),
    e = c(train_errors_splines, test_errors_splines),
    id = c(rep("train", length(train_errors_splines)),
           rep("test", length(test_errors_splines))),
    type = "splines"
  )
  out_obj$errors_splines_plot <- ggplot(data = error_df_splines) +
    geom_line(aes(x = x, y = e)) +
    facet_wrap(~ id) +
    labs(title = "Error Rates with Natural Cubic Spline Transformations",
         x = ("Number of Estimated Parameters"),
         y = ("Average Squared Error"))


  error_df <- rbind(error_df_cuts, error_df_splines)
  out_obj$error_df <- error_df

  # The training error for the first cut model is always an outlier, and
  # messes up the y range of the plots.
  y_lower_bound <- min(c(train_errors_cuts, train_errors_splines))
  y_upper_bound = train_errors_cuts[2]
  out_obj$errors_comparison_plot <- ggplot(data = error_df) +
    geom_line(aes(x = x, y = e)) +
    facet_wrap(~ id*type) +
    scale_y_continuous(limits = c(y_lower_bound, y_upper_bound)) +
    labs(
      title = ("Binning vs. Natural Splines"),
      x = ("Number of Estimated Parameters"),
      y = ("Average Squared Error"))

  out_obj
}

19

L'aggregazione è sostanzialmente significativa (indipendentemente dal fatto che il ricercatore ne sia consapevole).

Uno dovrebbe bin dati, comprese le variabili indipendenti, in base ai dati stessi quando si desidera:

  • Emorragia potere statistico.

  • Per influenzare le misure di associazione.

Una letteratura che inizia, credo, con Ghelke e Biehl (1934 — merita sicuramente una lettura, e suggerisce alcune simulazioni al computer abbastanza facili da poter essere eseguiti da soli), e proseguendo soprattutto nella letteratura sul "problema modificabile dell'area unitaria" (Openshaw , 1983; Dudley, 1991; Lee e Kemp, 2000) chiariscono entrambi questi punti.

A meno che uno non abbia una teoria a priori della scala di aggregazione (quante unità aggregare a) e la funzione di categorizzazione dell'aggregazione (quali osservazioni individuali finiranno in quali unità aggregate), non si dovrebbe aggregare. Ad esempio, in epidemiologia, ci preoccupiamo della salute degli individui e della salute delle popolazioni . Le seconde non sono semplicemente raccolte casuali della prima, ma definite, ad esempio, da confini geopolitici, circostanze sociali come la categorizzazione etnica di razza, lo stato carcerale e le categorie di storia, ecc. (Vedi, ad esempio Krieger, 2012)

Riferimenti
Dudley, G. (1991). Scala, aggregazione e problema di unità areale modificabile . [pay-walled] The Operational Geographer, 9 (3): 28–33.

Gehlke, CE e Biehl, K. (1934). Alcuni effetti del raggruppamento sulla dimensione del coefficiente di correlazione nel materiale del tratto di censimento . [pay-walled] Journal of American Statistical Association , 29 (185): 169–170.

Krieger, N. (2012). Chi e che cos'è una "popolazione"? dibattiti storici, attuali controversie e implicazioni per la comprensione della "salute della popolazione" e la correzione delle disuguaglianze sanitarie . The Milbank Quarterly , 90 (4): 634–681.

Lee, HTK e Kemp, Z. (2000). Ragionamento gerarchico ed elaborazione analitica on-line di dati spaziali e temporali . Negli atti del nono simposio internazionale sulla gestione dei dati territoriali , Pechino, Cina. Unione geografica internazionale.

Openshaw, S. (1983). Il problema modificabile dell'unità areale. Concetti e tecniche nella geografia moderna . Geo Books, Norwich, Regno Unito.


10
Sono stato triste di votare questa risposta perché il tuo rappresentante è ora più grande di 8888, il che è stato esteticamente piacevole per me.
Sycorax dice di reintegrare Monica il

@ hxd1011 e GeneralAbrial:: D: D: D: D
Alexis

ADORO questa risposta, ma la risposta di @ MatthewDrury è davvero che voglio vedere.
Haitao Du,

Grazie per una risposta convincente con un sacco di riferimenti interessanti!
y.selivonchyk,
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.