J'ai un Pandas DataFrame avec une colonne date
(par exemple: 2013-04-01
) de type d datetime.date
. Lorsque j'inclus cette colonne dans X_train
et que j'essaie de m'adapter au modèle de régression, j'obtiens l'erreur float() argument must be a string or a number
. La suppression de la colonne date
a évité cette erreur.
Quelle est la bonne façon de prendre en compte date
dans le modèle de régression?
Code
data = sql.read_frame(...)
X_train = data.drop('y', axis=1)
y_train = data.y
rf = RandomForestRegressor().fit(X_train, y_train)
Erreur
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
La meilleure méthode consiste à décomposer la date en un ensemble de caractéristiques catégorielles codées sous forme booléenne à l’aide du codage 1-of-K (par exemple, comme indiqué par DictVectorizer ). Voici quelques fonctionnalités pouvant être extraites d'une date:
Cela devrait permettre d'identifier des dépendances linéaires d'événements périodiques sur des cycles de vie typiques.
En outre, vous pouvez également extraire la date d'un seul flotteur: convertissez chaque date en nombre de jours depuis la date minimale de votre entraînement et divisez-la par la différence entre le nombre de jours entre la date maximale et le nombre de jours de la date minimale. . Cette caractéristique numérique devrait permettre d’identifier les tendances à long terme entre le résultat de la date de l’événement: p. Ex. une pente linéaire dans un problème de régression pour mieux prévoir l'évolution des prochaines années qui ne peut pas être encodée avec la variable catégorique booléenne pour l'entité année.
Vous avez deux options. Vous pouvez convertir la date en un ordinal, c'est-à-dire un entier représentant le nombre de jours depuis l'année 1 jour 1. Vous pouvez le faire à l'aide de la fonction toordinal
de datetime.date
.
Sinon, vous pouvez transformer les dates en variables catégorielles à l'aide de OneHotEncoder de sklearn. Cela crée une nouvelle variable pour chaque date distincte. Ainsi, au lieu de quelque chose comme la colonne date
avec les valeurs ['2013-04-01', '2013-05-01']
, vous aurez deux colonnes, date_2013_04_01
avec les valeurs [1, 0]
et date_2013_05_01
avec les valeurs [0, 1]
.
Je recommanderais d'utiliser l'approche toordinal
si vous avez plusieurs dates différentes, et le seul encodeur chaud si le nombre de dates distinctes est petit (disons jusqu'à 10 - 100, en fonction de la taille de vos données et du type de relation entre a avec la variable de sortie).
Avant de procéder au codage booléen à l’aide du codage 1-of-K proposé par @ogrisel, vous pouvez essayer d’enrichir vos données et de jouer avec le nombre de fonctionnalités que vous pouvez extraire du type date/heure, à savoir jour de la semaine, jour du mois de l'année, semaine de l'année, trimestre, etc. Voir par exemple https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DatetimeIndex.weekofyear.html à d'autres fonctions.