2014-05-11 2 views
0

회귀가 옥타브에서 구현 됨으로써 어떻게 작동 하는지를 알고 싶었습니다. 제 함수가 올바른지 확인하기 위해 그 결과를 내장 함수 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) 작은 학위를 작동하지만 더 큰도 것이 너무 작은 계수를 producecs : 여기 내 코드입니다. orginal 한 기능이 근사치의 플롯 : - 블루, 내 - 빨강, polyfit - orginal 한

녹색 나는이 부분 (pinv(mx' * mx) * mx' * my)'에서 뭔가 잘못 될 수 있다고 생각한다. 또한, 내가 pinv에서 inv으로 바뀌면 나는 다른 결과를 얻는다.

몇 가지 조사를 수행하고 다른 솔루션 (예 : )을 찾았지만 이러한 프로그램이 유사하더라도 버그를 찾을 수 없습니다.

누군가 나에게 무엇이 잘못되었는지 설명해 주시겠습니까?

답변

1

큰 D (근사 다항식의 차수)에 대해 행렬의 상태가 좋지 않게됩니다. 당신은 회귀를하기 위해 다른 종류의 다항식 기반을 사용할 수 있습니다. 예 : x, x^2, x^3, ..., x^D 대신에 Chebyshev 다항식을 사용했습니다.

데이터를 가운데 맞추고 크기를 조정하면 약간 더 나은 결과를 얻을 수 있습니다. 한 세트 (X, Y)에 기능에 맞게하려고 기본적으로, 당신은 사용하여 문제를 다시 정의 할 수 있습니다 :

XN = (X - 평균 (X))/표준을 (X)이 적합 이후

(xn, y)에 대한 세트.

+0

역행렬을 사용하지 않고 해결할 수 있습니까? 방정식 시스템을 풀기 위해 다른 방법을 사용한다면 말입니다. – GSPdibbler

+0

아닙니다. 당신은 이미 "pinv"와 함께 inverse의 사용을 피합니다. – mmisu