機器學習練習之線性迴歸

       還是要打牢基礎吧,再做做機器學習最基本的方法和技術。這個練習是線性迴歸,來自Andrew Ng的 機器學習課程http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex2/ex2.html

    線性迴歸是有監督的學習方法,給定一些訓練數據,我們要找到數據中存在的規律,線性迴歸就是假定存在一條直線能夠擬合訓練數據,這樣再給新的數據時,就可以用訓練好的迴歸模型來對新數據作出預測。線性迴歸實質上式對輸入樣本的特徵進行線性組合的結果,就是對輸入的線性表達。

假設給定訓練數據,訓練數據輸入用X表示,輸出用Y表示。

        用平方損失函數計算迴歸模型與真實值的誤差:

    

     模型h就是線性模型,參數爲theta。要求出最優的theta能使損失最小,就是使預測值儘量接近真實值。可以採用梯度下降算法來找出這樣的theta。對於這個最小二乘問題,它也存在方程解的,方程解爲

    這裏採用batch梯度下降,每一次迭代都要掃描整個樣本集,計算總代價對於theta的偏導即梯度,然後更新梯度,循環到預先設定的最大迭代次數或者誤差小於一定範圍就停止算法。關鍵要理解的是怎麼算梯度,梯度的更新計算公式如下:


    上面的公式是矩陣向量的表達方式,也可以根據一個個樣本來求解出梯度,但是用matlab實現時用這樣的計算方式效率比對一個個樣本算出梯度然後累加起來要快得多。

這個練習是預測男生身高與年齡的關係,輸入x是年齡,輸出是身高,要找到一個線性模型,儘量擬合訓練數據,然後對於新數據作出預測。

程序如下:

%% Exercise: Linear regression 
% From http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex2/ex2.html
% 數據是不同男生的身高和體重,用線性迴歸模型對數據進行擬合
% 用到的算法是梯度下降
%%
x = load('ex2x.dat'); % x是男生年齡,是一個列向量
y = load('ex2y.dat'); % y是男生身高,也是一個列向量

figure % 打開新的繪畫窗口
plot(x, y, 'o');
ylabel('Height in meters');
xlabel('Age in years');

m = length(y);  % m存儲樣本數目
x = [ones(m, 1), x]; % 給x添加第一列全爲1,這樣x的每一行有2個數,表示每個男生的特徵,第二列纔是男生年齡

theta = zeros(2, 1); % theta爲權重參數,一個2維列向量,初始化爲0
alpha = 0.07; %步長
MAX_ITR = 1500; %最多迭代次數
ERROR = 1e-10;
%Jtheta = 0; % 代價函數

%% 直接用最小二乘方法求解
%theta = inv(x'*x)*x'*y
%%

%% Batch gradient decent
for i=1:MAX_ITR
    % Jtheta = 0.5/m*sum(x*theta-y).^2); 計算代價
    grad = 1/m*x'*(x*theta-y); %計算梯度
    prev_theta = theta;
    theta = theta - alpha*grad;
    if abs(prev_theta-theta)<ERROR
        break
    end
    fprintf('%d\n',i);
end
theta  
[1 3.5]*theta
[1 7]*theta

hold on % Plot new data without clearing old plot
plot(x(:,2), x*theta, '-'); % remember that x is now a matrix with 2 columns
                            % and the second column contains the time info
legend('Training data', 'Linear regression');
%%
%% Understand J(theta)
% 爲了更好理解batch梯度下降所做的事情,這裏畫出J(theta)也就是損失與theta之間的關係
J_vals = zeros(100, 100); % initialize Jvals to 100x100 matrix of 0's
theta0_vals = linspace(-3, 3, 100); %從-3到3,中間均勻採集100個點
theta1_vals = linspace(-1, 1, 100);
for i = 1:length(theta0_vals)
    for j = 1:length(theta1_vals)
        t = [theta0_vals(i); theta1_vals(j)];
        J_vals(i,j) = 0.5/m*sum((x*t-y).^2);
    end
end

% Plot the surface plot
% Because of the way meshgrids work in the surf command, we need to
% transpose J_vals before calling surf, or else the axes will be flipped
J_vals = J_vals';
figure;
surf(theta0_vals, theta1_vals, J_vals);
xlabel('\theta_0'); ylabel('\theta_1');

figure;
% Plot the cost function with 15 contours spaced logarithmically
% between 0.01 and 100
contour(theta0_vals, theta1_vals, J_vals, logspace(-2,2,15))
xlabel('\theta_0'); ylabel('\theta_1');

 
實驗結果如下:






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