Когда мы должны дискретизировать / bin непрерывные независимые переменные / функции, а когда нет?


22

Когда мы должны дискретизировать / bin независимые переменные / функции, а когда нет?

Мои попытки ответить на вопрос:

  • В общем, мы не должны bin, потому что binning потеряет информацию.
  • Биннинг на самом деле увеличивает степень свободы модели, поэтому после биннинга возможна чрезмерная подгонка. Если у нас модель «высокого смещения», биннинг может быть неплохим, но если у нас модель «высокого отклонения», нам следует избегать биннинга.
  • Это зависит от того, какую модель мы используем. Если это линейный режим, а данные имеют много «выбросов», то вероятность биннинга лучше. Если у нас есть модель дерева, то выбросы и биннинг будут иметь слишком большое значение.

Я прав? и что еще?


Я думал, что этот вопрос нужно задавать много раз, но я не могу найти его в резюме, только эти сообщения

Должны ли мы бин непрерывных переменных?

В чем выгода разделения непрерывной переменной-предиктора?


Я не думаю, что этот вопрос является дубликатом, потому что ответ на самом деле не решает эту проблему («мы должны это сделать»).
Firebug

8
Подходы CART / случайный лес - это более или менее объединяющие непрерывные переменные (подходящие кусочно-постоянные функции), но они делают это намного лучше. Если вы делаете предварительный сбор, вы отказываете своему алгоритму построения деревьев в гибкости, позволяющей размещать разрывы в оптимальном месте ...
Бен Болкер

Ответы:


16

Похоже, вы также ищете ответ с точки зрения прогнозирования, поэтому я собрал краткую демонстрацию двух подходов в R

  • Преобразование переменной в факторы равного размера.
  • Естественные кубические сплайны.

Ниже я дал код для функции, которая автоматически сравнивает два метода для любой заданной функции истинного сигнала

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

Эта функция создаст зашумленные обучающие и тестовые наборы данных из данного сигнала, а затем подгонит ряд линейных регрессий к обучающим данным двух типов.

  • cutsМодель включает в себя Binned предикторов, образованных сегментировании диапазона данных на равные по размеру половиной открытых интервалы, а затем создать двоичные предикторы указывающих на какой интервал каждой точка обучения принадлежит.
  • splinesМодель включает в себя естественный кубический сплайн расширение базиса, с узлами , равномерно распределенных по всему диапазону предиктора.

Аргументы

  • signal: Одна переменная функция, представляющая истину, которая будет оценена.
  • N: Количество образцов, включаемых в данные обучения и тестирования.
  • noise: Уровень случайного гауссовского шума, добавляемый к сигналу тренировки и тестирования.
  • range: Диапазон данных обучения и тестирования x, данные, которые генерируются равномерно в этом диапазоне.
  • max_paramters: Максимальное количество параметров для оценки в модели. Это и максимальное количество сегментов в cutsмодели, и максимальное количество узлов в splinesмодели.

Обратите внимание, что количество параметров, оцениваемых в splinesмодели, совпадает с количеством узлов, поэтому две модели сравниваются.

Возвращаемый объект из функции имеет несколько компонентов

  • signal_plot: График функции сигнала.
  • data_plot: Точечный график данных обучения и тестирования.
  • errors_comparison_plot: График, показывающий эволюцию суммы квадратов частоты ошибок для обеих моделей в диапазоне числа оцененных параметров.

Я продемонстрирую с двумя функциями сигнала. Первая - это синусоида с нарастающим линейным трендом

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

obj <- test_cuts_vs_splines(true_signal_sin, 250, 1)

Вот как развиваются показатели ошибок

группировка против сплайнов обучает и тестирует производительность с различной степенью свободы для увеличения синусоиды

Второй пример - сумасшедшая функция, которую я использую только для такого рода вещей.

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)

группировка против сплайнов тренирует и тестирует производительность с различной степенью свободы для увеличения бисарро-функции

А для развлечения вот скучная линейная функция

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

группировка против сплайнов обучает и тестирует производительность с различной степенью свободы для линейной функции

Ты это видишь:

  • Сплайны дают в целом лучшую общую производительность теста, когда сложность модели должным образом настроена для обоих.
  • Сплайны дают оптимальную производительность теста с гораздо меньшими оценочными параметрами .
  • В целом производительность сплайнов гораздо стабильнее, так как количество оценочных параметров варьируется.

Поэтому сплайны всегда предпочтительнее с точки зрения прогнозирования.

Код

Вот код, который я использовал для сравнения. Я обернул все это в функцию, чтобы вы могли опробовать ее с вашими собственными сигнальными функциями. Вам нужно будет импортировать библиотеки ggplot2и 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

Агрегирование имеет существенное значение (знает ли об этом исследователь или нет).

Нужно объединять данные, включая независимые переменные, на основе самих данных, когда нужно :

  • Кровоизлияние статистическая сила.

  • Предвзятости меры ассоциации.

Я полагаю, что литература началась с Гельке и Биля (1934 г. - определенно стоит почитать и предлагает некоторые достаточно простые компьютерные симуляции, которые можно запустить для себя) и продолжилась, особенно в литературе, посвященной проблеме модифицируемой ареальной единицы (Openshaw). , 1983; Дадли, 1991; Ли и Кемп, 2000).

Если у человека нет априорной теории шкалы агрегации (сколько единиц агрегирования) и функции категоризации агрегации (какие отдельные наблюдения будут заканчиваться в каких единицах агрегации), нельзя агрегировать. Например, в эпидемиологии мы заботимся о здоровье людей и о здоровье населения . Последние представляют собой не просто случайные наборы первых, но определяются, например, геополитическими границами, социальными обстоятельствами, такими как расово-этническая категоризация, категории карцерального статуса и категории истории и т. Д. (См., Например, Krieger, 2012).

Ссылки
Дадли, Г. (1991). Масштаб, агрегация и модифицируемая ареальная проблема единиц . [платный] Оперативный географ, 9 (3): 28–33.

Gehlke, CE и Biehl, K. (1934). Определенное влияние группировки на величину коэффициента корреляции в материале переписного тракта . [платный] Журнал Американской статистической ассоциации , 29 (185): 169–170.

Кригер, Н. (2012). Кто и что такое «население»? исторические дебаты, текущие противоречия и последствия для понимания «здоровья населения» и устранения несправедливости в отношении здоровья . Milbank Quarterly , 90 (4): 634–681.

Lee, HTK and Kemp, Z. (2000). Иерархические рассуждения и оперативная аналитическая обработка пространственных и временных данных . В материалах 9-го Международного симпозиума по обработке пространственных данных , Пекин, КНР. Международный географический союз.

Openshaw S. (1983). Модифицируемая ареальная единичная задача. Концепции и методы в современной географии . Geo Books, Норвич, Великобритания.


10
Мне было грустно голосовать за этот ответ, потому что ваша репутация теперь больше, чем 8888, что было эстетически приятно для меня.
Sycorax сообщает, что восстановит Монику

@ hxd1011 и GeneralAbrial:: D: D: D: D
Алексис

Я люблю этот ответ, но ответ @ MatthewDrury действительно я хочу видеть.
Haitao Du

Спасибо за убедительный ответ с кучей интересных ссылок!
y.selivonchyk
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.