八度音阶的多项式回归 - 系数太小

时间:2014-05-11 19:36:31

标签: octave numerical-methods

我想通过以八度音程实现它来理解回归是如何工作的。要检查我的函数是否正确,我将其结果与内置函数polyfit进行比较。这是我的代码:

    p = [0, 1.5 * pi];

    function y = f(x)
        y = (exp(-4 * sin(4*x)));
    end

    function c = regress1(x, y, degree)
        L = @(j)(arrayfun( @(k)(j^k), (0:degree)));

        x_data = [];
        for i = x
            x_data = [x_data; L(i)];
        end

        mx = x_data;
        my = y';

        c = fliplr((pinv(mx' * mx) * mx' * my)');
    end

    % number of known points
    N = 50;
    % polynomial degree
    D = 20;

    % known points
    X = linspace(p(1), p(2), N);
    Y = arrayfun(@f, X);

    % my function
    R = regress1(X, Y, D);
    % reference function
    C = polyfit(X, Y, D);

    % test points
    W = linspace(p(1), p(2), 1000);
    V1 = arrayfun(@(x)(polyval(R,x)), W);
    Z = arrayfun(@(x)(polyval(C,x)), W);


    clf;
    hold on;
    fplot(@f, p);
    plot(X, Y, '*');
    plot(W, V1, '1-');
    plot(W, Z, '2-');
    hold off;

问题是它适用于小程度(我的程序中的变量D),但是对于更大的程度,它产生的系数太小。原始函数的图和两个近似值: 原始 - 蓝色,我 - 红色,polyfit - 绿色

我怀疑这部分(pinv(mx' * mx) * mx' * my)'中的某些内容可能有误。此外,如果我从pinv更改为inv,我会得到不同的结果,但更糟。

我做了一些研究,找到了其他一些解决方案,例如,但即使这些程序相似,我也找不到我的错误。

有人可以解释我有什么问题吗?

1 个答案:

答案 0 :(得分:1)

对于大D(近似多项式的次数),矩阵会变得病态。您可以尝试使用不同类型的多项式基数来进行回归。对于例如使用Chebyshev多项式代替x,x ^ 2,x ^ 3,...,x ^ D.

如果您居中并扩展数据,则可以获得稍微好一点的结果。基本上,如果您尝试将函数拟合到集合(x,y),则可以使用以下命令重新定义问题:

xn =(x - mean(x))/ std(x)

之后

将设置放在(xn,y)上。