2d用法 matlab_吴恩达机器学习ex1(Matlab版)

基本练习

简单的MATLAB函数

A = eye(5)

输出:

A =     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

一个值的线性回归

目标:实现一个单值的线性回归来预测一条食品链的利润。

ex1data1.txt 包含了本次实验所用的数据集,第一列是城市人口,第二列是利润(负数表示亏损)。

画出数据

ef72c6d04677c7fce1e3b5d4a314f8b1.png

上图表示的是ex1data1.txt中的样例,第一列表示样例的特征值,第二列表示样例的结果

开始任务之前,先对数据进行可视化是十分必要的。

鉴于数据只有两维,我们先用一个散点图来观察

加载数据:

data = load('ex1data1.txt'); % read comma separated dataX = data(:, 1); y = data(:, 2);m = length(y);

图中部分命令解释:data = load(‘ex1data1.txt’):表示将ex1data1.txt中的数据以矩阵的形式存放在变量data中X = data(:,2):表示将data中的第一列的全部的数据存放在X.

data 是一个矩阵

data(x,y) x是行数 y是列数

data(:,y)就是指y列对应的所有行的值组成的一个向量

data(:,[y1:y2]) 就是指y1到y2列的对应的所有行的值组成的一个矩阵

此外 data(:,[y1:y2])与data(:,y1:y2)结果是一样的

因为y1:y2 默认为向量

例:

data=[1 2 3

          4 5 6

          7 8 9];

data(1,2)=2

data(:,2)=[2

                     5

                    8];

data(:,[2:3])=[2 3

                          5 6

                          7 8];

m = length(y):length()函数表示求取vector的长度,如何函数中的参数为矩阵,则只会求矩阵有多少列

使用下列语句来画图:

plot(x, y, 'rx', 'MarkerSize', 10); % Plot the dataylabel('Profit in $10,000s'); % Set the y−axis labelxlabel('Population of City in 10,000s'); % Set the x−axis label

图中部分命令解释:

plot():表示绘制一个2D图像,前两个参数X,Y的数据分别对应到2D图像中X和Y轴上的数据,rx中r表示使用red颜色,x表示以 ‘X’ 标志绘制点,‘MarkerSize’ 10 表示将点的大小设置为10ylabel(‘Profit in $10000s’):表示在y轴附上说明

bb8396cbd6999fd8fb30f6e083fd50b4.png

梯度下降

使用梯度下降来调整参数求出最佳的theta,使得代价函数J的值最小。

更新等式

注意,初学者容易把i和j搞混淆。

i 表示样本个数编号,j 表示特征个数编号(也就是上面的m)

样本特征:X = [1, x1, x2, …, xj, …, xN]

样本特征权重:θ = [1, θ1, θ2, …, θj, …, θN]

1、computeCost()用于计算代价函数J

根据ex1data1.txt对应的样例,我们设置hypothesis函数为:

6bcd3bb3a111c0d428f5f99240f31ccb.png

代价函数为:

72715744d17e2f2d5c88326705c7e216.png

J(θ) = sum[(hθi-yi)^2]/2m     = sum{[sum(xj*θj)i-yi]^2}/2m

以及,θj的每次迭代函数:

θj = θj - alpha*[dJ(θ)/dθj]   = θj - alpha*sum[(hθi-yi)*xj]/m

部分命令解释:5062451140c7a3773fb8319f6ffcf503.png

(模块化函数)【运行脚本】

% Initialize some useful valuesm = length(y); % number of training examples% You need to return the following variables correctly J = 0;% ====================== YOUR CODE HERE ======================% Instructions: Compute the cost of a particular choice of theta%               You should set J to the cost.J = sum((X * theta - y).^2) / (2*m);     % X(79,2)  theta(2,1)

(X * thera - Y) .^2中的 .^2表示矩阵对应的每一个数都取平方值
sum():表示对矩阵中的每一个数求和

实现

X = [ones(m, 1), data(:,1)]; % Add a column of ones to xtheta = zeros(2, 1);         % initialize fitting parametersiterations = 1500;           %迭代次数alpha = 0.01;

运行如下语句:

computeCost(X, y, theta)

可以看到有输出:

32.07

2、gradientDescent.m:用梯度下降的方法求最佳的theta值,使代价函数的值最小

利用梯度下降求theta的公式如下:

3979a209d28faaa36d1f25c384b05bd0.png

对theta求偏导数的过程如下:

da999b207d18313db4da3d5f5b0913c7.png

在 gradientDescent.m实现代码:(模块化函数)【运行脚本】
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)%GRADIENTDESCENT Performs gradient descent to learn theta%   theta = GRADIENTDESENT(X, y, theta, alpha, num_iters) updates theta by %   taking num_iters gradient steps with learning rate alpha迭代次数% Initialize some useful valuesm = length(y); % number of training examplesJ_history = zeros(num_iters, 1);theta_s=theta;for iter = 1:num_iters    % ====================== YOUR CODE HERE ======================    % Instructions: Perform a single gradient step on the parameter vector    %               theta.     %    % Hint: While debugging, it can be useful to print out the values    %       of the cost function (computeCost) and gradient here.    %    theta(1) = theta(1) - alpha / m * sum(X * theta_s - y);           theta(2) = theta(2) - alpha / m * sum((X * theta_s - y) .* X(:,2));        theta_s=theta;     % ============================================================    % Save the cost J in every iteration        J_history(iter) = computeCost(X, y, theta);endJ_historyend

J(θ)应该会随着迭代的进行逐渐收敛到一个最小值(相对)。

最终得到的θ :

-3.630291 1.166362
根据这个θ画出线性拟合图,进行观察:
plot(X(:,2), X*theta, '-')legend('Training data', 'Linear regression')

5861c0fa5ca989db8bbcdae001cd9dc9.png

3.可视化J(θ)

为了对代价函数J(θ)有一个更深刻的认识,接下来将画出θ的二维网状图上的J(θ)分布(一个三维图)。

初始化

theta0_vals = linspace(-10, 10, 100);theta1_vals = linspace(-1, 4, 100);J_vals = zeros(length(theta0_vals), length(theta1_vals));

linspace生成线性间距向量查阅:

用法:linspace(x1,x2,N),其中x1、x2、N分别为起始值、中止值、元素个数。若缺省N,默认点数为100

栗子1:
X=linspace(1,100)

产生从1到100步长为1的数组。类似于在命令窗口中输入:

X=[1:1:100]


栗子2:
在命令窗口中输入:

X=linspace(5,100,20) % 5到100,总共输出20个数,则步长为5
结果为:
5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100

等价于:
X=[5:5:100]

初始化:
theta0_vals = linspace(-10, 10, 100);theta1_vals = linspace(-1, 4, 100);J_vals = zeros(length(theta0_vals), length(theta1_vals));
计算在每个点θ处的J(θ)值:
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);    endend
画出表面图和等高线图:
% Because of the way meshgrids work in the surf command, we need to % transpose J_vals before calling surf, or else the axes will be flippedJ_vals = J_vals';% Surface plotfigure;surf(theta0_vals, theta1_vals, J_vals)xlabel('\theta_0'); ylabel('\theta_1');% Contour plot%figure;hold on;% Plot J_vals as 15 contours spaced logarithmically between 0.01 and 100contour(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', 10);

surf():绘制3D图像,theta0,theta1分别表示第一和第二个参数,J_val表示此时参数对应的代价函数值

代价函数J随参数theta变化的等高线图像:contour():用于绘制等高线图像

logspace(a,b,n):生成n个点,在10^a 和 10^b之间

295717b173f058e83dde696c01bb6e49.png

f6904ae3489054b325e0cf4c030da968.png

额外练习

简述:实现多元线性回归。

实现一个多值线性回归来预测房子价格。

文件ex1data2.txt包含了本次练习所用的数据集。

第1步:加载数据文件;

%% Clear and Close Figuresclear ; close all; clcfprintf('Loading data ...\n');%% Load Datadata = load('ex1data2.txt');X = data(:, 1:2);y = data(:, 3);m = length(y);% Print out some data pointsfprintf('First 10 examples from the dataset: \n');fprintf(' x = [%.0f %.0f], y = %.0f \n', [X(1:10,:) y(1:10,:)]')

1、fprintf函数:将数据按指定格式写入到文本文件中。

2、用法说明:
fprintf(fid, format, variables);
按指定的格式将变量的值输出到屏幕或指定文件;

fid为文件句柄,指定要写入数据的文件,若缺省,则输出到屏幕;

format是用来控制所写数据格式的格式符, format用来指定数据输出时采用的格式:
%d 整数
%e 实数:科学计算法形式
%f 实数:小数形式
%g 由系统自动选取上述两种格式之一
%s 输出字符串

variables是用来存放数据的矩阵

特征归一化

第2步:均值归一化featureNormalize函数实现;

此部分主要是对示例的特征值进行特征收缩处理,使用的场景:当示例中的特征值相差的级别较大时,此时会导致梯度下降算法收敛的速度过于缓慢,比如下图中的数据,此时前两列为特征值,特征值1的数量级为10^ 3,而特征值2的数量级为10^1,此时就会造成梯度下降的速度过于缓慢,可以采用特征收缩的方法使其特征尺度都尽量收缩到[-1,1]之间。

标准差是一种用来衡量某个特征的值的离散分布的方式。

注意要将所得的均值和标准差保存起来,以便在给出一个测试数据时,将其标准化。

特征收缩的公式:

6b539cb98ed612166fee943d9bd5d10e.png

在 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,1);sigma = std(X,0,1);X_norm = (X_norm-mu)./sigma; end
repmat(mu,size(X,1):将实数mu变成变成m行n列的向量,因为此时X为m行1l列的向量,正好对应。
[X mu sigma] = featureNormalize(X);      % 均值0,标准差1% Add intercept term to XX = [ones(m, 1) X];

梯度下降

第3步:使用梯度下降函数计算局部最优解,并显示线性回归;

此部分主要是根据经过 特征收缩之后的特征值利用梯度下降的方法来求出最佳的  θ \thetaθ值,同时,此部分利用  plot函数画出代价函数 J随迭次次数增加的变化曲线图,根据此曲线图,可以判断梯度下降的公式是否正确

与之前唯一的区别就是,本次有多个特征。假设函数和批梯度下降的更新规则都是一样的。

由于是多值线性回归,对θ的计算从之前的向量运算转换成矩阵运算

d2bcb3cb122080df20ce669a377ce680.png

theta = theta - alpha / m * X' * (X * theta - y);

初始化参数:

% Choose some alpha valuealpha = 0.01;num_iters = 8500;% Init Theta and Run Gradient Descenttheta = zeros(3, 1);[theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters); % Plot the convergence graphfigure;plot(1:numel(J_history), J_history, '-b', 'LineWidth', 2);xlabel('Number of iterations');ylabel('Cost J');

第4步:实现梯度下降gradientDescentMulti函数;

function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters) m = length(y); % number of training examplesJ_history = zeros(num_iters, 1); for iter = 1:num_iters    theta = theta - alpha/m*(X'*(X*theta-y));    % Save the cost J in every iteration       J_history(iter) = computeCostMulti(X, y, theta);end end 

第5步:实现代价计算computeCostMulti函数;

function J = computeCostMulti(X, y, theta)m = length(y); % number of training examplesJ = 1/(2*m)*sum((X*theta-y).^2);%J=(X*theta-y)'*(X*theta-y)/(2*m);end

8c089ffd7d9941b69d4bbdd0b8499d53.png

第6步:使用上述结果对“the price of a 1650 sq-ft, 3 br house”进行预测;

X1 = [1,1650,3];X1(2:3) = (X1(2:3)-mu)./sigma;price = X1*theta;

预测结果:

8c078776ca97fc6c02da24d124d4a88b.png

第7步:使用正规方程法求解;

%%Load Datadata = csvread('ex1data2.txt');X = data(:, 1:2);y = data(:, 3);m = length(y); % Add intercept term to XX = [ones(m, 1) X]; % Calculate the parameters from the normal equationtheta = normalEqn(X, y);

第8步:实现normalEqn函数;

function [theta] = normalEqn(X, y)theta = zeros(size(X, 2), 1);theta = (X'*X)^(-1)*X'*y;end

第9步:使用上述结果对“the price of a 1650 sq-ft, 3 br house”再次进行预测;

1

price = [1,1650,3]*theta;

预测结果:(与梯度下降法结果很接近)

89c0a3e8de74c6650d75fd6cb7e1a5c8.png

正规方程如下:24837fcb04a12f710f87cf4c21fcb2b6.png

上述公式的推导这位大佬已给出:https://zhuanlan.zhihu.com/p/22757336

1、normalEqn():

12b05b88a07cc25d0797d8a1dcd023e4.png

正规方程与梯度下降的比较

梯度下降正规方程
需要选择适合的学习率α \alphaα不需要
需要进行多次迭代一次运算便可得出
当特征数量n较大时也能很好的适用需要计算( x T x ) − 1−1,当特征值n较大时,运算代价过大,因为矩阵逆的计算时间复杂度为 O ( n 3 ) ,通常n小于10000时可以使用
适合于各种类型的模型只适用于线性模型,不适用于逻辑回归模型等其他模型
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值