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.

  • 相关阅读:
    基于Token的WEB后台认证机制
    导出和导入Docker容器
    进入Docker容器
    介绍Docker容器
    Docker镜像的实现原理
    Docker 移除镜像
    存出和载入Docker镜像
    Docker 创建镜像
    Docker 列出镜像
    Docker如何获取镜像
  • 原文地址:https://www.cnblogs.com/en-heng/p/6907839.html
Copyright © 2011-2022 走看看