前言
这一章还是紧接上一章的内容,在上一章,我们详细地讨论了关于一个变量的线性回归问题,而在我们的实际问题中,一般都不止一个变量,就比如上一章讨论的预测房价问题,房价不仅只跟房子的大小有关,还跟它有几间房间,几层楼等等有关,所以我们需要涉及到的是多元变量的问题,在这一章,我讲详细地给大家介绍多元变量地线性回归问题。
最后还是那句话,如果内容有什么错误的理解,希望大家不吝赐教,指正,谢谢!
第三章 多元的线性回归问题
3.1 多元变量和单个变量的异同
在前面,我们讨论的问题如图1所示,我们对它做出假设h(x)=
图1 Price只和Size有关
而现在我们需要讨论的问题如图2所示,这个时候price不仅只和size有关,而和其他因素有关,所以之前我们用来假设的h(x)=就不对,这个时候我们需要重新定义一个h(x)=,在这个表达式中,我们定义,则h(x)=,我们用矩阵的形式来重新整理下这个表达式,,,,这个时候问题就简单化了,我们把看作一个整体,就是一个(n+1)*1维的一个矩阵变量,所以上式的变量就是一个,还有之前我们需要讨论的Cost Function(代价函数):J()=
即J()=,Gradient descent: (simultaneously update ,for j=0,1,2,...,n),即,注意=1。
3.2 Feature Scaling(特征的缩放)
理想的情况下,我们是希望每个feature都是在同一个scale,而实际中例如:x1=size (0-2000 feet^2),x2=number of bedrooms (1-5),这个时候J()如图2所示,收敛会比较慢。关于这个原因是因为当一个特征的范围比较大时,在这个特征求的梯度会很小,而学习速率因为受其他特征的约束不能设太大,所以导致J()收敛的速度会比较慢。
图2 不做处理的J()下降趋势
而我们如果做一下处理,进行比例的缩放,例如:,,这个时候0<=x1<=1,0<=x2<=1,即x1、x2在同一个范围内了,这个时候J()的收敛趋势可能是如图3所示,收敛会比较快,不会走很多的折线。
图3 经过处理后的J()
我们所希望的是让每个feature都大约在-1<=xi<=1范围内,x0=1所以不需要处理,但是其实“1”这个值并不是绝对的,我们对数据进行放缩的目的是让数据的取值范围尽量保证在一个接近的范围内,但也不一定要相同,比如:x1:0~3、x2:-2~0.5等等也都是可以的,不会很大程度上影响J()的收敛程度,但是如果有x3:-100~100、x4:-0.0001~0.0001,这个时候,就是不行的,这范围相差太大,就会有影响了。
下面给大家介绍一个更加靠谱的缩放方法:Mean normalization(均值归一化),,即每个特征的平均值,s即特征值的最大值减去最小值,例如,,这个时候-0.5<=x1<=0.5,-0.5<=x2<=0.5。
3.3 Learning rate(学习速率)
Gradient descent:,和前一章问题一样,怎样来选择的大小,使J()减小的速度尽量快并收敛到最小值。当比较小时,J()通过多次的迭代会不断减小,最终减小到一个很小值,但太小,减小速度也是比较慢;当太大时,J()通过多次的迭代可能不会减小反而增大,如图4所示。
图4 当太大时
3.4 Features and polynomial regression(特征与多项式回归)
对于房子的价格预测问题,h(x)=0+1*frontage+2*depth,这个时候我们引入了两个变量frontage、depth,而我们在实际中可以用size=frontage*depth来代替两个变量,这个时候h(x)=0+1*size,问题就会变得简单,根据价格price(y)和size(x)的关系,如图5所示,在前面的介绍中,我们一直都是在用线性关系来描述y和x的关系,但是从这个图中可以看出,用线性关系来描述显然是不够准确的,从图像前面的走向似乎是一个二次函数,不妨我们设h(x)=0+1*x+2*x^2,但是二次函数是一个关于对称轴对称的图形,表明到了后面,会是下降的趋势,而根据实际情况可知,price是不会下降的,所以我们可以猜想h(x)=0+1*x+2*x^2+3*x^3,这个时候若令h(x)=0+1*x+2*x^2+3*x^3=0+1*(size)+2*(size)^2+3*(size)^3,所以x1=(size)、x2=(size)^2、x3=(size)^3,而似乎我们还有另外一个更好的函数关系来描述两者的关系:h(x)=0+1*(size)+2*等等,想告诉大家的是在选择函数时,是不止有线性关系可以考虑的,还有其他的函数关系可以考虑,可能比线性关系更接近实际关系。
图5 price(y)和size(x)的关系
3.5 Normal equation(标准方程)
回到最初的问题,我们的目的是寻找使J()最小时的值,如图6所示。
图6 J()和的关系
如果我们令J()=a*^2+b*+c,找到使J()最小,即当时的值,而对于J()=,令 (for every j),去找到0,1,...,n。
下面用一个实际的例子来向大家介绍的求法,如图7所示。
图7 当m=4时,每个y所对应的不同x
,至于关于这个式子的数学推到,大家可以只做了解,不需要深入地探究。
J()=J()==,再对J()关于求导并令其为0,即可求出对应的,值得注意的是()必须是可逆矩阵,即每个特征都是相互独立的,没有多余的特征。
以上就是关于的另一个求法,注意X矩阵的写法,增加了第一列都是1,这是为了对后面做运算相匹配。那么问题就来了,对于前面我们介绍了通过迭代来求出,现在又有这个公式可以一步求出,那到底哪一个对于求比较好了,或者哪种情况该用哪一个?
答:关于这个的计算比较方便容易的,不需要选择(learning rate),而而前面所介绍的Gradient Descent需要选择,而这个是不好掌控的,但是不是任何时候选择Normal Equation都是最好的了?答案是否定的,因为当数据量很大时,关于求()的逆是很消耗计算机的时间的,所以我们大致有一个评判标准,当n=10000多时,我们就选择Gradient Descent而当n小于这个值时,我们就果断地选择Normal Equation。
在以上的讨论中,我们所得到的公式是:,而上面也提到了使用这个公式时的前提就是()要求可逆,但如果不可逆,则怎么办了?而前面也说了,不可逆即存在多余的特征,我们要做的就是去除多余的特征,使特征都是相互独立的再进行计算。
最后想跟大家说一下如何用matlab来计算这个式子,直接输入=inv(X'X)*(X')*y即可,注意X'即求X的转置。