机器学习入门(二)

Octave/Matlab

数据处理

  1. size(A,1)可以输出矩阵A第一维度的大小,也就是m维度(行数)。
  2. size(A,2)能够输出矩阵A第二维度的大小,即n维度(列数)。
  3. length()命令通常对向量使用,对矩阵使用容易造成误解。
  4. 使用who可以查看所有的变量,whos可以查看所有变量的详细信息。
  5. 利用clear+变量名的形式可以清除具体的变量,利用clear直接回车能够清空所有的变量信息。
  6. 使用load X.dat命令能够加载数据到矩阵X中,前提是当前工作目录内包含有X.dat这个文件。
  7. V=Y(2:10)这个命令可以将Y矩阵内第2至第10个变量赋值给V行向量,这里的9条数据指的是纵列的第2至第10条数据。比如Y是一个4*2的矩阵,那么前5条数据就是第一列的4个数据再加上第二列开头第一个数据,最后得到的V是一个行向量。
  8. 将变量保存至硬盘save hello.mat v;这行命令可以把变量v保存到mat文件内,mat文件是用来存储二进制的,即使v变量有大量的数据,mat文件也可能会被压缩的很小。如果想将数据存储成为人类可以理解的形式,可以使用下面的命令save hello.txt v -ascii。

操作数据

  1. A(3,2)能够获得第三行第二列的数据。
  2. A(3,:)表示获得第三行的所有元素。
  3. A(:,2)表示第二列的所有元素。
  4. A([1 3],:)表示得到A中索引为1、3行的所有元素。
  5. Octave中向量、矩阵的索引都是以1开始的
  6. 利用A([1,2,3],[1,2,3])这样的命令可以对矩阵进行任意行,任意列的分割。
  7. 假设v是一个33的矩阵,k是一个13的行向量,那么v=[k;v]的含义是在v的最上面增加一行k,v=[v;k]的含义是在v的最下面增加一行k。
  8. 若j是一个3*1的列向量,那么v=[j,v]的含义就是在v的最左侧增加一列j,同样的在v最右侧增加一列j使用命令v=[v,j],将逗号换成空格也可以,因为空格代表列向量输入,分号代表换行。
  9. A(:)表示将A中所有的元素放在一个列向量中。
  10. A.*B的意思是将A与B对应的元素一一相乘(矩阵需要同型才行)。
  11. A.^2表示对A矩阵内所有的元素进行乘方。
    12.** 可以将“.”符号理解为针对元素进行的运算。**
  12. log(x),x可以是向量、矩阵、单元素变量,实际计算过程中是以e为底进行对数运算的
  13. exp(x),x可以是向量、矩阵、单元素变量,计算过程中是以e为底进行的指数运算
  14. 将向量v内每个元素都增加1的方法如下,ones(2,3)能够生成一个2行3列的矩阵(元素全都是1)。
v+ones(length(v),1)
  1. 可以利用find(a<3)函数来返回a矩阵内所有小于3的元素,返回的结果是列向量。
  2. magic函数能够返回幻方矩阵,任意行、列对角线中的元素加在一起都等于一样的值。
  3. [r,c]=find(A>=7)这里的r和c分别表示行索引和列索引,r与c的第i对元素就是第i各满足A>=7条件的元素坐标。
  4. sum(a)会对a内所有的元素进行求和。
  5. prod(a)会对a内所有的元素进行乘积。
  6. floor(a)会对a内所有的元素进行向下取整。
  7. ceil(a)会对a内所有的元素进行向上取整。
  8. rand(3)能够返回一个3*3的随机矩阵。
  9. max(rand(3),rand(3))能够取得两个rand中比较大的元素组成的矩阵。
  10. max(A,[],1)能够得到每一列的最大值,这里的1指的是用第1维度去取值,也就是说把每一列的最大值存储在一个行向量内。如果把1换成2的话,那么就是用第二维度去取值,也就是max(A,[],2)能够获得每一行的最大值,最后的结果是一个列向量
  11. max(max(A))可以获得矩阵内最大的元素,也可以使用max(A(😃)。
  12. sum(A,1)表示对矩阵内每一列进行求和,最后放在一个行量内。
  13. sum(A,2)表示对每一行进行求和,最后放在一个列向量内。
  14. 求矩阵对角线的和
sum(sum(eye(3).*A))
  1. 对矩阵的副对角线求和,需要使用垂直翻转命令flipud
sum(sum(A.*flipud(eye(3))))
  1. pinv是求解伪逆的命令,A*pinv(A)的主对角线上的元素都约等于1,除了主对角线上的元素外,其余部分都可以看为0。

绘图

  1. plot(x,y),其中y是因变量,x是自变量。
  2. xlabel('time')能够给x轴增加标签
  3. legend('sin','cos')能够增加图例
  4. print -dpng ‘name.png’可以保存图像到本地
  5. close命令能够直接关闭图像。
  6. figure(1)可以增加一个图像窗口(窗口名称是Figure 1)
  7. subplot(1,2,1)命令的含义是将图像分为两个格子(前两个参数1*2是矩阵的长宽,第三个参数是表示使用Figure 1窗口)
  8. axis([0.5 1 -1 1])可以将图中横轴区间设置成0.51,纵轴区间设置成-11
  9. clf命令可以清空一个figure图像
  10. imagesc(A)命令能够生成矩阵对应的色块图像。
  11. imagesc(),colorbar,colormap gray;三个命令同时运行,能够生成一个灰度图像,事实上使用逗号连接三个命令就是让这三个命令一次执行而已。

语句与函数

for循环、while循环、if判断如下:

for i=1:10,
  v(i)=2^i;
end;

while i<5,
  v(i)=100;
  i=i+1;
end;

while true,
  v(i)=999;
  i=i+1;
  if i==6,
    break;
  end;
end;

函数定义

function J=costFunctionJ(X,y,theta)
%X is the design matrix containing our training examples.
%y is the class labels
m=size(X,1);
predictions=X*theta;
sqrErrors=(predictions-y).^2;

J=1/(2*m)*sum(sqrErrors);

向量化

# 实现线性回归

代码样例下载

数据加载

fprintf('Loading data ...\n');
data = load('ex1data2.txt');
X = data(:, 1:2);   % X为特征矩阵
y = data(:, 3);     % y为样本结果
m = length(y);      % m为样本的个数
fprintf('Data loaded successfully\n');

特征缩放与均值归一化

在主函数调用处理特征的函数:

[X mu sigma] = featureNormalize(X);
X = [ones(m, 1) X];%% Add intercept term to X(可以理解为增加了截距项)

特征处理函数如下:

function [X_norm, mu, sigma] = featureNormalize(X)
X_norm = X;                    % X_norm是最后处理好的特征矩阵
mu = zeros(1, size(X, 2));     % mu是一个记录了每个特征均值的行向量
sigma = zeros(1, size(X, 2));  % sigma是一个记录了每个特征标准差的行向量

mu=sum(X)/size(X,1);
sigma=sqrt(sum((X-mu).^2)/size(X,1));
X_norm=(X-mu)./sigma;

end

梯度下降

主函数

fprintf('Running gradient descent ...\n');
% 设置学习率和迭代次数
alpha =0.1;
num_iters = 50;
% 初始化模型参数,由于样本有两个特征,所以需要利用一个3维度的列向量
theta = zeros(3, 1);
% 梯度下降寻找最优的theta,并返回迭代过程中的历史代价值
[theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters);

% 绘制梯度下降图像
figure;
plot(1:numel(J_history), J_history, '-b', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('代价值');

梯度下降函数

function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)

m = length(y);                         % 样本数目
J_history = zeros(num_iters, 1);       % 初始化历史代价值,设置其大小为迭代次数即可

% 开始迭代
for iter = 1:num_iters
    predictions=X*theta;            % 预测值,此预测值与三个参数都有关系,所以需要对这些参数进行同步更新
    temp=zeros(size(theta,1),1);    % 临时存储theta参数,用于同步更新

    for i = 1:size(theta,1)
        temp(i)=theta(i,1)-(1/m)*alpha*sum((predictions-y).*(X(:,i))); % 这里将会在下面详细的说明
    end

    theta=temp; 
    J_history(iter) = computeCostMulti(X, y, theta);                   % 存储当前theta下的代价

end
end

代价函数

function J = computeCostMulti(X, y, theta)
m = length(y); % 样本数目
J = 0;         % 初始化代价值

predictions=X*theta;               % 利用theta得到的预测结果
sqrErrors=(predictions-y).^2;      % 平方差集合
J=1/(2*m)*sum(sqrErrors);          % 计算代价

end

解释

temp(i)=theta(i,1)-(1/m)alphasum((predictions-y).*(X(:,i)));
下面是梯度下降的普适公式:

\[\theta_j:=\theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta_0,\theta_1) \]

假设一个模型样本如下:

(截距项) 房子面积 卧室数量 价格
1 2104 5 460
1 1416 3 323
1 1534 3 315
1 852 2 178
假设现在的偏导项是对theta_1进行求导,那么h(theta)-y是一个实数,x也是一个实数,唉算了明天再写。
posted @ 2021-01-29 21:01  mirage_mc  阅读(161)  评论(0编辑  收藏  举报