scitkit-learn.ensemble.GradientBoostingRegressor的均方根平方误差问题

Mar*_*ite 2 python machine-learning scikit-learn

我正在进行Kaggle竞赛(数据在这里),但是在使用scikit-learn的GradientBoostingRegressor时遇到了麻烦。竞争是使用均方根均方根误差(RMLSE)来评估预测。


为了进行MWE,以下是我train.csv在上面的链接中用于清理的代码:

import datetime
import pandas as pd

train = pd.read_csv("train.csv", index_col=0)

train.pickup_datetime = pd.to_datetime(train.pickup_datetime)
train["pickup_month"] = train.pickup_datetime.apply(lambda x: x.month)
train["pickup_day"] = train.pickup_datetime.apply(lambda x: x.day)
train["pickup_hour"] = train.pickup_datetime.apply(lambda x: x.hour)
train["pickup_minute"] = train.pickup_datetime.apply(lambda x: x.minute)
train["pickup_weekday"] = train.pickup_datetime.apply(lambda x: x.weekday())
train = train.drop(["pickup_datetime", "dropoff_datetime"], axis=1)
train["store_and_fwd_flag"] = pd.get_dummies(train.store_and_fwd_flag, drop_first=True)

X_train = train.drop("trip_duration", axis=1)
y_train = train.trip_duration
Run Code Online (Sandbox Code Playgroud)

为了说明一些作品,如果我使用一个随机森林,那么RMSLE计算就好了:

import numpy as np
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import make_scorer
from sklearn.model_selection import cross_val_score


def rmsle(predicted, real):
    sum=0.0
    for x in range(len(predicted)):
        p = np.log(predicted[x]+1)
        r = np.log(real[x]+1)
        sum = sum + (p - r)**2
    return (sum/len(predicted))**0.5

rmsle_score = make_scorer(rmsle, greater_is_better=False)

rf = RandomForestRegressor(random_state=1839, n_jobs=-1, verbose=2)
rf_scores = cross_val_score(rf, X_train, y_train, cv=3, scoring=rmsle_score)
print(np.mean(rf_scores))
Run Code Online (Sandbox Code Playgroud)

这样就好了。但是,梯度提升回归器throw RuntimeWarning: invalid value encountered in log,我nanprint语句中得到a 。查看三个RMSLE分数的数组,它们都是nan

gb = GradientBoostingRegressor(verbose=2)
gbr_scores = cross_val_score(gb, X_train, y_train, cv=3, scoring=rmsle_score)
print(np.mean(gbr_scores))
Run Code Online (Sandbox Code Playgroud)

我认为这是因为在某个我不应该去的地方得到了负值。Kaggle告诉我,当我将预测上传到那里以查看是否与我的代码有关时,它也遇到零或非负RMSLE。为什么不能使用梯度增强来解决此问题?如果将我mean_squared_error用作计分器(mse_score = make_scorer(mean_squared_error, greater_is_better=False)),则返回的结果很好。

我确定我缺少关于梯度增强的简单知识;为什么这种评分方法不适用于梯度增强回归器?

LYu*_*LYu 7

我建议您将其向量化

def rmsle(y, y0):
    return np.sqrt(np.mean(np.square(np.log1p(y) - np.log1p(y0))))
Run Code Online (Sandbox Code Playgroud)

基准可以在这里找到

https://www.kaggle.com/jpopham91/rmlse-vectorized