机器学习练习之逻辑斯谛回归和牛顿方法

         做完前面的线性回归练习后,这里继续练习逻辑斯谛回归模型http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex4/ex4.html。

        给出的数据是40个被大学接收的学生和40个被拒绝的学生的数据,输入是一个二维向量,表示2门科目成绩,输出是一个分类结果(接收、拒绝),用0和1表示。

        首先,我们要知道logistic regression的假设函数为:

        机器学习练习之逻辑斯谛回归和牛顿方法_第1张图片

    这个假设函数是估计在参数为theta下,输入x被预测为1的概率。这个函数是sigmoid函数,是神经网络中的常用的一种激活函数。

     模型的损失函数是:

   

       这个形式是适用于类别y的值为0、1的,如果是1或-1就要变成另一种形式了。为什么要最小化这个函数呢?这个损失函数是怎么来的呢?它是通过最大化数据出现的概率推出来的,就是MLE(最大似然估计)。当样本类别为1时,我们的模型要使数据出现1的可能性最大,当样本类别为0时,我们要使它出现0的可能性最大。对于整个样本集,我们希望它们一起出现的概率最大,假设样本之间是独立的,则把每个样本出现的概率作累积就是样本集的似然估计。

     机器学习练习之逻辑斯谛回归和牛顿方法_第2张图片

     要最大化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')



结果:

机器学习练习之逻辑斯谛回归和牛顿方法_第3张图片

      

   从图中梯度下降与牛顿法的比较可以看出,梯度下降要经过至少10次才靠近局部最优,而牛顿法不到5次就收敛了,而且梯度下降法如果步长选得不好可能不会收敛,但是牛顿法的计算代价比较大,要算出海森矩阵的逆来,不过有一些优化方法比如拟牛顿法,这些以后再慢慢研究。


你可能感兴趣的:(机器学习练习之逻辑斯谛回归和牛顿方法)