機器學習練習之邏輯斯諦迴歸和牛頓方法

         做完前面的線性迴歸練習後,這裏繼續練習邏輯斯諦迴歸模型http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex4/ex4.html

        給出的數據是40個被大學接收的學生和40個被拒絕的學生的數據,輸入是一個二維向量,表示2門科目成績,輸出是一個分類結果(接收、拒絕),用0和1表示。

        首先,我們要知道logistic regression的假設函數爲:

        

    這個假設函數是估計在參數爲theta下,輸入x被預測爲1的概率。這個函數是sigmoid函數,是神經網絡中的常用的一種激活函數。

     模型的損失函數是:

   

       這個形式是適用於類別y的值爲0、1的,如果是1或-1就要變成另一種形式了。爲什麼要最小化這個函數呢?這個損失函數是怎麼來的呢?它是通過最大化數據出現的概率推出來的,就是MLE(最大似然估計)。當樣本類別爲1時,我們的模型要使數據出現1的可能性最大,當樣本類別爲0時,我們要使它出現0的可能性最大。對於整個樣本集,我們希望它們一起出現的概率最大,假設樣本之間是獨立的,則把每個樣本出現的概率作累積就是樣本集的似然估計。

     

     要最大化L(theta), 即要最大化l(theta),即最小化損失函數J(theta)。

      

     使這個損失函數最小的算法可以用梯度下降法,也可以用牛頓法,梯度下降法要求出J對theta的一階導數,然後逐步更新theta達到局部最優,而牛頓方法要用到一階導和二階導也就是海森矩陣,牛頓法其實是求解函數f(x)=0的x值,對於初始值點x0,求出函數在這點的切線,然後求出切線與x軸的交點作爲新的x值,一直重複這樣的步驟直到到達f(x)=0的點x。

      即

       還記得我們是要最小化損失函數J, 我們就要找到使得J達到局部最優的theta,即極小點,在這一點上,J對theta的導數爲0, 所以我們要求使得J的一階導爲0的theta。這樣,就可以使用牛頓方法來求出這樣的theta,而牛頓方法也要算出一階導來,所以就要對J進行二階求導,也就是海森矩陣

     J對theta的一階導爲:

      

     這個看起來跟之前做過的線性迴歸的求導方程是一樣的!但是是要根據J的表達式一步一步推出來的。


     海森矩陣的方程式如下:

     

      牛頓方法的更新規則:

   

    

     實現如下:

%% Exercise 4: Logistic Regression and Newton's Method
% 邏輯斯蒂迴歸和牛頓方法
% 這裏是採用logistic regression模型和newton算法對數據進行二類分類(0和1)的
% 數據是40個被大學接收的學生和40個被拒絕的學生的兩門成績
% 從中學到分類模型然後給出一名學生的兩門成績,預測被大學接收的概率
%%


%% 初始化數據
x = load('ex4x.dat');
y = load('ex4y.dat');
m = length(x);   %m訓練樣本數
x = [ones(m,1), x];  %加入偏置項1到第一列
n = size(x, 2);  % n爲特徵數,這裏是3
% find找出滿足條件的行號索引
pos = find(y == 1); 
neg = find(y == 0);
% 畫圖顯示
plot(x(pos, 2), x(pos, 3), '+'); hold on
plot(x(neg, 2), x(neg, 3), 'o'); hold on
xlabel('Exam 1 score')
ylabel('Exam 2 score')
%%


%% 定義sigmod 函數
g = inline('1.0 ./ (1.0 + exp(-z))', 'z');
% 用法: 要找出2的sigmod值,調用g(2)
% 如果傳入矩陣或向量,則計算矩陣或向量中每個元素的sigmod
%%


%% 牛頓法
MAX_ITR = 20;   % 最大迭代次數
J = zeros(MAX_ITR, 1); % 保存每次迭代後損失
theta = zeros(n, 1); % 初始化訓練參數


for i = 1:MAX_ITR
    h = g(x*theta);   % 計算假設函數,得到一個列向量,每行爲那個樣本屬於1的概率
    J(i) = (1/m) * sum(-y.*log(h) - (1-y).*log(1-h)); % 計算損失函數
    % 計算梯度和海森矩陣
    grad = (1/m) .* x' * (h - y); %計算J對theta的一階導
    % 自己想到的實現
    H = (1/m) .* x' * (repmat(h .* (1-h), 1, n) .* x);  %計算海森矩陣,即J對theta的二階導
    theta = theta - inv(H)*grad;
    % Solution中的實現
    % H = (1/m).*x'*diag(h)*diag(1-h)*x;
    % theta = theta - H\grad; % 左除跟inv(H)*grad一樣
end
% Display theta
theta
%%
%% prediction
fprintf(['Probability that a student with a escore of exam 1 20 and 80 on exam 2 \n' ...
    'will not be admitted to college is %f\n'], 1 - g([1 20 80]*theta));
%%


%% 畫出牛頓方法結果
% 決策邊界:theta(1)*1+theta(2)*x2 + theta(3)*x3=0
% 兩點確定一點直線,這裏選擇x2維度上的兩點,
plot_x = [min(x(:,2))-2, max(x(:,2))+2];
% 算出對應的x3值
plot_y = (-1./theta(3)).*(theta(2).*plot_x+theta(1));
% 畫直線
plot(plot_x, plot_y)
legend('Admitted', 'Not admitted', 'Decision Boundary')
hold off
%%
%% 畫出J
figure
plot(0:MAX_ITR-1, J, 'o--', 'MarkerFaceColor', 'r', 'MarkerSize', 8)
xlabel('Iteration'); ylabel('J')
J
%%
%% 跟梯度下降法對比
MAX_ITR = 20;   % 最大迭代次數
J = zeros(MAX_ITR, 1); % 保存每次迭代後損失
theta = zeros(n, 1); % 初始化訓練參數
alpha = 0.01;
for i = 1:MAX_ITR
    h = g(x*theta);   % 計算假設函數,得到一個列向量,每行爲那個樣本屬於1的概率
    J(i) = (1/m) * sum(-y.*log(h) - (1-y).*log(1-h)); % 計算損失函數
    % 計算梯度
    grad = (1/m) .* x' * (h - y); %計算J對theta的一階導
    theta = theta - alpha*grad;
end
% Display theta
theta
hold on
plot(0:MAX_ITR-1, J, '*--', 'MarkerFaceColor', 'r', 'MarkerSize', 8)
legend('newton', 'gradient descent')



結果:


      

   從圖中梯度下降與牛頓法的比較可以看出,梯度下降要經過至少10次才靠近局部最優,而牛頓法不到5次就收斂了,而且梯度下降法如果步長選得不好可能不會收斂,但是牛頓法的計算代價比較大,要算出海森矩陣的逆來,不過有一些優化方法比如擬牛頓法,這些以後再慢慢研究。


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