Регрессия с переменной Date с использованием Scikit-learn

У меня есть Pandas DataFrame с столбцом date (например: 2013-04-01) dtype datetime.date. Когда я включаю этот столбец в X_train и пытаюсь подобрать модель регрессии, я получаю float() argument must be a string or a number error float() argument must be a string or a number. Удаление столбца date предотвратило эту ошибку.

Каков правильный способ учета date в модели регрессии?

Код

data = sql.read_frame(...)
X_train = data.drop('y', axis=1)
y_train = data.y

rf = RandomForestRegressor().fit(X_train, y_train)

ошибка

TypeError                                 Traceback (most recent call last)
<ipython-input-35-8bf6fc450402> in <module>()
----> 2 rf = RandomForestRegressor().fit(X_train, y_train)

C:\Python27\lib\site-packages\sklearn\ensemble\forest.pyc in fit(self, X, y, sample_weight)
    292                 X.ndim != 2 or
    293                 not X.flags.fortran):
--> 294             X = array2d(X, dtype=DTYPE, order="F")
    295 
    296         n_samples, self.n_features_ = X.shape

C:\Python27\lib\site-packages\sklearn\utils\validation.pyc in array2d(X, dtype, order, copy)
     78         raise TypeError('A sparse matrix was passed, but dense data '
     79                         'is required. Use X.toarray() to convert to dense.')
---> 80     X_2d = np.asarray(np.atleast_2d(X), dtype=dtype, order=order)
     81     _assert_all_finite(X_2d)
     82     if X is X_2d and copy:

C:\Python27\lib\site-packages\numpy\core\numeric.pyc in asarray(a, dtype, order)
    318 
    319     """
--> 320     return array(a, dtype, copy=False, order=order)
    321 
    322 def asanyarray(a, dtype=None, order=None):

TypeError: float() argument must be a string or a number

Ответ 1

Лучший способ - взорвать дату в набор категориальных функций, закодированных в логической форме, с использованием кодирования 1-к-K (например, как это сделано DictVectorizer). Вот некоторые функции, которые можно извлечь из даты:

  • час дня (24 логических объекта)
  • день недели (7 булевых функций)
  • день месяца (до 31 логических функций)
  • месяц года (12 логических функций)
  • год (как много логических функций, поскольку они разные годы в вашем наборе данных)...

Это должно позволить идентифицировать линейные зависимости от периодических событий на типичных жизненных циклах человека.

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

Ответ 2

У вас есть два варианта. Вы можете преобразовать дату в порядковый номер, т. toordinal Целое число, представляющее количество дней с 1-го дня 1-го дня. Вы можете сделать это с помощью функции datetime.date toordinal.

Кроме того, вы можете включить даты в категориальные переменные, используя sklearn OneHotEncoder. Он создает новую переменную для каждой отдельной даты. Так что вместо того, чтобы что - то вроде столбца date со значениями ['2013-04-01', '2013-05-01'], вы будете иметь две колонки, date_2013_04_01 со значениями [1, 0] и date_2013_05_01 со значениями [0, 1],

Я бы рекомендовал использовать подход toordinal если у вас много разных дат, и один горячий кодировщик, если количество отдельных дат невелико (допустим, до 10 - 100, в зависимости от размера ваших данных и какого рода отношение к дате имеет с выходной переменной).

Ответ 3

Прежде чем делать булево кодирование с использованием кодировки 1-в-K, предложенной @ogrisel, вы можете попробовать обогатить свои данные и сыграть с количеством функций, которые вы можете извлечь из типа datetime, то есть день недели, день месяца, день года, недели года, квартала и т.д. См. например https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DatetimeIndex.weekofyear.html и ссылки на другие функции.