Python Logistic回归--抛去复杂公式的简单理解

来源:互联网 发布:优秀的短篇小说知乎 编辑:程序博客网 时间:2024/06/05 05:47
def gradAscent(dataMat,classLabels):    dataMatrix = np.mat(dataMat)    labelMat = np.mat(classLabels).transpose()    m,n = np.shape(dataMatrix)    #100,3    alpha = 0.001    maxCycles = 500    weights = np.ones((n,1))    for k in range(1):        h = sigmoid(dataMatrix*weights)        error = (labelMat - h)        #我们的目的是最小化这个error        weights = weights + alpha*(dataMatrix.transpose()*error)        ##括号里的计算过程:[[1,1,1,1,...] [x1,x2,x3,x4...x100] [y1,y2,y3,y4..,y100]] *[[e1],[e2]..[e100]]--> [[1*e1+1*e2+..1*e100] [x1*e1+x2*e2+..x100*e100] [y1*e1+y2*e2+..y100*e100]]    return weights

第一点:矩阵A的列必须等于B的行才能做乘法
矩阵乘法A[100,3]*B[3,1] 得到C[A的行数,B的列数]
C的m行n列的值是『(A的m行)*(B的n列)』的和

第二点:特征数据有两个特征X1,X2,为什么要加一个X0且默认都为1? 因为线性回归方程(y=a*X+b )不仅要给自变量(即特征值)寻找回归系数,还要寻找常数来适配回归方程,X0选择1就是为了计算方便,不要选择0就行

第三点: weights = weights + alpha*(dataMatrix.transpose()*error)

《机器学习实战》中说省略了一个简单的计算过程(并不简单),其实是省略了解释dataMatrix.transpose()*error 的意义,这个乘式表示“梯度”,(就是在某点的导数值,变化率,对于线性函数就是斜率,对于自变量多维的是一个向量)决定了weights的调整方向和大小,可以去除alpha理解:weights = weights +(dataMatrix.transpose()*error) ,而alpha是为了让 weights调整大小更细化,如果每一下都改变太大,那循环多少次也都没什么意义了。核心问题就是梯度为什么这么计算?

统计学原理:首先如果我们有一个以系数weight为对象的目标函数f(w),而这个函数表示的是不一样的系数使得现象(数据集)发生的概率,因为现象已经发生,自然让概率越大的w系数越是合理的,(似然函数的一系列知识,条件和结果的一种互换),转化为对f(w)的求极大值,决定了我们需要选择梯度上升算法(而不是下降),以下是目标函数f(w)的推导:
http://blog.csdn.net/whai362/article/details/51860379

这里是直观的感受:

给定一个样本集,每个样本点有两个维度值(X1,X2)和一个类别值,类别只有两类,我们以0和1代表。数据如下所示:样本  X1  X2  类别1   -1.4    4.7 12   -2.5    6.9 0... ... ... ...机器学习的任务是找一个函数,给定一个数据两个维度的值,该函数能够预测其属于类别1的概率。假设这个函数的模样如下:h(x) =sigmoid(z)z = w0 +w1*X1+w2*X2问题转化成了,根据现有的样本数据,找出最佳的参数w(w0,w1,w2)的值迭代找出最佳的w为进一步简化问题,我们假设样本集只有上表中的两个。假设现在手上已经有一个wt,也就是有了一个函数h(x),那么我们可以把样本1和样本2的数据代进去,看看这个函数的预测效果如何,假设样本1的预测值是p1 = 0.8,样本2的预测值是:p2 = 0.4。函数在样本1上犯的错误为e1=(1-0.8)= 0.2,在样本2上犯的错误为e2=(0-0.4)= -0.4,总的错误E为-0.20(e1+e2)。如下表所示:样本  X1  X2  类别  预测值 error1   -1.4    4.7 1   0.8 0.22   -2.5    6.9 0   0.4 -0.4... ... ... ... ... ...现在我们要改进wt的值,使得函数在样本1和2上犯的总错误E减小。将wt的改进拆开来,就是分别改进它的三个分量的值,我们以w1为例。对于样本1:X1*e1=-1.4*0.2= -0.28-0.28告诉我们什么呢?它告诉我们,样本1的X1和e1是异号的,减小w1的值,能够减小函数在样本1上犯的错误。为什么呢?w1减小,则X1*w1增大(因为样本1的X1是负的),进而 z = w0 +w1*X1+w2*X2增大,又由于sigmoid函数是单调递增的,则h(x)会增大。当前的h(x)是0.8,增大的话就是在向1靠近,也就是减小了在样本1上犯的错。对于样本2:X1*e2=-2.5*-0.4= 11告诉我们,样本2的X1和e2是同号的,增大w1的值,能够减小函数在样本2上犯的错误。为什么呢?w1增大,则X1*w1减小,进而 z = w0 +w1*X1+w2*X2减小,又由于sigmoid函数是单调递增的,则h(x)会减小。当前的h(x)是0.4,减小的话就是在向0靠近,也就是减小了在样本2上犯的错。现在的问题就是这样的,样本1说,要减小w1的值,这样函数对我的判断就更准确了,样本2说,要增大w1的值,这样函数对我的判断就更准确了。显然,样本1和样本2都只从自己的角度出发,对改进w1提出了各自不同意见,我们要综合它们的意见,以决定是增大w1还是减小w1,如下:-0.28+1 = 0.72最后的结果0.72是正的,说明,增大w1对函数的总体表现更有利。就是说,增大w1后,虽然在样本1上犯的错误会稍稍增大,但在样本2上犯的错误会大大减小,一个是稍稍增大,一个是大大减小,为了函数总体表现,肯定是增大w1的值啦。那么具体增加多大呢?我们可以用一个专门的参数alpha来控制。以上,只是对书中所用算法的一个形象直观的理解,没有任何严谨的数学证明,目的是让大家能够更感性地理解这个算法在做什么。作者:milter链接:http://www.jianshu.com/p/eb94c60015c7來源:简书
原创粉丝点击