一些前提的约定,还是沿用上篇文章的哈。先来致敬下男神。

每天进步一点点《ML - 逻辑回归》_机器学习

一:Logistic Regression Model简介
它是一种二分类的模型(Binary-Classification),属于监督学习的分类算法,也就是说它的结果只有(0,1)两种结果,给定某个样本,每个样本的y(i) 的值属于集合{0, 1},非0即1,非1即0,没有其他结果。比如是不是垃圾邮件,是不是高电位等等,此处的0,1仅仅是符号,没有数字上的意义,我们可认为1代表是/否,也可以认为0代表是/否。
从某种习惯上讲,在二分类模型中,我们倾向于当某个事件的概率大于50%,则100%认为是某个结果,相应地,当某个事件的概率小于50%,则100%认为是某个另外的那个结果,这个结果可以{0, 1}的任意一种,切记{0, 1}仅仅是符号,某种代表具体含义的符号。
当然我们也可以换种习惯,当某个事件的概率大于60%,则100%认为是某个结果,相应地,当某个事件的概率小于40%,则100%认为是某个另外的那个结果,中间的40%~60%区间的事件,我们认为不确定。这样的假设,在后面介绍SVM的时候会讲到。
此处我们先学习下,第一种习惯。
由于所有的结果只有0,1两种结果,非0即1,非1即0。
我们认为某个事件A=1发生的概率是:P{Y=1|X} = H(θ)(X)
那么认为某个事件A=1发生的概率是:P{Y=0|X} = 1 - H(θ)(X)
即:P{Y=1|X} + P{Y=0|X} = 1

一:模型函数(假设函数)

每天进步一点点《ML - 逻辑回归》_代价函数_02


其实这俩式子是一样的,因为若我们得到了预测P{Y=1|X}的概率,其实也同样得到P{Y=0|X}的概率。

整理一下,两个式子合并得:

每天进步一点点《ML - 逻辑回归》_最小化_03


举个例子:某运动员Andrew射箭,射中的概率是Y=P,那么不中的概率是Y=Q=1-P。中和不中是两个互斥事件,假设射中用1表示,射不中用0表示,所以,当某个事件(未知)已发生。

这个事件的概率就是Y=(P^y) * ((1-P) ^ (1-y))。

以上纯属概率论的基本知识了。

好了,回到我们的假设函数,当某个事件(x,y)发生,我们需要做的事情就是,根据X计算预测输出y’,使得y’= y ,大概率是等于该事件,这里大概率是指起码超过50%的可能。
1)比如(x, 1)事件发生。
若我们根据Y=H(θ)(X)函数进行预测,期望Y>0.5,即Xθ>0;若我们根据Y=1-H(θ)(X) 函数进行预测,期望Y<0.5,即Xθ<0。
2)比如(x, 0)事件发生。
若我们根据Y=1-H(θ)(X) 函数进行预测,期望Y>0.5,即Xθ>0;若我们根据Y=H(θ)(X) 函数进行预测,期望Y<0.5,即Xθ>0。

再简单讨论,后续我们仅用Y=H(θ)(X) 函数进行讨论,该函数是仅仅用来预测Y=1的事件的发生概率,反过来看,H(θ)(X)越大,越能确信是Y=1的事件,H(θ)(X)越小,越不能确定是Y=1。
若Y>0.5,即Xθ>0,我们就预测该输出Y=1
若Y<0.5,即Xθ<0,我们就预测该输出Y != 1,其实也就是Y=0

上述函数H(θ)(X) 的曲线刚好就是sigmoid曲线。

1:sigmoid曲线,蓝色是H(θ)(X),红色是1-H(θ)(X)

每天进步一点点《ML - 逻辑回归》_最小化_04


仅仅看蓝色这条线,H(θ)(X)。H(θ)(X) 是用来预测是Y=1的概率的。H(θ)(X)越大,越能确信是Y=1,反之H(θ)(X)越小,越不能确信Y=1,也就是Y=0。

如果有个事件Y=1,那么我们希望H(θ)(X)应该尽可能接近1,否则会有代价损失;

同样如果有个事件Y=0,那么我们希望H(θ)(X)应该尽可能接近0,否则会有代价损失;2:代价函数

此时请注意,这里的Y=1和Y=0依然是符号。

每天进步一点点《ML - 逻辑回归》_迭代_05


上述代价函数的图像如下:

每天进步一点点《ML - 逻辑回归》_机器学习_06


蓝色是1式的代价函数图像,H(θ)(X)范围在[0,1]之间。
对于Y=1 的事件,如果H(θ)(X) 预测的概率 越接近1,代价值越小。误差越小。
对于Y=1 的事件,如果H(θ)(X) 预测的概率 越接近0,代价值越大。误差越大。
红色是2式的代价函数图像:,H(θ)(X)范围在[0,1]之间。
对于Y=0 的事件,如果H(θ)(X) 预测的概率 越接近1,代价值越大。误差越大。
对于Y=0 的事件,如果H(θ)(X) 预测的概率 越接近0,代价值越小。误差越小。
切记,此处,H(θ)(X)是专门用来预测Y=1 的概率的。

合并两式代价估算函数得:

每天进步一点点《ML - 逻辑回归》_代价函数_07

3:极大似然

上述这个代价函数如何得来的呢?我们已经得知某个事件发生的概率是:

每天进步一点点《ML - 逻辑回归》_最小化_08


极大似然,简单来说呢,就是已知一系列已知的事件,已知某个概率模型(只知道输入输出,不知道模型的参数),那么事实上,发生这个一系列的事件概率就是P = ∏_(i=1)m▒〖P{Y((i)) |X^((i))}〗,那么P是就是一个关于参数θ的函数:P(θ),反推最具有可能(最大概率)导致这些样本结果出现的模型参数值。说人话就是,在θ取何值得时候,P(θ)有最大值,才导致了现在这些样本序列的出现。

求最大值,上述函数太复杂,我们做个映射,用对数函数做映射。

每天进步一点点《ML - 逻辑回归》_代价函数_09


诶?我们的代价函数感觉跟这个很像了。

每天进步一点点《ML - 逻辑回归》_迭代_10


也就是说,我们希望求得某个θ参数使得L(θ)有最大值,那么相当于某个θ参数使得Cost(H(θ)(X),Y)有最小值。对L(θ)乘以 -1/m,就是我们的代价函数。

因为我们习惯上是,根据某个模型,找出代价函数,通过梯度下降等方法最小化代价函数,去求得θ。

因为我们习惯上是,根据某个模型,找出代价函数,通过梯度下降等方法最小化代价函数,去求得θ。

因此我们找到的代价函数其实源自于极大似然估计。从这里我们也能得到一个感觉,凡是你能通过最大最小值估计参数的计算过程,说不定也是可以用作代价函数的,不过必须得满足代价函数的基本要求,因为,所谓代价函数其实也就是,通过最小化代价函数(最小化误差)得到某个参数的过程,概念上如出一辙


4:最小化代价函数

我们常用的有梯度下降的计算过程。当然除此之外,还有共轭梯度法,BFGS,L- BFGS等。

代价函数已知

每天进步一点点《ML - 逻辑回归》_机器学习_11


根据梯度下降:

不用说,先赋初值,θ=0;

每天进步一点点《ML - 逻辑回归》_代价函数_12


我们一起推倒下:加深学习的理解,这里涉及导数求解的过程。

每天进步一点点《ML - 逻辑回归》_代价函数_13

到此,我们可以用梯度下降法求解参数。
到目前为止我们就讲解了大部分的 Logistic Regression的核心内容。
后续还会降到对参数的正则化。向量化我都不讲了,且看我操作实践的例子就有向量化的运算过程,

5:多类别的分类(multiple calssication) (one – vs -all)

现在假设有多个分类,不再是二重分类,输出特征有(y1,y2,y3……yk),有k种不同的类别,怎么操作呢?

利用现有的binary-classication进行分析。

每天进步一点点《ML - 逻辑回归》_最小化_14


这样我们能得到k个不同的假设函数,这样一来最后我们选择 概率值最大的那个类别即可,

Y = max(H_((θ))^((i))(X)),也就是哪个概率预测最大,就属于哪个类型。

6:实例操作。
通过两个实例,连展示在不同的决策边界情况下对样本类别的划分。Xθ是空间的划分边界。也就是就决策边界(边界上的点,Xθ=0,两边的分别是>0和<0的),

实例一:(线性边界),θ0+ θ1X1 + θ3 X2= 0

每天进步一点点《ML - 逻辑回归》_最小化_15

clc;clear all;close all;
set(0,'defaultfigurecolor','w') ;

src_x1 = [1.3,1.35,1.4,1.45,1.5, 1.32,1.33,1.42,1.43,1.46];
src_y1 = [3.32, 3.15, 3.12, 3.41, 3.26 ,3.3, 3.5, 3.2, 3.4, 3.6];
src_x2 = [3.3, 3.35, 3.4, 3.45, 3.5, 3.32,3.352,3.42,3.47,3.52];
src_y2 = [5.3, 5.5, 5.2, 5.4, 5.6, 5.32, 5.35, 5.24, 5.34, 5.61];

src_x = [src_x1, src_x2];
src_y = [src_y1, src_y2];
tag = [zeros(1, size(src_x1)(2)), ones(1, size(src_x2)(2))];

x = [ones(size(src_x)(2), 1), src_x', src_y'];
y = tag';
theta = (zeros(3, 1));

itr = 10000; %iteration times
rate = 0.02; %step
cost = zeros(1, itr);
for it=1:itr
% update each theta
temp = theta;
for j=1:size(theta)(1)
temp(j) = theta(j) - rate * sum(((1 ./ (1 + exp(-1 * x * theta))) - y)' * diag(x(:,j))) / (size(x)(1));
end;
theta = temp;

% compute the cost value
cost(it) = sum( (y .* log(1 ./ (1 + exp(-1 * x * theta))) + (1 .- y) .* (log(1 ./ (1 + exp(1 * x * theta)))) ) .- y) / (-1 * size(x)(1));
end;


figure();
subplot(1,2, 1);
hold on;

% 打点,画决策边界
scatter(src_x1, src_y1, 'b', 'linewidth', 3);
scatter(src_x2, src_y2, 'r', 'linewidth', 3);
xx = [0:0.1:6];
plot(xx, -((theta(1)/ theta(3)) + (theta(2)/theta(3)) .* xx), 'g', 'linewidth', 3);
xlim([0,6]);
ylim([2,6]);
%axis equal;
grid on;
xlabel('x1');
ylabel('x2');

% 画代价函数跟随迭代次数的收敛曲线
subplot(1,2, 2);
xx = (1:1:itr);
scatter(xx, cost, 'p', 'linewidth', 3);
xlim([0,itr]);
ylim([0,1.5]);
%axis equal;
grid on;
hold on;
xlabel('iteration times');
ylabel('cost value');

每天进步一点点《ML - 逻辑回归》_机器学习_16

左图的绿色划线是决策边界线,线上的点的数值为0, 两边分别是>0或者<0,右边是代价函数跟随迭代次数的收敛曲线。
Θ = [-4.5802, 5.9927, -2.1914]

实例二:(非线性边界): θ0 + θ1X1^2 + θ3X2^2= 0

随机生成一堆的环点。

clc;clear all;close all;
set(0,'defaultfigurecolor','w') ;

src_x1 = [-1:0.1:1];
src_y1 = [sqrt(1 - src_x1.^2) .* rand(1, size(src_x1)(2)), - sqrt(1 - src_x1.^2) .* rand(1, size(src_x1)(2))];
src_x1 = [src_x1, src_x1];

src_x2 = [-3:0.1:3];
src_y2 = zeros(1, size(src_x2)(2));
for i=1:size(src_x2)(2)
if src_x2(i) < -2 || src_x2(i) > 2
src_y2(i) = sqrt(9 - src_x2(i).^2) .* rand(1);
else
tmp = sqrt(9 - src_x2(i).^2) - sqrt(4 - src_x2(i).^2);
src_y2(i) = tmp + (sqrt(9 - src_x2(i).^2) - tmp) * rand(1);
end;
end;
src_x2 = [src_x2, src_x2];
src_y2 = [src_y2, -src_y2];



src_x = [src_x1, src_x2];
src_y = [src_y1, src_y2];
tag = [zeros(1, size(src_x1)(2)), ones(1, size(src_x2)(2))];

x = [ones(size(src_x)(2), 1), (src_x').^2, (src_y').^2];
y = tag';
theta = (zeros(3, 1));

itr = 50000; %iteration times
rate = 0.005; %step
cost = zeros(1, itr);
for it=1:itr
% update each theta
temp = theta;
for j=1:size(theta)(1)
temp(j) = theta(j) - rate * sum(((1 ./ (1 + exp(-1 * x * theta))) - y)' * diag(x(:,j))) / (size(x)(1));
end;
theta = temp;

% compute the cost value
cost(it) = sum( (y .* log(1 ./ (1 + exp(-1 * x * theta))) + (1 .- y) .* (log(1 ./ (1 + exp(1 * x * theta)))) ) .- y) / (-1 * size(x)(1));
end;


figure();
subplot(1,2, 1);
hold on;

% 打点,画出决策边界
scatter(src_x1, src_y1, 'b', 'linewidth', 3);
scatter(src_x2, src_y2, 'r', 'linewidth', 3);

px = [-sqrt(-theta(1)/theta(2)) : 0.001 : sqrt(-theta(1)/theta(2))];
py = sqrt((-theta(1) - theta(2)* (px .^ 2)) / theta(3));
px = [px, px];
py = [py, -py];

scatter(px, py, 'g', 'linewidth', 1);

xlim([-4,4]);
ylim([-4,4]);
%axis equal;
grid on;
xlabel('x1');
ylabel('x2');

% 画代价函数跟随迭代次数的收敛曲线
subplot(1,2, 2);
xx = (1:1:itr);
scatter(xx, cost, 'p', 'linewidth', 3);
xlim([0,itr]);
ylim([0.6,1.5]);
%axis equal;
grid on;
hold on;
xlabel('iteration times');
ylabel('cost value');

每天进步一点点《ML - 逻辑回归》_代价函数_17

左图示随机生成的两个类别的点,右图是随着迭代次数变化的代价函数。绿色划线是决策边界。
Θ = [-4.5390, 1.5240, 3.9479]