scitkit-learn.ensemble.gradientBoostingRegressor的根平均日志平方错误问题



我正在进行Kaggle竞赛(此处的数据),并且使用Scikit-Learn的渐变bloostingRegressor遇到了麻烦。竞争正在使用均值对数平方误差(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,我从print语句中获得了nan。查看三个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)),则返回就可以了。

我敢肯定,我缺少有关梯度提升的简单的东西;为什么这种评分方法不适合梯度提升回归器?

我建议您向矢量化

def rmsle(y, y0):
    return np.sqrt(np.mean(np.square(np.log1p(y) - np.log1p(y0))))

基准可以在此处找到

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

首先,make_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

其次,您的回归器在第1行的庇护所时给出了错误的价值。在第一个跨验证套件中的399937。希望这可以帮助 !最好的是您的比赛。

相关内容

  • 没有找到相关文章

最新更新