在做完上一篇只有一个变量的线性回归后,这里继续完成多元线性回归模型的练习:http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex3/ex3.html。其实模型也是完全一样的,只不过输入是多维的特征而已,这里的数据是给定了房子大小和房间数相对应的房价,给了这些数据,用线性回归模型求出模型参数,然后对新数据作出预测。
%% Exercise 3: Multivariate Linear Regression % 多变量线性回归 %% %% 载入数据并作预处理 x = load('ex3x.dat'); y = load('ex3y.dat'); m = length(x); x = [ones(m, 1), x]; %第一列全为1,加入偏置项 x_unscaled = x; %保存为归一化的x,后面方程解要用到 sigma = std(x); % 如果为vector,则返回标准差,如果是矩阵,返回每一列即每个维的标准差 mu = mean(x); % 如果为vector,返回平均值,如果为矩阵,返回每一列的平均值 x(:,2) = (x(:,2) - mu(2))./ sigma(2); % 归一化:减去平均值再除标准差 x(:,3) = (x(:,3) - mu(3))./ sigma(3); %% %% 为画图做准备 figure; plotstyle = {'b', 'r', 'g', 'k', 'b--', 'r--'}; %不同的学习率用不同的画线风格 %% %% 梯度下降 MAX_ITR = 100; alpha = [0.01, 0.03, 0.1, 0.3, 1, 1.3]; theta_grad_descent = zeros(size(x(1,:))); n = length(alpha); for i = 1:n theta = zeros(size(x(1,:)))'; % size(x(1,:))返回1*n向量,n为每个样本的维数,转置后为n*1的0向量 J = zeros(100, 1); for num_iterations = 1:MAX_ITR J(num_iterations) = (0.5/m) .* sum((y-x*theta).^2); % 损失函数 theta = theta - alpha(i)*(1/m).*x'*(x*theta-y); end plot(0:49, J(1:50), char(plotstyle(i)), 'LineWidth', 2); hold on; %通过实验发现alpha为1时损失最小,这里记录下这时的theta if alpha(i) == 1 theta_grad_descent = theta; end end legend('0.01', '0.03', '0.1', '0.3', '1', '1.3'); xlabel('Number of iterations'); ylabel('Cost L'); %% 预测 theta_grad_descent % 预测房子面积为1650,房间数为3的房价 price_grad_desc = dot(theta_grad_descent, [1, (1650-mu(2))/sigma(2), (3-mu(3))/sigma(3)]) %% Normal equations theta = inv(x_unscaled'*x_unscaled)*x_unscaled'*y price_normal = dot(theta, [1, 1650, 3]) %%实验结果:
从上面的结果看出,选择不同的步长会有不一样的结果,如果选得不好,算法可能不会收敛,即损失不会减少到某一极小点,可能在某一局部最优解上震荡,这样的模型对训练数据都没找出正确的规律,用来预测新数据也肯定不会好。做实验时,调参是一个很重要的步骤。还有就是预处理也非常重要,像这里的数据中,一个是房子面积,数目大而且变化大,而房间数数目小而且变化小,如果不做归一化等预处理学习到的模型可能会过拟合,做了归一化处理可能加加快学习速度,学到的模型更稳定,variance更小。