python - decision_tree_regressor 模型的负 cross_val_score

标签 python pandas machine-learning scikit-learn

我正在使用 cross_val_score 方法评估 desicion_tree_regressor 预测模型。问题是,分数似乎是负数,我真的不明白为什么。

这是我的代码:

all_depths = []
all_mean_scores = []
for max_depth in range(1, 11):
    all_depths.append(max_depth)
    simple_tree = DecisionTreeRegressor(max_depth=max_depth)
    cv = KFold(n_splits=2, shuffle=True, random_state=13)
    scores = cross_val_score(simple_tree, df.loc[:,'system':'gwno'], df['gdp_growth'], cv=cv)
    mean_score = np.mean(scores)
    all_mean_scores.append(np.mean(scores))
    print("max_depth = ", max_depth, scores, mean_score, sem(scores))

结果:

max_depth =  1 [-0.45596988 -0.10215719] -0.2790635315340 0.176906344162 
max_depth =  2 [-0.5532268 -0.0186984] -0.285962600541 0.267264196259 
max_depth =  3 [-0.50359311  0.31992411] -0.0918345038141 0.411758610421 max_depth =  4 [-0.57305355  0.21154193] -0.180755811466 0.392297741456 max_depth =  5 [-0.58994928  0.21180425] -0.189072515181 0.400876761509 max_depth =  6 [-0.71730634  0.22139877] -0.247953784441 0.469352551213 max_depth =  7 [-0.60118621  0.22139877] -0.189893720551 0.411292487323 max_depth =  8 [-0.69635044  0.13976584] -0.278292298411 0.418058142228 max_depth =  9 [-0.78917478  0.30970763] -0.239733577455 0.549441204178 max_depth =  10 [-0.76098227  0.34512503] -0.207928623044 0.553053649792

我的问题如下:

1) 分数返回 MSE 对吗?如果是,怎么会是负数?

2) 我有约 40 个观察值和约 70 个变量的小样本。这可能是问题所在吗?

提前致谢。

最佳答案

长话短说:

1) 不,除非您明确指定,否则它是估算器的默认 .score 方法。由于您没有,它默认为 DecisionTreeRegressor.score 返回确定系数,即 R^2。这可能是负面的。

2) 是的,这是一个问题。并且它解释了为什么您会得到一个负的决定系数。

详情:

你使用过这样的函数:

scores = cross_val_score(simple_tree, df.loc[:,'system':'gwno'], df['gdp_growth'], cv=cv)

所以您没有明确传递“评分”参数。让我们看看docs :

scoring : string, callable or None, optional, default: None

A string (see model evaluation documentation) or a scorer callable object / function with signature scorer(estimator, X, y).

所以它没有明确说明这一点,但这可能意味着它使用估算器的默认 .score 方法。

为了证实这个假设,让我们深入研究 source code .我们看到最终使用的scorer是这样的:

scorer = check_scoring(estimator, scoring=scoring)

那么,让我们看看 source for check_scoring

has_scoring = scoring is not None
if not hasattr(estimator, 'fit'):
    raise TypeError("estimator should be an estimator implementing "
                    "'fit' method, %r was passed" % estimator)
if isinstance(scoring, six.string_types):
    return get_scorer(scoring)
elif has_scoring:
    # Heuristic to ensure user has not passed a metric
    module = getattr(scoring, '__module__', None)
    if hasattr(module, 'startswith') and \
       module.startswith('sklearn.metrics.') and \
       not module.startswith('sklearn.metrics.scorer') and \
       not module.startswith('sklearn.metrics.tests.'):
        raise ValueError('scoring value %r looks like it is a metric '
                         'function rather than a scorer. A scorer should '
                         'require an estimator as its first parameter. '
                         'Please use `make_scorer` to convert a metric '
                         'to a scorer.' % scoring)
    return get_scorer(scoring)
elif hasattr(estimator, 'score'):
    return _passthrough_scorer
elif allow_none:
    return None
else:
    raise TypeError(
        "If no scoring is specified, the estimator passed should "
        "have a 'score' method. The estimator %r does not." % estimator)

请注意,scoring=None 已被执行,因此:

has_scoring = scoring is not None

暗示 has_scoring == False。此外,估算器有一个 .score 属性,所以我们通过这个分支:

elif hasattr(estimator, 'score'):
    return _passthrough_scorer

这很简单:

def _passthrough_scorer(estimator, *args, **kwargs):
    """Function that wraps estimator.score"""
    return estimator.score(*args, **kwargs)

最后,我们现在知道 scorer 是您的估算器的默认 score。让我们检查一下 docs for the estimator ,其中明确指出:

Returns the coefficient of determination R^2 of the prediction.

The coefficient R^2 is defined as (1 - u/v), where u is the regression sum of squares ((y_true - y_pred) ** 2).sum() and v is the residual sum of squares ((y_true - y_true.mean()) ** 2).sum(). Best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a R^2 score of 0.0.

所以看起来你的分数实际上是决定系数。因此,基本上,如果 R^2 为负值,则意味着您的模型非常表现不佳。比我们只预测每个输入的期望值(即平均值)更糟糕。这是有道理的,因为正如您所说:

I have a small sample of ~40 observations and ~70 variables. Might this be the problem?

一个问题。当您只有 40 个观测值时,几乎不可能对 70 维问题空间做出有意义的预测。

关于python - decision_tree_regressor 模型的负 cross_val_score,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45021452/

相关文章:

python - 在 macOS 上安装 rpy2——R_HOME 变量的问题

python - 寻找相似的词

python - Pandas :按多列中的值过滤

python - 如何删除两列中具有重复值对的行?

c# - MLAgents Agent 的训练并没有进步

带 dropout 的 Tensorflow 前向传递

python - 在 Django 模板中调用 Python 函数

python - 如何更快地用python计算指数移动平均线?

Python pandas插值系列

machine-learning - Keras:为什么观察到的批量大小与指定的批量大小不匹配?