使用liblinear和Matlab进行回归

时间:2018-02-06 17:32:23

标签: matlab regression libsvm liblinear

这是我的代码:

    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。

2 个答案:

答案 0 :(得分:1)

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

tl;dr:您从未规范化预期的输出值。

答案 1 :(得分: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(:,i))的)。

结束说明: 在我看来,这些问题很酷,你可以凭经验评估任何索赔(比如我上面提到的索赔)。一种方法是分割数据并使用零件进行培训。然后使用其余的进行验证。做多个分割以获得更好的图像。上述建议之类的改进应反映您的模型在验证集上的错误。训练集上的错误信息量不大,因为您可能刚刚过度拟合了数据。