이전에 새터를 자동으로 구해주는 Gradient Descent 기법을 설명하였습니다.

하지만 적정한 알파(σ) 값을 지정해 주어야 하고

iteration 크기도 정해 주어야 값이 구해집니다.

(이말은 적정한 알파와 이터레이션 크기를 안해주면 잘 나오지 않는다는 의미도 됩니다.)


그리하여 알파와 이터레이션을 정해주지 않아도 자동으로 새터를 구해주는 Normal equation 기법에 대해 알아 봅시다.




새터를 구하는 공식은 위와 같습니다.


함수로 구현하면 


function theta = normalEquation(x, y)

theta = pinv(x' * x) * x' * y;

end


이럴경우 최소 오차가 GD와 얼마나 차이가 있을지를 확인해 보겠습니다.


다항일 경우

>> data = load('ex1data2.txt');

>> n = size(data, 2);

>> x = data(:, 1:n-1);

>> y = data(:, n);

>> m = length(x);

>> [x, mu, sigma] = meanNormalization(x);

>> x = [ones(m, 1), x]; % add x0 1

>> theta = normalEquation(x, y)

ans =


  3.4041e+005

  1.1063e+005

  -6.6495e+003


cost function을 구해보면

>> computeCostMulti(x, y, theta)

ans =   2.0433e+009


이며 이전에 구한 값 

theta =


  3.4041e+005

  1.1063e+005

  -6.6493e+003


코스트 펑션은

ans =   2.0433e+009


와 비슷합니다.


단항일 경우 어떨지 다시 비교해보면


>> data = load('ex1data1.txt');

>> y = data(:, 2);

>> m = length(y);

>> x = [ones(m, 1), data(:,1)];

>> theta = zeros(2, 1);

>> theta = normalEquation(x, y)

theta =


  -3.8958

   1.1930


>>computeCost(x, y, theta)

ans =  4.4770


이전에 구한 값은

theta =


  -3.6303

   1.1664


ans =  4.4834


와 같이 비슷합니다.


NE 기법이 GD와 결과도 비슷하고 계산도 빠르다는 것을 볼 수 있습니다.


각각의 장단점은 아래 그림과 같습니다.





GD나 NE를 적절히 사용하라고 하네요.

이전에 Gradient Descent라는 기법을 이용하여 단항에서 자동으로 새터를 구해 주었습니다.

이번에는 다항일 때의 Gradient Descent 기법을 알아 보겠습니다.



다항일 때는 별로 달라지는게 없고 x0이 원래 존재 했었지만 1이여서 생략 했던 것이고

이전에 구한 multiple variable cost function에 h를 구한 식을 가져다가 

n(number of features) 만큼 iteration을 돌리면 됩니다.





식을 그림과 같으며 코드를 구현해 보면

* Gradient Descent Multi

function [theta, J_history] = gradientDescentMulti(x, y, theta, alpha, iterations)


m = length(y); % number of rows

n = size(x, 2); % number of features

    


    h = zeros(n, 1);

    J_history = zeros(iterations, 1);

    for i=1:iterations


    % sum of all hypotesis * x

    for j=1:n

H = (theta' * x')';

h(j) = sum((H - y)' * x(:, j));


    end


    % update theta

    for j=1:n

    theta(j) = theta(j) - alpha * (h(j) / m);

    end


    % add history

    J_history(i) = computeCostMulti(x, y, theta);

 

    end


end


다항 코스트 펑션 구하는 코드 + 단항 GD 코드로 구해지는 것을 알 수 있습니다.


>> data = load('ex1data2.txt');

>> n = size(data, 2);

>> x = data(:, 1:n-1);

>> y = data(:, n);

>> m = length(x);

>> [x, mu, sigma] = meanNormalization(x);

>> x = [ones(m, 1), x]; % add x0 1

>> theta = zeros(n, 1)

>> alpha = 0.01;

>> iterations = 1500;

>> theta = gradientDescentMulti(x, y, theta, alpha, iterations)


theta =


  3.4041e+005

  1.1063e+005

  -6.6493e+003


새터가 새로 변경된 것을 볼 수 있습니다.


그럼 코스트 펑션을 다시 구해보면


>> computeCostMulti(x, y, theta)

ans =   2.0433e+009


위와 같이 코스트 펑션이 나옵니다.

이 값이 reasonable 한지는 차차 알아보도록 하겠습니다.

'ML > octave구현 - w1' 카테고리의 다른 글

[octave] Stochastic Gradient descent  (0) 2016.03.22
[octave] Normal equation  (0) 2016.03.13
[octave] feature mean normalization  (0) 2016.03.10
[octave] multiple variable cost function  (0) 2016.03.10
[octave] 임의 값 예측  (0) 2016.03.07

다항일경우 각 feature에 대한 스케일 조정이 필요합니다.

예를들어 size는 4자리의 수를 표현되고 방의개수는 1자리로 표현됩니다.

이렇게 스케일이 안맞을 경우 Gradient Descent에서 찾는데 많이 걸리기 때문에 스케일을 먼저 조정해 줄 필요가 있습니다.





* 그림 설명 - 왼쪽그림은 스케일 조정이 되지 않아 GD가 오래 걸리니 오른쪽 그림처럼 스케일을 조정해야 속도가 빠릅니다.





* 그림 설명 - Mean normalization이라는 기법을 이용하여 x의 범위를 조정해주는 기법



그럼 Mean normalization을 이용하여 x의 변화에 대해 알아보도록 합시다.


새로운 데이터 셋(ex1data2.txt) 파일이다. 

x1, x2, y 순으로 값이 되어 있으며 x1은 size, x2는 방의개수, y는 가격입니다.

2104,3,399900

1600,3,329900

2400,3,369000

1416,2,232000

3000,4,539900


먼저 현재 데이터를 스케일 조정 없이 데이터를 그려보도록 합니다.


>> data = load('ex1data2.txt');

>> n = size(data, 2);

>> x = data(:, 1:n-1);

>> y = data(:, n);

>> plot(x(:, 1), y, 'rx')
>> hold on
>> plot(x(:, 2), y, 'bx')


보는것과 같이 값의 스케일이 너무 안맞아서 파란색 데이터가 안보이는 것을 볼 수 있습니다.

그럼 이를 해결 할 앞서 설명한 mean normalization에 대해 구현해보면

mean normalization 구현
function [x_normal, mu, sigma] = meanNormalization(x)

m = length(x); % number of rows
n = size(x, 2); % number of features

% init return data
x_normal = x;
mu = zeros(n, 1);
sigma = zeros(n, 1);
% calc mu(mean) and sigma(standard deviation)
for i=1:n
mu(i) = mean(x(:, i));
sigma(i) = std(x(:, i));
end

% calc data
for(i=1:n)
for(j=1:m)
x_normal(j, i) = (x(j, i) - mu(i)) / sigma(i);
end
end
end

뮤에 평균, 시그마에 표준변차를 구하고 그 값을 이용하여
기존 데이터를 평탄화 해주었습니다.

그 결과를 다시 x에 대입하여 그래프를 그려보면

>> [x, mu, sigma] = meanNormalization(x);
>> mu
mu =

   2000.6809
      3.1702

>> sigma
sigma =

   794.70235
     0.76098

>> x
x =

  1.3001e-001  -2.2368e-001
  -5.0419e-001  -2.2368e-001
  5.0248e-001  -2.2368e-001

...


>> plot(x(:, 1), y, 'rx')

>> hold on

>> plot(x(:, 2), y, 'bx')



그래프와 같이 0을 중심으로 데이타가 모여 있는 것을 확인 할 수 있습니다.


이후에 앞에서 설명한 cost function 을 구해보면



>> m = length(x);
>> x = [ones(m, 1), x]; % add x0 1
>> theta = zeros(n, 1)
>> computeCostMulti(x, y, theta)
ans =   6.5592e+010

feature를 변경해도 값이 그대로 인 것을 볼 수 있습니다.


'ML > octave구현 - w1' 카테고리의 다른 글

[octave] Normal equation  (0) 2016.03.13
[octave] Multiple Variable Gradient Descent  (0) 2016.03.11
[octave] multiple variable cost function  (0) 2016.03.10
[octave] 임의 값 예측  (0) 2016.03.07
[octave] GradientDescent  (0) 2016.03.07

+ Recent posts