基础知识:
- 矩阵乘法不满足交换律,但满足结合律 ,分配率。
- 有的矩阵不可逆。
第一章
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 颜色变灰 控制语句 for: for 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:UseraofengDesktop')可以增加搜索路径 (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