【问题标题】:Regression with Date variable using Scikit-learn使用 Scikit-learn 使用日期变量进行回归
【发布时间】:2013-05-03 10:46:32
【问题描述】:

我有一个带有date 列的 Pandas DataFrame(例如:2013-04-01),dtype 为datetime.date。当我将该列包含在X_train 中并尝试拟合回归模型时,我收到错误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

【问题讨论】:

    标签: python python-2.7 numpy pandas scikit-learn


    【解决方案1】:

    你有两个选择。您可以将日期转换为序数,即表示自第 1 天第 1 天以来的天数的整数。您可以通过datetime.datetoordinal 函数来执行此操作。

    或者,您可以使用 sklearn 的 OneHotEncoder 将日期转换为分类变量。它所做的是为每个不同的日期创建一个新变量。因此,您将有两列,date_2013_04_01 的值 [1, 0]date_2013_05_01 的值 [0, 1],而不是类似列 date 的值 ['2013-04-01', '2013-05-01']

    如果您有许多不同的日期,我建议使用toordinal 方法,如果不同日期的数量很少(假设最多 10 - 100 个,具体取决于您的数据大小和内容),则建议使用一个热编码器日期与输出变量的某种关系)。

    【讨论】:

      【解决方案2】:

      最好的方法是使用 1-of-K 编码将日期分解为一组以布尔形式编码的分类特征(例如 DictVectorizer 所做的)。以下是可以从日期中提取的一些特征:

      • 一天中的小时(24 个布尔特征)
      • 星期几(7 个布尔特征)
      • 一个月中的某天(最多 31 个布尔特征)
      • 一年中的月份(12 个布尔特征)
      • 年(与数据集中不同年份的布尔特征一样多) ...

      这应该可以识别典型人类生命周期中周期性事件的线性依赖关系。

      此外,您还可以将日期提取为单个浮点数:将每个日期转换为自训练集最小日期以来的天数,然后除以最大日期与训练集天数之间的天数之差最小日期。该数字特征应该可以识别事件日期输出之间的长期趋势:例如回归问题中的线性斜率,以更好地预测未来年份的演变,该年份无法使用布尔分类变量进行编码。

      【讨论】:

      • 我找不到使用 scikit-learn 将日期(字符串格式)转换为多个特征的直接解决方案,所以我手动完成了 date_object = datetime.strptime('2016-25-05', '%Y/%d/%m') print 'week day', date_object.strftime('%w')
      • 你的回答很好。但是,我认为在某些情况下保持秩序很重要,例如:天的顺序,或一周中的天的顺序。我认为这取决于问题并尝试不同的方式。
      【解决方案3】:

      在使用@ogrisel 建议的 1-of-K 编码进行布尔编码之前,您可以尝试丰富您的数据并使用您可以从 datetime 类型中提取的特征数量,即星期几、星期几月、一年中的某一天、一年中的一周、季度等。 参见例如https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DatetimeIndex.weekofyear.html 和其他功能的链接。

      【讨论】:

        【解决方案4】:

        通常最好将特征数量保持在较低水平,并且时间戳中不需要太多信息。在我的情况下,将日期保持为与初始时间戳的日差就足够了。这样可以保持顺序,并且只会留下一个(序数)特征。

        df['DAY_DELTA'] = (df.TIMESTAMP - df.TIMESTAMP.min()).dt.days
        

        当然,这不会在一天内识别行为(取决于小时)。因此,也许您想降低到最能识别数据中不断变化的行为的规模。

        小时数:

        df['HOURS_DELTA'] = (df.TIMESTAMP - df.TIMESTAMP.min()).dt.components['hours']
        

        上面的代码添加了一个带有 delta 值的新列,之后要删除旧的 TIMESTAMP:

        df = df.drop('TIMESTAMP', axis=1)
        

        【讨论】:

          【解决方案5】:

          我通常将 DateTime 转换为感兴趣的特征,例如年、月、日、小时、分钟。

          df['Year'] = df['Timestamp'].apply(lambda time: time.year)
          
          df['Month'] = df['Timestamp'].apply(lambda time: time.month)
          
          df['Day'] = df['Timestamp'].apply(lambda time: time.day)
          
          df['Hour'] = df['Timestamp'].apply(lambda time: time.hour)
          
          df['Minute'] = df['Timestamp'].apply(lambda time: time.minute)
          

          【讨论】:

            猜你喜欢
            • 2016-06-17
            • 2020-01-02
            • 2018-07-31
            • 2016-11-14
            • 2017-12-31
            • 2014-06-13
            • 2016-05-16
            • 2018-01-14
            相关资源
            最近更新 更多