0

这是我的代码:

    function testRegression()
    load carsmall
    x1 = Weight;
    x2 = Horsepower;    % Contains NaN data
    y = MPG;
    X = [ones(size(x1)) x1 x2 x1.*x2];
    X(isnan(X)) = 0;
    y(isnan(y)) = 0;

    for i = 2:size(X,2)
        X(:,i) = (X(:,i) - min(X(:,i))) / (max(X(:,i)) - min(X(:,i)));
    end
    y = (y - min(y)) / (max(y) - min(y));

    model = train(y,sparse(X),'s 0');
    [a,b,c] = predict(y, sparse(X), model);
    end

我总是得到 0 的预测。我的代码有什么问题?当我不规范化 y 时,我得到了一些输出,但是当我规范化输出时,输出始终为 0。

4

2 回答 2

1

以下是我在您的代码中看到的一些问题:

1)通过这样做:

X(isnan(X)) = 0;
y(isnan(y)) = 0;

您实际上是在向您的模型引入偏见(给定数据中不存在的主观信息)。简而言之,NaN 不等于 0(0 是一个数字)。我宁愿删除包含至少一个 NaN 值的 X 行。当然,y 中的相应行也需要删除。

2)如果您正在构建 SVR 模型而不是线性模型,而不是:

X = [ones(size(x1)) x1 x2 x1.*x2];

你可以使用

X = [x1 x2];

在 SVR 模型中设计包含一个常数项,并且标准内核(例如 rbf、多项式)很好地捕获了诸如 x1*x2 之类的交互。

3)在实践中没有使用你所做的方式缩放 Y。据我所知,输出缩放可能有帮助的唯一情况是它的可能值跨越不同的数量级,例如 y 在 [0.1, 10^5] 范围内。在这种情况下,您通常使用 log(y) 代替。

4) 我还要注意你在 X 中所做的缩放。这种缩放倾向于“平滑”X 中的任何小的可变性,以增加 (max(X(:,i)) - min(X(: ,一世)))。

结束语:在我看来,此类问题的最酷之处在于,您可以自己凭经验评估任何主张(如我在上面提出的主张)。一种方法是拆分数据并使用一部分进行训练。然后你使用其余的进行验证。进行多次分割以获得更好的画面。上面提出的改进应该反映模型在验证集上的错误。训练集上的错误信息量不大,因为您可能刚刚过度拟合了数据。

于 2018-02-08T01:49:38.470 回答
1

不应该标准化输出值。归一化的重点是仅针对输入特征进行。这会减小输入特征的动态范围,从而使模型更容易训练。输出值需要保持不变,因为这些是您尝试预测的真实值。通过对输出值进行归一化,您可以有效地缩小预期输出的动态范围,这意味着输入特征中的小差异很大程度上会影响输出。

tl;dr:您永远不会标准化预期的输出值。

于 2018-02-06T22:41:42.613 回答