我正在编写我在Coursera机器学习课程(MATLAB)中学习的线性回归的代码。我找到了一个类似的帖子在这里,但我似乎无法完全理解。可能是因为我的机器学习基础有点薄弱。
我面临的问题是,对于某些数据…梯度下降(GD)和闭式解(CFS)给出了相同的假设线。然而,在一个特定的数据集上,结果却不同。我读到过,如果数据是奇异的,那么结果应该是相同的。然而,我不知道如何检查我的数据是否是奇异的。
我将尽我所能进行说明:
1) 首先,这是从这里改编的MATLAB代码。对于给定的数据集,一切都很顺利,GD和CFS给出了相似的结果。
数据集
X Y2.06587460000000 0.7791892600000002.36840870000000 0.9159675700000002.53999290000000 0.9053835400000002.54208040000000 0.9056613800000002.54907900000000 0.9389889000000002.78668820000000 0.9668474000000002.91168250000000 0.9643682400000003.03562700000000 0.9144593900000003.11466960000000 0.9393394400000003.15823890000000 0.9607497100000003.32759440000000 0.8983709400000003.37931650000000 0.9120973900000003.41220060000000 0.9423849900000003.42158230000000 0.9662457800000003.53157320000000 1.052650000000003.63930020000000 1.014379100000003.67325370000000 0.9596942600000003.92564620000000 0.9685371600000004.04986460000000 1.076606500000004.24833480000000 1.145497800000004.34400520000000 1.034062500000004.38265310000000 1.007000900000004.42306020000000 0.9668364800000004.61024430000000 1.089591900000004.68811830000000 1.063446200000004.97773330000000 1.123723900000005.03599670000000 1.032337400000005.06845360000000 1.087445200000005.41614910000000 1.070298800000005.43956230000000 1.160649300000005.45632070000000 1.077803700000005.56984580000000 1.106975800000005.60157290000000 1.097187500000005.68776170000000 1.164860300000005.72156020000000 1.141179600000005.85389140000000 1.084415600000006.19780260000000 1.125249300000006.35109410000000 1.116834100000006.47970330000000 1.197078900000006.73837910000000 1.206946200000006.86376860000000 1.125104600000007.02233870000000 1.123567200000007.07823730000000 1.213282900000007.15142320000000 1.252265200000007.46640230000000 1.249706500000007.59738740000000 1.179970600000007.74407170000000 1.189729900000007.77296620000000 1.302993400000007.82645140000000 1.260113400000007.93063560000000 1.25622670000000
我的MATLAB代码:
clear all; close all; clc; x = load('ex2x.dat');y = load('ex2y.dat');m = length(y); % 训练样本的数量% 绘制训练数据figure; % 打开一个新的图形窗口plot(x, y, '*r');ylabel('高度(米)')xlabel('年龄(年)')% 梯度下降x = [ones(m, 1) x]; % 在x中添加一列1theta = zeros(size(x(1,:)))'; % 初始化拟合参数MAX_ITR = 1500;alpha = 0.07;for num_iterations = 1:MAX_ITR thetax = x * theta; % 对于theta_0和x_0 grad0 = (1/m) .* sum( x(:,1)' * (thetax - y)); % 对于theta_0和x_0 grad1 = (1/m) .* sum( x(:,2)' * (thetax - y)); % 这是实际的更新 theta(1) = theta(1) - alpha .* grad0; theta(2) = theta(2) - alpha .* grad1;end% 将theta打印到屏幕上theta% 绘制假设线(即线性拟合)hold onplot(x(:,2), x*theta, 'ob')% 使用闭式解绘制plot(x(:,2), x*((x' * x)\x' * y), '--r')legend('训练数据', '线性回归', '闭式解')hold off % 不要在该图形上覆盖更多图形''
[编辑:抱歉标记错误…不是正规方程,而是闭式解。我的错误]此代码的结果如图所示(结果非常好:D GD和CFS的结果相同) –
- 现在,我正在用另一个数据集测试我的代码。数据集的URL是这里 – 灰袋鼠。我将其转换为CSV格式并读取到MATLAB中。请注意,我进行了缩放(除以最大值,因为如果我不这样做,根本不会出现假设线,而且theta在MATLAB中会变成非数字(NaN))。
灰袋鼠数据集:
X Y609 241629 222620 233564 207645 247493 189606 226660 240630 215672 231778 263616 220727 271810 284778 279823 272755 268710 278701 238803 255855 308838 281830 288864 306635 236565 204562 216580 225596 220597 219636 201559 213615 228740 234677 237675 217629 211692 238710 221730 281763 292686 251717 231737 275816 275
我对代码的修改以读取此数据集
dataset = load('kangaroo.csv'); % 缩放? x = dataset(:,1)/max(dataset(:,1)); y = dataset(:,2)/max(dataset(:,2));
得到的结果如下所示:[编辑:抱歉标记错误…不是正规方程,而是闭式解。我的错误]
我想知道是否有任何解释可以说明这种差异?任何帮助将不胜感激。提前谢谢你!
回答:
我没有运行你的代码,但我给你一些理论:
如果你的代码是正确的(看起来是这样的):增加MAX_ITER
,结果会更好。
梯度下降并不能保证在MAX_ITER
时收敛,实际上,梯度下降方法在收敛速度上相当慢。
对于“标准”的凸函数(如你试图解决的函数),梯度下降的收敛情况如下(来自互联网):
不要在意迭代次数,因为它取决于问题本身,重点关注形状。可能发生的情况是,你的最大迭代次数落在类似于图像中“20”的位置。因此你的结果不错,但不是最佳的!
然而,直接求解正规方程会给你最小二乘误差解。(我假设你说的正规方程是指x=(A'*A)^(-1)*A'*b
)。问题在于,在许多情况下,你无法将A
存储在内存中,或者在病态问题中,正规方程会导致病态矩阵,这在数值上是不稳定的,因此使用梯度下降方法。