机器学习笔记(一)线性回归

基础知识:

  1. 矩阵乘法不满足交换律,但满足结合律 ,分配率。
  2. 有的矩阵不可逆。

 

第一章

1.监督学习:指的是通过分析一些实际的例子的特性,来预测一些新的问题。 (比如线性回归,分类)
2.无监督学习:给出数据,但不告诉数据的信息,进行聚类

3.开发环境Octave

第二章,线性回归(两种解法)

设函数为:      

Cost Function:  

%octave代码实现Cost function
function J = computeCost(X, y, theta)
    m = length(y);
    J = 0;
    predictions=X*theta;
    sqrError=(predictions-y) .^ 2;
    J=sum(sqrError)/(2*m);
end

 

Goal:        

方法:        

%octave代码实现一元线性求theta
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

    m = length(y); % number of training examples
    J_history = zeros(num_iters, 1);

    for iter = 1:num_iters    %同步操作
        temp1=theta(1)-(alpha/m)*sum((X*theta-y) .* X(:,1));
        temp2=theta(2)-(alpha/m)*sum((X*theta-y) .* X(:,2));
        theta(1)=temp1;
        theta(2)=temp2;
        J_history(iter) = computeCost(X, y, theta);
    end
end

 

1.梯度下降法:从这一点环顾四周,判断向哪里走是到达最低点的方向,然后不断走(可能会出现局部最优解,而不是整体最优解,就是不同的初值得到不同的结果)(同步更新)
2.特征缩放:当两个参数相差太大时,梯度下降法会使下降轨迹左右摇摆,效率很慢。将所有参数除以它的范围(最大值-最小值),使它在0<=Xi<=1,这样的话在数学上可以证明会更快地得到结果。一般都是除以标准差std(X)。

注意只要它的范围不要太大,也不要太小就可以,比如[-2,0.5],[-3,0],一般情况下范围最大不大于[-3,3],最小不小于[-1/3,1/3]就可以接受。而[-0.002,0.002]就太小了!

3.归一化:将每个参数用,Xi-平均值来代替,这样它就正好在0的左右两边(如果本来就是在左右两边就不需要了),如果再加上特征缩放的话-0.5<=Xi<=0.5。

4.通过查看代价函数的值,来确定是否运行正确,如果变大了说明应该减小α(学习速率)。

5.合理选择因素,会有更好的效果。α的选择,按照3的倍数增减(0.3,0.1,0.03,0.01)

6.合理的选择模型,(多项式回归可以转化为线性回归,如下:因为只要求出θi就可以了)

 

7.非梯度下降法:正规方程

就是令所有的偏导数等于0,然后解方程就可以求得θi。

公式推导:

(X * A -Y)' * X=0('表转置矩阵)

先转置一下X'(XA-Y)=0
移项X'XA=X'Y
在X'X可逆的条件下乘一下逆矩阵就行了

 

8.不可逆的情况

  • 某一列(行)是另一列(行)的倍数,即多余的。(删除)
  • 当数据量小于特征变量时。(合并某些特征变量)

Octave里的伪逆函数pinv()可以无视这种情况,依然正确。

9.对比:

梯度下降法

缺点:

  • 要尝试α,找一个合适的,额外的开销
  • 效率低,需要迭代下降

优点:

  • 在有很多特征变量是也能运行的很好

正规方程

缺点:

矩阵乘法复杂度是n^3,当n在百的级别时没有问题,但再大的话效率就很慢。

总结:n小时,优先使用正规方程。

10.向量化:将求和转化成向量相乘,相应的扩展

 

代码:

归一化和特征缩放:

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);%每一列平均差
    sigma=std(X);%每一列标准差

    for i=1:size(X,1)
    X_norm(i,:)=(X(i,:)-mu) ./ sigma;%必须在加上X的第一列(全是1,标准差是0)之前调用,否则会除0
    end
end

多元cost function:

function J = computeCostMulti(X, y, theta)
    m = length(y); % number of training examples
    J = 0;

    predictions=X*theta;
    sqrError=(predictions-y)' *(predictions-y);
    J=sqrError/(2*m);
end

 

求多元theta:

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

    m = length(y); % number of training examples
    J_history = zeros(num_iters, 1);

    for iter = 1:num_iters
        temp=zeros(size(theta,1),size(theta,2));
        for j=1:size(theta,1)
            temp(j,1)=theta(j)-(alpha/m)*sum((X*theta-y) .* X(:,j));
        end
        theta=temp;

%     theta=theta-(alpha/m)*(((X*theta-y)' * X)');%可以用这一句话代替,向量化

J_history(iter)
= computeCostMulti(X, y, theta); end end

 正规方程解法:

function [theta] = normalEqn(X, y)

        theta = zeros(size(X, 2), 1);    
        theta=pinv(X' * X)* X' * y;
end

 

附:octave的操作

 

基本操作
%注释

~=不等于//!=不对

xor(a,b)异或//逻辑操作,只算第一位

PS1('>>' )修改前导

;语句后面加;表示不输出本条语句的操作

disp(a)输出a

disp(sprintf('ssdssdsfd %0.2f' ,1.234435))其中sprintf返回字符串

format long可以存更多的位

format short存的位不多

a=[1,2;3,5]矩阵

a=[1,2,3]向量

v=1:0.2:2表示v是一串数从1到2,步长为0.2

v=1:5表示v是一串数从1到5,默认步长为1

ones(2,3)表2*3的矩阵,元素都是1

zeros(2,3)同上

rand(2,3)同上,元素随机[0,1]之间

hist(a)输出a的柱状图

hist(a,10)输出a的柱状图分成10分

eye(n)表n*n的单位矩阵

help 命令//表示查看命令的帮助

size(A)返回矩阵的行列,用1*2的矩阵表示

size(A,1)行

size(A,2)列

length(B)求矩阵最大维度的长度

pwd查看默认路径//支持linux命令

who查看所有定义的变量//whos详细显示信息

load 文件名//加载文件

clear变量名//删除变量

clear //删除所有变量

v=a(2:4)//v等于由a(变量名)的第2到4行所有首元素组成的1*3的矩阵

save save.txt a//表示将a存到save.txt文件中

A(1,3)返回1行3列的元素

A(2,:)//:表示行或者列的所有元素

A([1,3],:)//第1,3行的所有元素

a1(:,2)=[100,109,199]赋值

a1=[a1,[1;2;3]]增加一列

 a1(:)返回所有元素,每个元素是一列

a=[a1 a2]将两个矩阵合来,左右两边

a=[a1;a2]上下两边

复杂计算
a*b矩阵相乘

a .* b//a,b的相应元素相乘

a .^ 2//a的每个元素平方
./ a//a每个元素的倒数

log(v),exp(v)//都是关于e的

abs(a),max(a)(矩阵的话,每一列返回一个最大值),find(a<3)(返回那个元

素true),sum(a),floor,……

max(a,[],1)//表示每一列的最大值;max(a,[],2)//表示每一行的最大值;

max(max(a))//所有的,sin,

a'表示a的转置

pinv(a)矩阵的逆

flipud(eye(4))flipud表示反转


绘图
plot(x,y)//x,y分别表示向量

 plot(t,v,'r')//'r'表示红色

title('myfirst')主题
xlabel('x')//x坐标
ylabel('y')//y坐标

legend('cos','sin')图例

close在命令行关闭图

figure(1);plot(x,y)//表示不同的图

subplot(m,n,p)//m表示是图排成m行,n表示图排成n列,也就是整个figure

中有n个图是排成一行的,一共m行,如果m=2就是表示2行图。p表示图所在的位

置,p=1表示从左到右从上到下的第一个位置。

axis([0 1 2 3])表明图线的x轴范围为0~1y轴范围为2~3

clf清理图像

imagesc(a)用颜色将矩阵可视化;colorbar显示颜色对应的值;colormap gray

颜色变灰

控制语句
forfor i=1:10

disp(v(i))//v[i]是不对的

end

while:

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

if:

if x==1
disp(1)
elseif x==2
disp(2)
else
disp(3)
end

函数使用:
在当前路径下定义一个文件(默认只搜索当前路径),名为文件内函数名.m

比如:

(1)

squareThisNumber.m文件

文件内容:

function y=squareThisNumber(x)
y=x^2;
返回值是y,参数是x

注意:addpath('e:\User\baofeng\Desktop')可以增加搜索路径

(2)返回多个值的函数

function [y1,y2]=squareAndCube(x)
y1=x^2;
y2=x^3;

xplot=linspace(-10,10,5)//表示-10到10之间生成5个数,成等差数列,存储在变量xplot中

surf(X,Y,Z)// 当x = 1:n、y = 1:m,并且[m,n]=size(Z)时画三维有色图。

contour(X,Y,Z)// 当x = 1:n、y = 1:m,并且[m,n]=size(Z)时画等高线绘制函数。
 c=[a;b]//表示a在上,b在下,即a,b的列要一样
 c=[a,b]//表示a在左,b在右,即a,b的行要一样

c=[a(:),b(:)]//表示先将a,b变为列向量,且合在一起赋值给c

 

posted @ 2014-11-05 11:40  baoff  阅读(674)  评论(0编辑  收藏  举报