一、为什么要用逻辑回归
下面的图1可以看出使用线性的回归函数还是勉强可以分开的,以y值为0.5分界。直线的左边表示No,右边表示Yes。但是数据量一旦加多,例如图2,线性的回归函数就不适用了。
二、逻辑回归各种函数的描述
1、假设函数
针对逻辑回归问题,使用下面的回归函数,也叫sigmoid( )函数,对数(逻辑)回归是用来实现分类任务的。它的范围在[0,1]区间内,函数值的意义就是针对二分类问题预测属于某一类的概率。
这里拿预测是否是恶性肿瘤举例子,先商定当函数值为1的时候,则预测患的是恶性肿瘤,当函数值为0的时候,预测是良性肿瘤。当z大于0的时候,说明g(z)大于0.5,说明患有恶性肿瘤概率比较大,就预测是恶性的;而当z小于0的时候,g(z)不足0.5,说明良性肿瘤可能性比较大,就预测是良性的。
sigmoid函数表达式如下图:
此函数的图像如下:
用该函数和之前线性回归的假设函数组合为逻辑回归的假设函数如下:
hθ(X) = g(Xxθ) //g(z)就是上面说的回归函数
2、决策边界
根据回归函数的意义和逻辑回归的假设函数,很容易发现Xxθ
是否大于0对预测结果起着决定性的作用。当Xxθ>0的时候,往往就预测是恶性肿瘤;当Xxθ<0时就会预测是良性。
很好理解,就是h(x)=0.5即是分类的边界线,左右代表不同的预测结果。
训练对数回归的方法跟线性回归一样,同样是定义一个代价函数(损失函数),并且通过梯度下降算法或者更高级BFGS、L-BFGS等算法最小化我们的代价函数。后面给出的代码时手搓梯度下降来实现的。不过,MATLAB里提供了一个最小化函数fminunc(),你可以直接使用它来实现梯度下降。通过梯度下降,我们使得代价函数最小,训练得到参数theta,然后带入机器学习模型中。
2、损失函数
上面公式有两个参数,第一个参数h代表预测结果,第二个参数y则是真正的结果。
拿预测肿瘤是良性还是恶性举例验证分段的损失函数公式的正确性:
① 前提:y=1的时候即病人真的得癌症了。我们预测患恶性肿瘤的概率为1即h(x)(假设函数)=1,横坐标接近1的时候,预测完全正确,loss几乎为零;而当我们预测患恶性肿瘤的概率为0即h(x)(假设函数)=0,横坐标接近0的时候,预测完全错误,loss为无限大。第一段函数如下图:
② 前提:y=0的时候即病人只是患良性肿瘤。我们预测患恶性肿瘤的概率为0即h(x)(假设函数)=0,横坐标接近0的时候,预测完全正确,loss几乎为零;而当我们预测患恶性肿瘤的概率为1即h(x)(假设函数)=1,横坐标接近1的时候。预测完全错误,loss为无限大。第二段函数如下图:
通过对数极大似然法,将之前的分段函数合并成一个函数之后,可得逻辑回归的真正代价函数定义如下:
3、梯度下降
这张图片明显少了1/m这个系数。。。
梯度下降求出来的最后结果和线性回归的梯度下降所求的偏导数一模一样,太巧合了,不过主体回归函数却是大相径庭。这个导数真的有点考研数学题的样子,不太好搞。。。。。。。
三、代码实现
loss函数的m文件:
function [J, grad] = costFunctionJ_classification( x,y,theta )
m=length(x(:,1));
temp_square_matrix=[y 1-y]*[(log(sigmoid(x*theta)))';(log(1-sigmoid(x*theta)))'];
%J=-1/m*sum(diag(temp_square_matrix)) %取出方阵的对角线求和
grad =(sigmoid(x*theta)-y)'*x;
J=1/m*sum(-y.*(log(sigmoid(x*theta))-(1-y).*log(1-sigmoid(x*theta))));
end
感觉两个J的实现都没毛病,但是值不一样,这里没搞懂。第一个J其实是两个向量相乘变成一个方阵,再取它的对角线上的和。第二个J实现比较简单,向量点乘直接求和;讲道理,对角线上的元素不就是对应向量的点乘吧,有大佬知道有哪里想得不对滴滴我。
梯度下降的m文件:
function destination = gradient_decline_classification( X,y,theta )
alpha=0.02;
i=1;
iter=70;
m=length(X(:,1)); %样本数
J=zeros(1,iter);
while i<iter,
[J(i),grad]=costFunctionJ_classification(X,y,theta');
%offset=(sigmoid(X*theta')-y)'*X;
theta=theta-alpha*grad;
i=i+1;
end;
plot(1:iter,J);
destination=theta;
end
这次改写了loss函数,返回了loss值和梯度,算是相比前面文章中的一个小优化。
逻辑回归m文件:
function theta_new = logistic_regression( )
%生成三类数据
x=load('D:\machineLearning\逻辑回归\ex4Data\ex4x.dat');
y=load('D:\machineLearning\逻辑回归\ex4Data\ex4y.dat');
m=length(x(:,1));
c_p=find(y==1);
s_p=find(y==0);
x(:,1)=(x(:,1)-mean(x(:,1)))./std(x(:,1));
x(:,2)=(x(:,2)-mean(x(:,2)))./std(x(:,2));
plot(x(c_p,1),x(c_p,2),'ro');
hold on;
plot(x(s_p,1),x(s_p,2),'bs');
x=[ones(m,1),x];
d_x=sort(x(:,2));
theta=[0 0 0];
theta_new=gradient_decline_classification(x,y,theta);
d_y=-theta_new(1)/theta_new(3)-theta_new(2)*d_x/theta_new(3); %决策边界,令那个函数等于0,反求x2
plot(d_x,d_y,'k-','LineWidth',1);
legend('first kind','second kind','fitting line');
end
踩坑里面挣扎了两天,绘图的时候用的是归一化前面的点,而权重都是特征归一化后训练过的,那肯定有偏差。在此揪出这个问题,要归一化后再画图!!!
四、结果与总结
对数几率回归是感知机和神经网络模型的组成基础,所以我们可以以神经网络的角度来看待它。将一个对数几率回归看成一个神经元,其参数的训练看成神经元的参数训练,只不过它不含隐藏层而已。本例中的模型可以看成:
下一篇准备写Regularization,希望大家多多支持!谢谢