机器学习笔记(2): Logistic 回归

Logistic 回归是线性回归中一个很重要的部分。

Logistic 函数:

σ(x)=L1+exp(k(xx0))

其中:

  • L 表示最大值
  • x0 表示对称中心
  • k 表示倾斜度

一般来说,都将 L 设为 1,而 kx0 在参数中控制。


认为特征只有一个,那么自然:

p(y=1|x)=σ(ω0+ω1x)=11+exp(ω0+ω1x)

认为 x 是特征向量,并且是增广向量,也就是:

x=[x0x1xc1]

认为参数向量也是增广的:

ω=[ω0ω1ωc1]

那么:

p(y=1|x)=σ(xω)=11+exp(xω)

对于多组数据,X=[x0x1xm]

p(y=1|X)=σ(Xω)

注意最终得到是一个向量,σ 函数作用于向量中的每个单独的元素。


利用交叉熵作为损失函数:

R(ω)=1mn=1m(ynlogy^n+(1yn)log(1y^n))

其中 y^ 表示预测分类,而 y 表示实际分类。

由于 σ(x)=σ(x)(1σ(x)),自然的可以推出其偏导数:

ωR(ω)=1m(yny^n(1y^n)y^nxn+(1yn)y^n(1y^n)1y^nxn)=1m(yny^n)xn

写成向量形式也就是:

1m(y^y)x

于是利用梯度下降算法:

ω=ωαmXT(σ(Xω)y)

代码和梯度下降函数十分相似。


Feature Mapping

合理的利用线性回归可以解决很多复杂的问题。

大概率我们需要一个类似于圆的东西才可以拟合。

考虑到在高中我们学过:

C:Ax2+By2+Cx+Dy+F=0

可以表示一个圆,那么我们就可以利用重映射:

(x,y)[1xyxyx2y2]

的方式将特征向量进行一点点简单的变换,那么自然就变成了对于多个参数的线性回归问题,一种可能的拟合是:

当然,我们也可以更复杂的利用这些参数,例如 x3x1x 之类的参数,这取决于我们想要如何去拟合。


正则化参数

和平方损失函数的正则化方式一模一样,见 机器学习笔记(1): 梯度下降算法


代码

function g = sigmoid(z)
	g = 1.0 ./ (1.0 + exp(-z));
end

function [J, grad] = costFunctionReg(theta, X, y, lambda)
	m = length(y);
	H = sigmoid(X * theta);
	temp = theta;
	temp(1) = 0;
	J = 1 / m * (- y' * log(H) - (1 - y)' * log(1 - H)) + temp' * temp * lambda / 2 / m;
	grad = 1 / m * (X' * (H - y)) + lambda / m * temp;
end

function theta = train(X, y, lambda)
	initial_theta = zeros(size(X, 2), 1);
	options = optimset('GradObj', 'on', 'MaxIter', 400);
	[theta, J, exit_flag] = ...
		fminunc(@(t)(costFunctionReg(t, X, y, lambda)), initial_theta, options);
end
	
function p = predict(theta, X)
	m = size(X, 1);
	H = sigmoid([ones(m, 1) X] * theta);
	p = H >= 0.5;
end

其实整体的代码都非常的简单并且简洁。


Softmax Regression

其实就是多分类的 Logistic 回归:

p(y=c|x)=softmax(xW)=exp(xWc)k=1Cexp(Wk)

其中 C 表示分类数,而 W=[ω1ω2ωC],其中 ωi 就表示某一个 Logistic 函数的参数。

由于其实就是多个 Logistic 函数,所以其偏导数和参数学习过程非常相似:

W=WαmXT(σ(XW)Y)

值得注意的是,对于每一个 ωi 减去同一个 θ 结果不会改变,意味着一般都需要正则化。


One VS All Classifier

其实就是多次 Logistic 回归。

function [J, grad] = lrCostFunction(theta, X, y, lambda)
m = length(y);
H = sigmoid(X * theta);
temp = theta;
temp(1) = 0;
J = 1 / m * (- y' * log(H) - (1 - y)' * log(1 - H)) + temp' * temp * lambda / 2 / m;
grad = 1 / m * (X' * (H - y)) + lambda / m * temp;

end

function [all_theta] = oneVsAll(X, y, num_labels, lambda)
	m = size(X, 1);
	n = size(X, 2);
	
	all_theta = zeros(n + 1, num_labels);
	X = [ones(m, 1) X];
	
	options = optimset('GradObj', 'on', 'MaxIter', 300);
	for c = 1:num_labels
		initial_theta = zeros(n + 1, 1);
		[theta] = ...
			fmincg(@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
				initial_theta, options);
		all_theta(:, c) = theta;
	end
end

function p = predictOneVsAll(all_theta, X)
	m = size(X, 1);
	X = [ones(m, 1) X];
	H = X * all_theta;
	[_, p] = max(H, [], 2);
end

也就是对于每一个分类来一次线性回归而已,并没有什么特别之处。

posted @   jeefy  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示