机器学习编程作业(一)线性回归(Linear Regression)

作业结构:

其中前面带星号的单变量线性回归的内容是必须完成的,而后面带十字架的多变量线性回归的内容是选做的。由于MATLAB和Octave的语法基本一样,而且学校里面用的MATLAB比较多,所以我这里就使用MATLAB来做这个作业了。

代码我已经上传到了GitHub上,需要的自取:代码地址

1 简单的Octave/MATLAB函数(Simple Octave/MATLAB function)

第一个任务需要将 warmUpExercise.m 文件中的 warmUpExercise() 函数补充完整,使其能够返回一个5x5的单位矩阵,构建n阶单位矩阵的函数为 eye(n),所以在函数中键入如下代码即可:

A = eye(5);

然后在到matlab的命令行里面测试函数是否正确:

>> warmUpExercise()

输出结果为:

ans =

   1     0     0     0     0
   0     1     0     0     0
   0     0     1     0     0
   0     0     0     1     0
   0     0     0     0     1

2 单变量线性回归(Linear regression with one variable)

在这一部分中,我们将使用单变量线性回归来预测一家连锁餐厅的利润。假设你是一家餐厅的CEO,正在考虑在不同的城市开设一家新餐厅。因为该连锁店已经在多个城市开展,所以你可以获得这些城市的餐厅收益和人口的关系。现在希望你借助这些数据来预测下一次在哪个城市开连锁店受益最大。

ex1data1.txt文件包含本问题的数据集。第一列是城市的人口,第二列是连锁餐厅的利润,利润为负值代表亏损。

2.1 可视化数据(Plotting the Data)

在开始这项工作之前,我们可以通过将数据可视化的方式来更好的帮助我们理解这些数据。对于这个数据集,我们可以用散点图来可视化,因为只有两个参数(利润和人口)。

首先我们将plotData.m文件中的plotData(x, y)函数补充完整:

plot(x, y, 'rx', 'MarkerSize', 10); % Plot the data 
ylabel('Profit'); % y轴为利润
xlabel('Population'); % x轴为人口

其中的 'rx' 代表红色的叉叉,后面的'MarkerSize', 10调节叉叉的大小。

将plotData(x, y)函数补充完整后在MATLAB命令行里面导入ex1data1.txt中的数据集,其中第一列为人口,这里放入矩阵x中;第二列为利润,这里放入矩阵y中,然后再调用函数plotData(x, y):

>> data = load('ex1data1.txt');
>> x = data(:, 1); y = data(:, 2);
>> plotData(x,y);

执行结果为:
2.2 梯度下降(Gradient Descent)

在这一部分,我们将使用梯度下降算法来找到该数据集的线性回归参数 θ 。

首先复习一下之前学习的几个公式:

  • 假设函数(Hypothesis Function)

  • 代价函数(Cost Function)

  • 梯度下降(Gradient Descent)


    不要忘了梯度下降算法需要同时更新 θj

我们进行梯度下降算法的目标是为了找到最好的 θj 使得其对应的代价函数最小,在梯度下降算法的迭代过程中参数θj会不断接近最优值最后达到收敛。

2.2.1 计算代价函数
首先我们需要补充完整 computeCost.m文件中的 computeCost(x, y, theta) 函数来计算代价函数,根据代价函数的公式,我们不难写出:

m = length(y); % 数据集的数量
J = sum((x * theta - y) .^ 2) / (2*m); % 计算代价函数

为了验证代码是否正确,我们来执行一下。还是使用ex1data1.txt中的数据集,设置一些必要的参数,在命令行中执行如下代码:

>> data = load('ex1data1.txt');
>> x = [ones(m, 1), data(:,1)]; % 第一列全为1,第二列为人口
>> y = data(:, 2); % 利润
>> theta = zeros(2, 1); % 初始化一个全为0的2维向量 [θ0, θ1]T
>> J = computeCost(x, y, theta) % 执行函数

注:将x矩阵第一列设置为全1是为了方便矩阵运算

运行结果为:

2.2.2 实现梯度下降算法

我们需要补充完整 gradientDescent.m文件中的 gradientDescent(x, y, theta, alpha, num_iters) 函数来进行梯度下降,其中theta是我们要求的内容,alpha是学习率,num_iters是迭代次数,算法要求是经过num_iters次迭代后得到的theta能使代价函数J(θ)接近最小值**(因为经过num_iters次迭代不一定能达到最优值)。根据梯度下降的公式我们不难写出:

m = length(y); % 数据集的数量
for iter = 1:num_iters

    theta = theta -  alpha * (x' * (x * theta - y)) / m; % 梯度下降
    c = computeCost(X, y, theta); % 计算更新后的theta值对应的代价函数
    fprintf('%f\n', c); % 打印代价函数计算结果

end

判断一个梯度下降算法是否正常工作的方法是:每次迭代的代价函数值应该是永远不会增加的,并且是先下降然后收敛到一个稳定值。

然后我们来运行看看代码是否正确,首先初始化一些必要的参数,然后再运行gradientDescent函数:

>> x = [ones(m, 1), data(:,1)]; 
>> theta = zeros(2, 1); 
>> iterations = 1500;
>> alpha = 0.01;
>> theta = gradientDescent(X, y, theta, alpha, iterations); % 运行梯度下降函数

结果如下:

可以看到代价函数值是在慢慢减小的,最终趋于稳定。

再打印一下求出的结果theta:


最后对数据进行可视化:
2.3 可视化代价函数(Visualizing J(θ))

这部分代码已经在ex1.m文件中写好:

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';
figure;
surf(theta0_vals, theta1_vals, J_vals)
xlabel('\theta_0'); ylabel('\theta_1');

figure;
contour(theta0_vals, theta1_vals, J_vals, logspace(-2, 3, 20))
xlabel('\theta_0'); ylabel('\theta_1');
hold on;
plot(theta(1), theta(2), 'rx', 'MarkerSize', 10, 'LineWidth', 2);

运行之后图像如下:

其中左边的是其等高线图,右边的则是其三维图像。

到这里必做部分就已经完成了,下面开始选做的部分,感兴趣的可以继续看下去。最后submit一下结果:


3 多变量线性回归(Linear regression with multiple variables)

在这一部分,我们会使用多变量线性回归来解决房价预测的问题。假设你想要出售你的房子并且想知道定一个怎样的价格才合适,对此,你可以采取收集最近的房屋交易数据,进而构建房屋价格模型。

ex1data2.txt 文件中包含了一系列训练集,其中第一列是房子的尺寸,第二列是卧室的数量,第三列是房子的价格。

3.1 特征归一化(Feature Normalization)

在训练集ex1data2.txt中可以看到,房子的尺寸和房子的卧室数量相差近1000倍,若此时使用特征归一化将特征变量的取值范围减小,可以使得梯度下降算法能够更快地收敛。

首先复习一下特征缩放的公式:


注:其中μn表示某一特征的平均值,sn表示某一特征的标准差(或该特征的最大值与最小值间的差)

根据特征缩放的公式,我们需要补充完整featureNormalize.m文件中的函数:

function [X_norm, mu, sigma] = featureNormalize(X)

X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));

mu = mean(X); % 求平均值,返回一个1x2的矩阵
sigma = std(X); % 求标准差,返回一个1x2的矩阵
X_norm = (X - mu) ./ sigma; % 进行归一化

end

然后我们测试看代码是否正确,首先设置必要的参数,然后执行函数:

>> data = load('ex1data2.txt');
>> X = data(:, 1:2);
>> y = data(:, 3);
>> m = length(y);
>> [X mu sigma] = featureNormalize(X); % 执行特征缩放函数

然后我们打印缩放前后的X矩阵看看:
缩放前

缩放后

可以看到房子尺寸和房子卧室数量已经变成差不多数量级大小。

3.2 梯度下降(Gradient Descent)

多变量线性回归相较于上面的单变量多出了几个特征,相当于矩阵向量多加了几个维度,所以还是可以使用之前写的代码的:

故在 gradientDescentMulti.m 与 computeCostMulti.m 加入之前在单变量线性回归里写的代码即可:

J = sum((X*theta - y).^2) / (2*m); % 计算代价函数
theta = theta -  alpha * (X' * (X * theta - y)) / m; % 更新参数
3.3 正规方程(Normal Equations)

首先是正规方程的公式:

根据公式我们可以写出代码:

theta = pinv( X' * X ) * X' * y;

注:使用正规方程求解theta时,我们可以不用特征缩放。pinv(X)函数可以求伪逆矩阵,而inv(X)函数只能对方阵求逆。

最后submit一下结果:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容