機器學習練習之多變量線性迴歸

      在做完上一篇只有一個變量的線性迴歸後,這裏繼續完成多元線性迴歸模型的練習:http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex3/ex3.html。其實模型也是完全一樣的,只不過輸入是多維的特徵而已,這裏的數據是給定了房子大小和房間數相對應的房價,給了這些數據,用線性迴歸模型求出模型參數,然後對新數據作出預測。


%% Exercise 3: Multivariate Linear Regression
% 多變量線性迴歸
%%
%% 載入數據並作預處理
x = load('ex3x.dat');
y = load('ex3y.dat');
m = length(x);
x = [ones(m, 1), x];  %第一列全爲1,加入偏置項
x_unscaled = x; %保存爲歸一化的x,後面方程解要用到
sigma = std(x);  % 如果爲vector,則返回標準差,如果是矩陣,返回每一列即每個維的標準差
mu = mean(x);  % 如果爲vector,返回平均值,如果爲矩陣,返回每一列的平均值
x(:,2) = (x(:,2) - mu(2))./ sigma(2);  % 歸一化:減去平均值再除標準差
x(:,3) = (x(:,3) - mu(3))./ sigma(3);
%%
%% 爲畫圖做準備
figure;
plotstyle = {'b', 'r', 'g', 'k', 'b--', 'r--'}; %不同的學習率用不同的畫線風格
%%
%% 梯度下降
MAX_ITR = 100;
alpha = [0.01, 0.03, 0.1, 0.3, 1, 1.3];
theta_grad_descent = zeros(size(x(1,:)));
n = length(alpha);
for i = 1:n
    theta = zeros(size(x(1,:)))'; % size(x(1,:))返回1*n向量,n爲每個樣本的維數,轉置後爲n*1的0向量
    J = zeros(100, 1);
    for num_iterations = 1:MAX_ITR
        J(num_iterations) = (0.5/m) .* sum((y-x*theta).^2);  % 損失函數
        theta = theta - alpha(i)*(1/m).*x'*(x*theta-y);
    end
    plot(0:49, J(1:50), char(plotstyle(i)), 'LineWidth', 2);
    hold on;
    
    %通過實驗發現alpha爲1時損失最小,這裏記錄下這時的theta
    if alpha(i) == 1
        theta_grad_descent = theta;
    end
end
legend('0.01', '0.03', '0.1', '0.3', '1', '1.3');
xlabel('Number of iterations');
ylabel('Cost L');

%% 預測
theta_grad_descent

% 預測房子面積爲1650,房間數爲3的房價
price_grad_desc = dot(theta_grad_descent, [1, (1650-mu(2))/sigma(2), (3-mu(3))/sigma(3)])

%% Normal equations
theta = inv(x_unscaled'*x_unscaled)*x_unscaled'*y

price_normal = dot(theta, [1, 1650, 3])
%%

實驗結果:


 從上面的結果看出,選擇不同的步長會有不一樣的結果,如果選得不好,算法可能不會收斂,即損失不會減少到某一極小點,可能在某一局部最優解上震盪,這樣的模型對訓練數據都沒找出正確的規律,用來預測新數據也肯定不會好。做實驗時,調參是一個很重要的步驟。還有就是預處理也非常重要,像這裏的數據中,一個是房子面積,數目大而且變化大,而房間數數目小而且變化小,如果不做歸一化等預處理學習到的模型可能會過擬合,做了歸一化處理可能加加快學習速度,學到的模型更穩定,variance更小。

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章