在国外发现一个很好的机器学习教学,有兴趣可以可以私聊我。
本篇文章写得是学习梯度下降法的心得,理论的话不赘述了,网络上一大片,主要讲解下本文写得matlab代码
首先计算cost function,也就是预测值和真实值的残差平方均值,如下:
function J = computeCost(X, y, theta)
m = length(y);
J = 0;
for i=1:m
J=J+(X(i,:)*theta-y(i))^2;
end
J=1/(2*m)*J;
end
再其次就是梯度下降法的代码:
function [theta1, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
m = length(y);
J_history = zeros(num_iters, 1);
J_theta=[];
Jtheta=0;
for iter = 1:num_iters
for k=1:length(theta) %增加一个循环,扩充到n维,变化theta值
for i=1:m
Jtheta=Jtheta+(X(i,:)*theta-y(i))*X(i,k);%这个是公式
end
J_theta(k)=theta(k)-alpha/m*Jtheta;%这个也是公式
end
theta=J_theta';
Jtheta=0;
J_history(iter) = computeCost(X, y, theta);
theta1(iter,:)=theta';
end
end
说下出现的一次错误,没加Jtheta=0导致残差平方和无限增大。为了方面后面计算,theta值的计算已扩充到n维。
实际应用于
一个数据集,如下:
代码:
data = load('ex1data1.txt'); % 读取数据
x = data(:, 1); y = data(:, 2);
m = length(y);
X = [ones(m, 1), data(:,1)]; % 使x前加上一列
theta = zeros(2, 1); % 初始化theta值
iterations = 1500;
alpha = 0.01;
computeCost(X, y, theta)
[J_theta, J_history] = gradientDescent(X, y, theta, alpha,iterations)
plot(1:1500,J_history(1:1500));%画图
title('gradientDescent')
xlabel('iterations')
ylabel('cost function')
figure
plot(x, y, 'rx', 'MarkerSize',10); %画图
y1=X*J_theta(m,:)';
hold on
plot(x,y1)
上述代码中,X自变量矩阵前要加入一列全为1的矩阵,这是为了计算截距项,也方便后面加theta值,theta的数量为自变量个数加一,第一个计算出来的theta值也就是截距项,然后这边theta初始值为[0;0],迭代次数设置为1500,学习速率设为0.01,结果如下:
三维图制作
theta0_vals = linspace(-10, 10, 100);
theta1_vals = linspace(-1, 4, 100);
J_vals = zeros(length(theta0_vals), length(theta1_vals));
for i = 1:length(theta0_vals)
for j = 1:length(theta1_vals)
t = [theta0_vals(i); theta1_vals(j)];
J_vals(i,j) = computeCost(X, y, t);
end
end
J_vals = J_vals';
surf(theta0_vals, theta1_vals, J_vals)
xlabel('\theta_0'); ylabel('\theta_1');
下面试验新数据集,看是否会出现代码错误现象:
代码:
data = load('ex1data2.txt'); % 读取数据
x = data(:, 1:2); y = data(:, 3);
m = length(y);
X = [ones(m, 1), data(:,1:2)]; % 使x前加上一列
[inputn,inputps]=mapminmax(X');
[outputn,outputps]=mapminmax(y');
theta = zeros(3, 1); % 初始化theta值
iterations = 1500;
alpha = 0.01;
computeCost(X, y, theta)
[J_theta, J_history] = gradientDescent(inputn', outputn', theta, alpha,iterations)
J_history=mapminmax('reverse',J_history,outputps);
plot(1:1500,J_history(1:1500));%画图
title('gradientDescent')
xlabel('iterations')
ylabel('cost function')
figure
plot(x, y, 'rx', 'MarkerSize',10); %画图
y1=X*J_theta(m,:)';
hold on
plot(x,y1)
以上代码另加入了归一化处理,结果没有出现问题,如下:
各位可自找数据集应用。