代码如下:
data=load('E:\研究生\机器学习\吴恩达机器学习python作业代码\code\ex1-linear regression\ex1data2.txt');
x=data(:,1:2);y=data(:,3);
m=length(y);
[x,mu,sigma]=featureNormalize(x);
X=[ones(m,1),x];
alpha=[0.01,0.03,0.1,0.3,1];
plotstyle={'r','g','b','y','k'};
num_iters=400;
for i=1:length(alpha)
al=alpha(i);
theta=zeros(size(X,2),1);
[theta,J_history]=gradientDescentMulti(X,y,al,theta,num_iters);
plot(1:numel(J_history),J_history,char(plotstyle(i)),'linewidth',2);
hold on
end
xlabel('number of iterations');ylabel('cost J');
legend('alpha=0.01','alpha=0.03','alpha=0.1','alpha=0.3','alpha=1','location','northeast')
predict1=[1,([1650 3]-mu)./sigma]*theta;
在多变量线性回归中,由于变量的范围有所不同,如x1是0到5000的数,而x2则是0到5的数,这会导致在X与Y坐标轴比例尺相同的情况下,整个图像显得极为修长,且此时梯度下降会需要很多次迭代才能收敛。因此需要进行特征缩放,使x1和x2在保持原有对应关系下,能稳定在-1到1之间。
公式为 x n = x n − μ n s n x_n=\frac{x_n-\mu_n}{s_n} xn=snxn−μn,其中 μ \mu μ是平均值, s n s_n sn是标准差。
function [X_norm mu sigma]=featureNormalize(X)
X_norm=X;
mu=zeros(1,size(X,2));
sigma=zeros(1,size(X,2));
for i=1:size(X,2)
mu(i)=mean(X_norm(:,i));%分别求出所有x1和x2的均值
sigma(i)=std(X_norm(:,i));%分别求出所有x1和x2的标准差
end
X_norm=(X_norm-ones(size(X,1),1)*mu)./(ones(size(X,1),1)*sigma);
%乘上ones(size(X,1),1)可以让mu返回矩阵状态,与X_norm进行矩阵运算
end
得到的最终值X_norm为特征缩放后的x1和x2值。
公式为 θ j = θ j − α 1 m ∑ i n t = 1 m ( ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j=\theta_j-\alpha\frac{1}{m}\sum_{int=1}^m((h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} θj=θj−αm1∑int=1m((hθ(x(i))−y(i))xj(i)(同时更新 θ j \theta_j θj,其中j=0,1,…,n)。同样,for循环外层为迭代次数,内层为每次迭代过程中 θ j \theta_j θj的更新。J_history在每次迭代完成计算代价函数。
function [theta J_history]=gradientDescentMulti(X,y,al,theta,num_iters)
m=length(y);
temp=theta;
J_history=zeros(num_iters,1);
for iter=1:num_iters
for i=1:size(theta,1)
temp(i,:)=theta(i,:)-al/m*sum((X*theta-y)'*X(:,i));
end
J_history(iter)=computeCost(X,y,m,theta);
theta=temp;
end
代价函数computeCost.m同单变量线性回归,但需要写成矩阵形式。
function J = computeCost(X,y,m,theta)
J=0;
J=1/(2*m)*sum(((X*theta)-y)'*((X*theta)-y));
end
最后梯度下降得到最优 θ \theta θ,接下来要对不同的 α \alpha α学习效率进行绘图比对。其中numel()可以得到矩阵元素个数,由于这里J_history是列向量,因此也可以用length代替。得到图1如下:
图1 不同学习效率下的J |
---|
最后通过预测,当x1=1650,x2=3时,预测y结果为293081.464334896。
代码如下:
data=load('E:\研究生\机器学习\吴恩达机器学习python作业代码\code\ex1-linear regression\ex1data2.txt');
x=data(:,1:2);y=data(:,3);
m=length(y);
X=[ones(m,1),x];
theta=normalEqn(X,y);
predict2=[1,1650,3]*theta;
公式为 θ = ( X T X ) − 1 X T y \theta=(X^TX)^{-1}X^Ty θ=(XTX)−1XTy。
推导过程为:
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta)=\frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2 J(θ)=2m1∑i=1m(hθ(x(i))−y(i))2 其中: h θ ( x ( i ) ) = θ T X = θ 0 x 0 + θ 1 x 1 + . . . + θ n x n h_\theta(x^{(i)})=\theta^TX=\theta_0x_0+\theta_1x_1+...+\theta_nx_n hθ(x(i))=θTX=θ0x0+θ1x1+...+θnxn
将向量形式转为矩阵形式,则有 J ( θ ) = 1 2 ( X θ − y ) 2 J(\theta)=\frac{1}{2}(X\theta-y)^2 J(θ)=21(Xθ−y)2,在进行如下变换:
J ( θ ) = 1 2 ( X θ − y ) T ( X θ − y ) = 1 2 ( θ T X T − y T ) ( X θ − y ) = 1 2 ( θ T X T X θ − θ T X T y − y T X θ − y ) J(\theta)=\frac{1}{2}(X\theta-y)^T(X\theta-y)=\frac{1}{2}(\theta^TX^T-y^T)(X\theta-y)=\frac{1}{2}(\theta^TX^TX\theta-\theta^TX^Ty-y^TX\theta-y) J(θ)=21(Xθ−y)T(Xθ−y)=21(θTXT−yT)(Xθ−y)=21(θTXTXθ−θTXTy−yTXθ−y)
根据矩阵求导法则有:
d A B d B = A T \frac{dAB}{dB}=A^T dBdAB=AT和 d X T A X d X = 2 A X \frac{dX^TAX}{dX}=2AX dXdXTAX=2AX
所以有:
∂ J ( θ ) ∂ θ = 1 2 ( 2 X T X θ − X T y − ( y T X ) T − 0 ) = 1 2 ( 2 X T X θ − X T y − X T y − 0 ) = X T X θ − X T y \frac{\partial J(\theta)}{\partial \theta}=\frac{1}{2}(2X^TX\theta-X^Ty-(y^TX)^T-0)=\frac{1}{2}(2X^TX\theta-X^Ty-X^Ty-0)=X^TX\theta-X^Ty ∂θ∂J(θ)=21(2XTXθ−XTy−(yTX)T−0)=21(2XTXθ−XTy−XTy−0)=XTXθ−XTy
令 ∂ J ( θ ) ∂ θ = 0 \frac{\partial J(\theta)}{\partial \theta}=0 ∂θ∂J(θ)=0,则有:
θ = ( X T X ) − 1 X T y \theta=(X^TX)^{-1}X^Ty θ=(XTX)−1XTy。
function [theta]=normalEqn(X,y)
theta=zeros(size(X,2),1);
theta=pinv(X'*X)*X'*y;
end
其中inv是求逆,而pinv是求伪逆。用pinv时,即使不可逆的结果,算法流程是正确的。
此时求出的 θ \theta θ为最优值,直接输入矩阵[1 X]与 θ \theta θ相乘可以得到预测值predict。当x1=1650,x2=3时,预测y结果为293081.464334989。
值得注意的是,在多变量线性回归预测中,输入X需要进行特征缩放,而在使用正规方程时不需要,直接代入即可。