zoukankan      html  css  js  c++  java
  • 自行车需求预测

    1. 问题

    今天来看一个回归问题——Kaggle竞赛Bike Sharing Demand,根据日期时间、天气、温度等特征,预测自行车的租借量。训练与测试数据集大概长这样:

    // train
    datetime,season,holiday,workingday,weather,temp,atemp,humidity,windspeed,casual,registered,count
    2011-01-01 00:00:00,1,0,0,1,9.84,14.395,81,0,3,13,16
    2011-01-01 01:00:00,1,0,0,1,9.02,13.635,80,0,8,32,40
    
    // test
    datetime,season,holiday,workingday,weather,temp,atemp,humidity,windspeed
    2011-01-20 00:00:00,1,0,1,1,10.66,11.365,56,26.0027
    2011-01-20 01:00:00,1,0,1,1,10.66,13.635,56,
    

    观察上面的数据,我们可以发现:租借量等于注册用户租借量加上未注册用户租借量,即casual + registered。评价指标是loss函数RMSLE (Root Mean Squared Logarithmic Error):

    [sqrt{frac{1}{n} sum_{i=1}^n (log (p_i +1) - log (a_i+1))^2 } ]

    其中,(p_i)为预测的租借量,(a_i)为实际的租借量,(n)为样本数。实际上,RMSLE就是一个误差函数。

    2. 分析

    特征工程

    日期时间放在一个string字段里,我们需要解析出年、月、weekday、小时等,之所以没有选择天做特征,是因为weekday更具有周期性、代表性。

    import pandas as pd
    
    train = pd.read_csv("data/train.csv", parse_dates=[0],
                        date_parser=lambda d: pd.datetime.strptime(d, '%Y-%m-%d %H:%M:%S'))
    train['year'] = train['datetime'].map(lambda d: d.year)
    train['month'] = train['datetime'].map(lambda d: d.month)
    train['hour'] = train['datetime'].map(lambda d: d.hour)
    train['weekday'] = train['datetime'].map(lambda d: d.weekday())
    train['day'] = train['datetime'].map(lambda d: d.day)
    

    为了方便计算,我们categorical化部分特征:

    df['weather'] = df['weather'].astype('category')
    df['holiday'] = df['holiday'].astype('category')
    df['workingday'] = df['workingday'].astype('category')
    df['season'] = df['season'].astype('category')
    df['hour'] = df['hour'].astype('category')
    

    选用的特征如下:

    features = ['season', 'holiday', 'workingday', 'weather', 'temp', 'atemp', 'humidity',
                'windspeed', 'time', 'weekday', 'year']
    

    之所以丢掉了month特征,是因为发现有过拟合。

    回归

    选用GBM来做回归,参数是通过grid_search挑出来的:

    booster = ensemble.GradientBoostingRegressor(n_estimators=500)
    
    param_grid = {'learning_rate': [0.1, 0.05, 0.01],
                  'max_depth': [10, 15, 20],
                  'min_samples_leaf': [3, 5, 10, 20],
                  }
    gs_cv = GridSearchCV(booster, param_grid, n_jobs=4).fit(training[features], training['log-count'])
    # best hyperparameter setting
    print(gs_cv.best_params_)
    # {'learning_rate': 0.05, 'max_depth': 10, 'min_samples_leaf': 20}
    

    该方法的RMSLE为0.43789。前面提到了租借量为casual + registered之和,那么我们可以把这两者看做类别,分别用GBM进行预测,然后相加后得到结果。结果的确将RMSLE降低到了0.41983。

    前面只用到了一种回归方法,那能不能将GBM与RF的结果合到一起呢?答案是可以的,通过赋权值0.5(即平均ensemble)的方式将两个结果组合起来,RMSLE降低到了0.37022。评价指标结果对比如下:

    特征 回归 RMSLE
    +年、星期、小时 GBM 0.43789
    GBM + GBM 0.41983
    GBM RF ensemble 0.37022

    结论:ensemble真是个好方法,三个臭皮匠赛过诸葛亮。

    3. 参考资料

    [1] 阿波, kaggle上的自行车出租数量预测.
    [2] Damien RJ, Forecasting Bike Sharing Demand.

  • 相关阅读:
    zoj 3279 线段树 OR 树状数组
    fzu 1962 树状数组 OR 线段树
    hdu 5057 块状链表
    hdu3487 Play with Chain
    bzoj 1588营业额统计(HNOI 2002)
    poj2823 Sliding Window
    poj2828 Buy Tickets
    poj2395 Out of Hay
    poj3667 Hotel
    poj1703 Lost Cows
  • 原文地址:https://www.cnblogs.com/en-heng/p/6907839.html
Copyright © 2011-2022 走看看