这一次,我们从回归问题走向了分类问题
1.拟合函数的选择
现实世界中我们不仅仅需要实际值的预测,更需要类别的预测。比如,邮件属于垃圾邮件还是正常邮件、性别区分男女等等。在这些问题中,我们的目标只有两种状态,1(是)、0(非),如果采用之前的回归模型,那么我们将会得到,大于1或者小于1的实际值。因为我们回归模型问题中,是用一个函数来拟合数据
想要实现分类模型,我们先来看一看实际问题。
分辨肿瘤为良性(0)、恶性(1)。
如果你要用函数来拟合数据,你可能会得到图中品红色的函数。而且我们可以通过设定阈值来处理分类问题,在品红色函数上有一个点,是与y=0.5直线的交点,只要x值小于品红点的特征一律为良性肿瘤,而大于的则为恶性肿瘤。
但现在考虑,如果在右边出现了另一个特征数据(三个箭头指向的),那么我们的拟合函数就会变成蓝色的直线,同样与y=0.5的交点的x值也向右移动,本来应该是恶性肿瘤的数据就被我们预测成了良性。
刚才蓝色的线例子告诉我们对于分类问题我们还是不要用回归模型来做。那么想一想,我们想要将h(x)的值域控制在(0,1)之间,我们应该采用一种映射,将(正无穷,负无穷)映射到(0,1)之间。
通过数学家的不断努力,我们有了一个s型函数。它的值域是(0,1)
现在,让我们重新改造h(x)。
,如我们所愿,h(x)现在的值域是(0,1)。我们用这个函数表示y=0(或者y=1)的概率。
这里提出一个概念:决策边界
可以说决策边界就是用来区分两类数据的线。
这里面 绿色的线就是我们的决策边界,左右两边对应着不同数据。
决策边界是我们拟合函数的一个属性,和我们的任何选择不沾边。
如何找到决策边界?
博主刚开始学习逻辑回归的时候一直觉得决策边界才是逻辑回归的重点,因为决策边界把数据集分成了两个区域,
非常神奇,但是后来实际操作时并没发现这个东西,想了想,其实决策边界就是我们s型函数x=0的一条线,
看这个图,当我们的z>0的时候我们把这个数据预测为1这个类,相同的,z<0的时候是0这个类。
那么,我们是不是通过z值范围来分类的?那么我们的决策边界是不是应该是z=0这个东西?而我们的z是什么,在上面我们也说了
z=θTX,z=0就是θTX=0这条线
z
=
θ
T
X
,
z
=
0
就
是
θ
T
X
=
0
这
条
线
。
2.成本函数的选择
回想我们在线性回归中使用的成本函数,也就是均方差, 。如果我们在逻辑回归中依然使用这个成本函数会发生什么,我们把成本函数的图像画出来,
可以发现我们的成本函数并不是一个凸函数,如果对一个非凸函数进行梯度下降,我们可能会收敛于局部最小值,而并非全局最小值。
那么,我们需要找到另一个成本函数,它是一个凸函数。
这就是我们新找到的成本函数,我们拿y=1举例子,
如果y=1,我们的h(x)也非常接近1(现在h(x)是概率),那么我们的成本函数的值就应该很小。
如果y=1,我们的h(x)却非常接近0,那么我们的成本函数的值就应该很大,就应该对参数θ进行优化(梯度下降),
。
好,但是现在我们的成本函数是一个分段函数,我们把它变成一个连续函数
最后,这个凸函数就可以通过梯度下降收敛于全局最小值了。
接下来我们来实现逻辑回归,并用梯度下降找到最优J(x)(Θ)
首先我们需要训练用的数据集,如果把数据集用Octave画出来的话,我们会更直观:
x1+x2<2就是红色的点而x1+x2>=2则为黑色的点
x
1
+
x
2
<
2
就
是
红
色
的
点
而
x
1
+
x
2
>=
2
则
为
黑
色
的
点
,正例和反例一共50个(最后我会把代码和数据集全部放出来)。
数据集有了接下来我们开始三部曲:1.选定拟合函数形式2.选定拟合函数的成本函数3.通过优化成本函数得出拟合函数确定形式。
我这里直接给出代码
function hx = hFunction(x,theta)
hx = x *theta ;
function Jx = JFunction(theta)
load('train3Dx.txt');
load('trainY.txt');%这两步是为了加载训练数据,如果你有自己的也可以换掉
m = size(trainY)(1);
the_sum = 0;
for i = [1:1:m]
the_sum =the_sum+ (-trainY(i)*log(gFunction(hFunction(train3Dx(i,:),theta)))-(1-trainY(i))*log(1-gFunction(hFunction(train3Dx(i,:),theta))));
end%这一步是一个求和,我这里的Jx其实是成本函数
Jx = (1/m)*the_sum;
function [optTheta,functionVal,exitFlag] = GradientFunction()
options = optimset('GradObj','off','MaxIter',10000);%fminunc函数的必要参数
initialTheta = zeros(3,1);
[optTheta,functionVal,exitFlag] = fminunc(@JFunction,initialTheta,options);%找到最小值--梯度下降就在这里
draw3D(optTheta)%把数据画出来,自定义函数哦
function a = draw3D(theat)
load('train3Dx.txt');
load('trainY.txt');
x = [linspace(1,1,50)' [0:0.05:2.45]' [0:0.05:2.45]'];
arra = theat'*x';
sum_ = 0;
for i = arra
sum_ = [sum_;gFunction(i)];
end
sum_(1,:) = [];
plot3(x(:,2),x(:,3),sum_,'b','linewidth',3);%这是为了画出g(z)函数,s形函数
the_x = [-2:0.1:3]';
ya = -theat(1)/theat(2)-(theat(3)/theat(2))*the_x;%决策边界表达式
hold on
plot3(the_x,ya,zeros(size(ya)(1))(:,1),'g','linewidth',3);%画出决策边界
scatter(train3Dx(:,2)(1:25,:),train3Dx(:,3)(1:25,:),15,'red','filled')%红色的点
scatter(train3Dx(:,2)(26:50,:),train3Dx(:,3)(26:50,:),15,'black','filled')
最后的效果是这样的
链接: https://pan.baidu.com/s/1c3iRqdM 密码: nvg6
用的时候把Octave目录选择到这个解压后文件夹里,然后呢运行GradientFunction()就行了