Оптимальное построение дневной функции в нейронных сетях


19

Работая над проблемой регрессии, я начал думать о представлении функции «день недели». Интересно, какой подход будет работать лучше:

  • одна особенность; значение 1/7 для понедельника; 2/7 для вторника ...
  • 7 функций: (1, 0, 0, 0, 0, 0, 0) для понедельника; (0, 1, 0, 0, 0, 0, 0) для вторника ...

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

Количество всех функций около 20. Я использую простой backprop, чтобы изучить обычную прямую нейронную сеть.


Как насчет использования двоичного кодирования для дня недели? 3 функции, где (0, 0, 0) - воскресенье. (0, 0, 1) для понедельника и так далее?
Shamoon

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

Ответы:


23

Ваше второе представление более традиционно для категориальных переменных, таких как день недели.

Это также известно как создание фиктивных переменных и широко используется для кодирования категориальных переменных. Если вы использовали кодирование 1-7, вы говорите модели, что дни 4 и 5 очень похожи, а дни 1 и 7 очень разные. Фактически, дни 1 и 7 аналогичны дням 4 и 5. Та же логика действует для кодирования 0-30 для дней месяца.

День месяца немного сложнее, потому что, хотя каждая неделя имеет одинаковые 7 дней, не каждый месяц имеет одинаковые 30 дней: некоторые месяцы имеют 31 день, а некоторые месяцы имеют 28 дней. Поскольку и недели, и месяцы являются циклическими, вы можете использовать преобразования Фурье для преобразования их в гладкие линейные переменные.

Например ( используя R, мой язык программирования по выбору ):

day_of_month = c(1:31, 1:28, 1:30)
day_of_year <- 1:length(day_of_month)
s = sin((2*pi)/30*day_of_month)
c = cos((2*pi)/30*day_of_month)
plot(day_of_month ~ day_of_year)
lines(15*s+15 ~ day_of_year, col='blue')
lines(15*c+15 ~ day_of_year, col='red')
legend(10, 30, c('raw', 'sin', 'cos'), c('black', 'blue', 'red'))

сырье против греха против косинуса

(Я масштабировал переменные синус / косинус до 0/30, а не -1/1, чтобы график выглядел лучше)

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

Вы можете добавить остальные термины Фурье следующим образом:

for(i in 1:3){
  s = sin((2*pi)/30*day_of_month + 30 * i/4)
  c = cos((2*pi)/30*day_of_month + 30 * i/4)
  lines(15*s+15 ~ day_of_year, col='blue')
  lines(15*c+15 ~ day_of_year, col='red')
}
legend(10, 30, c('raw', 'sin', 'cos'), c('black', 'blue', 'red'))

Полные преобразования

Каждая пара волн синус / косинус образует круг:

m <- lapply(1:4, function(i){
  as.matrix(
    data.frame(
    s = sin((2*pi)/30*day_of_month + 30 * i/4),
    c = cos((2*pi)/30*day_of_month + 30 * i/4)
    )
  )
})
m <- do.call(cbind, m)
pairs(m)

круг На этой странице есть очень удобное объяснение того, как управлять волнами синуса и косинуса.


Есть ли конкретная причина для этого? Интересно, как это могло повлиять на конвергенцию? Мое второе сомнение - когда переменная все еще категориальна - как насчет дня месяца? (0 - 30)
Oepas Dost

То же самое; используйте переменные индикатора. Первое кодирование вызывает меру сходства, которая может быть неуместной; Например, действительно ли воскресенье - самый непохожий день с понедельника? Это то, что подразумевает кодировка ...
Эмре

@OepasDost Если мой пост отвечает на ваш вопрос, вы можете проголосовать за него и / или принять его, нажав на галочку.
Зак

@ Зачем вы считаете день недели (который можно кодировать от 0 до 6) категориальным, а день месяца - порядковым циклическим (и, следовательно, используйте преобразование Фурье). И не оба ли они как порядковые циклические и, следовательно, также преобразование Фурье для дня недели?
zipp

1
@zipp Вы также можете использовать Фурье для дня недели. По моему опыту, основное значение дня недели - это разница между днями недели и выходными, которую очень просто зафиксировать с помощью фиктивных переменных (или переменной индикатора).
Зак
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.