我正在进行一个Kaggle竞赛(data here),我在使用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

为了说明一些有用的东西,如果我使用一个随机林,那么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))

一切都很顺利。但是,梯度递增回归函数抛出RuntimeWarning: invalid value encountered in log,我从nan语句中得到print。从三个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))

我想这是因为我在某个不该去的地方得到了负值。Kaggle告诉我,当我把我的预测上传到那里,看它是否与我的代码有关时,它也遇到了零或非负的RMSLE。有什么原因不能用梯度增强来解决这个问题吗?如果我使用mean_squared_error作为记分器(mse_score = make_scorer(mean_squared_error, greater_is_better=False)),它返回的结果就很好。
我肯定我遗漏了一些关于梯度增强的简单内容;为什么这种评分方法不适用于梯度增强回归器?

最佳答案

首先,scorer使用的语法如下:

def metric(real,predictions)

不是
def metric(predictions,real)

因此,您需要在代码中打印real值,以获得回归器的实际predicted值。
只需按以下方式更改函数,它就应该正常工作:
def rmsle(real, predicted):
    sum=0.0
    for x in range(len(predicted)):
        if predicted[x]<0 or real[x]<0: #check for negative values
            continue
        p = np.log(predicted[x]+1)
        r = np.log(real[x]+1)
        sum = sum + (p - r)**2
    return (sum/len(predicted))**0.5

其次,您的回归函数在第一个交叉验证集的第399937行的predcition处给出了错误的值。希望这有帮助!为您的竞争对手尽最大努力。

关于python - scitkit-learn.ensemble.GradientBoostingRegressor的均方根均方根误差问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46202223/

10-15 10:29