Logistics回归算法个人总结

Logistics回归定义

说是回归,但其本质上还是属于分类算法。利用Logistics回归进行分类的主要思想是:根据现有数据对分类边界建立回归方程,以此进行分类。

基于Logistics回归和Sigmoid函数的分类

因为要分类,于是希望有这样一个函数,它在接受所有的输入之后,可以返回该样本的类别。例如,在两种类别的情况下,函数希望输出0或1。在数学上恰好有这样一个函数具有该性质,该函数被称为Sigmoid函数。函数的具体计算公式如下:
σ ( z ) = 1 1 + e − z \sigma (z)=\frac{1}{1+e^{-z}} σ(z)=1+ez1
当输入为0使,函数值为0.5,随着因变量的增大,函数不断趋向于1;随着因变量的减小,函数逐渐趋向于0。当横坐标足够大的时候,sigmoid函数更像是一个跳跃函数。
Logistics回归算法个人总结_第1张图片
因此,为了实现该分类器,我们可以在每一个特征上都乘以一个回归系数,然后将所有结果相加,将这个总和代入sigmoid函数中,进而得到一个介于01之间的一个值。任何大于0.5的值被划分到1类中,小于0.5的值划分到0类,这样便实现了分类功能。因此,Logistics回归也可以看作是一种概率估计。
接下来的问题就变成了如何去寻找这个回归系数

基于最优化方法的最佳回归系数确定

sigmoid函数的输入记为 z z z,由下面的公式得出
z = w 0 x 0 + w 1 x 1 + w 2 x 2 + ⋯ + w n x n z=w_{0}x_{0}+w_{1}x_{1}+w_{2}x_{2}+\cdots+w_{n}x_{n} z=w0x0+w1x1+w2x2++wnxn
其中 x i x_{i} xi表示样本第i个特征, w i w_{i} wi表示特征i所对应的系数。
如果采用向量的写法,上述公式可以写成 z = w T X z=w^{T}X z=wTX,它表示两个向量对应元素乘积再求和得到 z z z值。其中向量 x x x是分类器输入的数据,向量 w w w是我们要求的回归系数向量。

w w w的计算方法

那么如何计算 w w w呢?
为了方便书写,我们令:
h w ( x ) = σ ( w T X ) = 1 1 + e − z h_{w }(x)=\sigma(w^{T}X)=\frac{1}{1+e^{-z}} hw(x)=σ(wTX)=1+ez1
根据sigmoid函数的特性,我们设:
P ( y = 1 ∣ x , w ) = h w ( x ) P ( y = 0 ∣ x , w ) = 1 − h w ( x ) \begin{matrix} P(y=1|x,w )=h_{w }(x) \\ P(y=0|x,w )=1-h_{w }(x) \\ \end{matrix} P(y=1x,w)=hw(x)P(y=0x,w)=1hw(x)
因为 h ( x ) h(x) h(x)介于01之间,我们可以用它来表示结果是0或1的概率,上面两个式子可以合并,得到:
P ( y ∣ x , w ) = ( h w ( x ) ) y ( 1 − h w ( x ) ) 1 − y P(y|x,w)=(h_{w }(x))^{y}(1-h_{w }(x))^{1-y} P(yx,w)=(hw(x))y(1hw(x))1y
其中 y = { 0 , 1 } y=\{0,1\} y={0,1}
有了概率了,就要考虑最大似然了。假定样本与样本之间相互独立,那么整个样本集生成的概率即为所有样本生成概率的乘积,我们定义为 L ( w ) L(w) L(w)
L ( w ) = ∏ i = 1 n ( h w ( x ( i ) ) ) y ( i ) ( 1 − h w ( x ( i ) ) ) 1 − y ( i ) L(w)=\prod_{i=1}^{n}(h_{w }(x^{(i)}))^{y^{(i)}}(1-h_{w }(x^{(i)}))^{1-y^{(i)}} L(w)=i=1n(hw(x(i)))y(i)(1hw(x(i)))1y(i)
其中 x ( i ) x^{(i)} x(i)表示第i个样本, y ( i ) y^{(i)} y(i)表示第i个样本所属的类别,n表示样本个数。
为了方便运算,我们取自然对数:
l ( w ) = ln ⁡ ( L ( w ) ) = ∑ i = 1 n [ y ( i ) ln ⁡ ( h w ( x ( i ) ) ) + ( 1 − y ( i ) ) ln ⁡ ( 1 − h w ( x i ) ) ] l(w)=\ln(L(w))=\sum_{i=1}^{n}[y^{(i)}\ln(h_{w}(x^{(i)}))+(1-y^{(i)})\ln(1-h_{w}(x^{i}))] l(w)=ln(L(w))=i=1n[y(i)ln(hw(x(i)))+(1y(i))ln(1hw(xi))]
这时,目标就变成了求 l ( w ) l(w) l(w)的最大值。

梯度上升法

我们要求一个函数的最大值,其中一个办法就是从函数的某一点开始,沿着该函数梯度方向前进。由梯度定义可知,梯度的方向是函数f增长最快的方向,梯度的反方向是f降低最快的方向。
梯度上升法其实类似于“爬山”的过程,我们想到达这座山的最高点,每次前进一小步,每到一个点的时候,都希望能找到最佳的移动方向(即上面所计算的梯度)。我们令梯度记为 ▽ \bigtriangledown ,则函数 f ( x , y ) f(x,y) f(x,y)的梯度表示为:
▽ f ( x , y ) = [ ∂ f ( x , y ) ∂ x ∂ f ( x , y ) ∂ y ] \bigtriangledown f(x,y)=\begin{bmatrix} \frac{\partial f(x,y)}{\partial x}\\ \\ \frac{\partial f(x,y)}{\partial y}\\ \end{bmatrix} f(x,y)=xf(x,y)yf(x,y)

其中,函数 f ( x , y ) f(x,y) f(x,y)必须在要计算的点上有定义且可微。
根据该算法,函数中某一点的下一步一定是沿着该点函数增长最快的方向移动,这里只强调了方向,没有说距离。下面我们把该距离称为步长,记作 α \alpha α。意味着我们可以通过 α \alpha α来控制每一步走的距离,不要走太快,步长太大会错过了最高点。同时也要保证不要走的太慢,太小的话在有限步内到达不了最值点。所以 α \alpha α的选择在该算法中往往是很重要的。梯度上升算法的迭代公式如下:
x i + 1 = x i + α ∗ ∂ f ( x ) ∂ x x_{i+1}=x_{i}+\alpha *\frac{\partial f(x)}{\partial x} xi+1=xi+αxf(x)
该公式一直被迭代执行,直到达到迭代次数或达到某个结束条件后停止。根据上面的推导, f ( x ) f(x) f(x) l ( w ) l(w) l(w)代替,下面计算 l ( w ) l(w) l(w) w j w_{j} wj求偏导:
∂ l ( w ) ∂ w j = ∑ i = 1 n y ( i ) 1 h w ( x ) ∂ h w ( x ( i ) ) ∂ w j − ( 1 − y ( i ) ) 1 1 − h w ( x ) ∂ h w ( x ( i ) ) ∂ w j \frac{\partial l(w)}{\partial w_{j}}=\sum_{i=1}^{n}y^{(i)}\frac{1}{h_{w}(x)}\frac{\partial h_{w}(x^{(i)})}{\partial w_{j}}-(1-y^{(i)})\frac {1}{1-h_{w}(x)}\frac{\partial h_{w}(x^{(i)})}{\partial w_{j}} wjl(w)=i=1ny(i)hw(x)1wjhw(x(i))(1y(i))1hw(x)1wjhw(x(i))
其中:
σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) ∂ w T X ∂ w j = ∂ ( w 0 x 0 + w 1 x 1 + w 2 x 2 + ⋯ + w n x n ) ∂ w j = x j h w ( x ) = σ ( w T X ) \begin{matrix} \sigma ^{'}(z)=\sigma(z)(1-\sigma(z)) \\ \\ \frac{\partial w^{T}X}{\partial w_{j}}=\frac{\partial (w_{0}x_{0}+w_{1}x_{1}+w_{2}x_{2}+\cdots+w_{n}x_{n})}{\partial w_{j}}=x_{j}\\ \\ h_{w}(x)=\sigma(w^{T}X)\\ \end{matrix} σ(z)=σ(z)(1σ(z))wjwTX=wj(w0x0+w1x1+w2x2++wnxn)=xjhw(x)=σ(wTX)
因此:
∂ h w ( x ( i ) ) ∂ w j = h w ( x ( i ) ) ( 1 − h w ( x ( i ) ) ) x j \frac{\partial h_{w}(x^{(i)})}{\partial w_{j}}=h_{w}(x^{(i)})(1-h_{w}(x^{(i)}))x_{j} wjhw(x(i))=hw(x(i))(1hw(x(i)))xj
代入上式,化简得:
∂ l ( w ) ∂ w = ∑ i = 1 n ( y ( i ) − h w ( x ( i ) ) ) x j ( i ) \frac{\partial l(w)}{\partial w}=\sum_{i=1}^{n}(y^{(i)}-h_{w}(x^{(i)}))x_{j}^{(i)} wl(w)=i=1n(y(i)hw(x(i)))xj(i)
综上,对于本内容来说,梯度算法的迭代公式如下:
w : = w + α ∗ ( y ( i ) − h w ( x ( i ) ) ) x j ( i ) w:=w+\alpha *(y^{(i)}-h_{w}(x^{(i)}))x_{j}^{(i)} w:=w+α(y(i)hw(x(i)))xj(i)

实例

下面举一个例子来说明:
如图所示是两类数据,不同的颜色分别代表不同的类别,下面使用梯度上升法找到Logistic回归分类器在此数据集上的最佳回归函数。
Logistics回归算法个人总结_第2张图片

数据导入

数据格式为文本形式,每行数据代表一个样本。每行前两个表示该样本的两个特征,第三个数据表示样本类别,为了方便运算,我们引入一个新特征,它是常量且为1。代码实现如下图:

def create_data():
    dataM=[]
    classM=[]
    with open('testSet.txt') as f:
        for l in f.readlines():
            lenarr=(l.strip().split())
            dataM.append([1.0,float(lenarr[0]),float(lenarr[1])])
            classM.append(int(lenarr[2]))
    return dataM,classM

数据处理

接下来是sigmoid函数,因为我们会用到向量的运算,所有引入numpy包。代码如下:

def sigmoid(x):
    return 1.0/(1+np.exp(-x))	#涉及向量运算,所以使用np包里面的函数

最后是分类算法,通过我们前面的推导,我们得到如下代码:

def grad(dataM,classM):		#返回值为回归系数
    dataM=np.mat(dataM)     #转换成矩阵形式,方便计算
    classM=np.mat(classM).transpose()   #转换成矩阵后再转置
    m,n=np.shape(dataM)
    alpha=0.001
    maxcycles=500
    weights=np.ones((n,1))
    for i in range(maxcycles):
        h=sigmoid(dataM*weights)
        error=classM-h
        weights=weights+alpha*dataM.transpose()*error
    return weights

其中

weights+alpha*dataM.transpose()*error

转换成矩阵形式如下:
d a t a M . t r a n s p o s e ( ) ∗ e r r o r = [ x 0 1 x 0 2 x 0 3 ⋯ x 0 100 x 1 1 x 1 2 x 1 3 ⋯ x 1 100 x 2 1 x 2 2 x 2 3 ⋯ x 2 100 ] ∗ [ y 1 − s i g m o i d ( w 0 x 0 1 + w 1 x 1 1 + w 2 x 2 1 ) y 2 − s i g m o i d ( w 0 x 0 2 + w 1 x 1 2 + w 2 x 2 2 ) ⋯ y 100 − s i g m o i d ( w 0 x 0 100 + w 1 x 1 100 + w 2 x 2 100 ) ] dataM.transpose()*error=\left[ \begin{matrix} x_{0}^{1} & x_{0}^{2} & x_{0}^{3} & \cdots &x_{0}^{100} \\ x_{1}^{1} & x_{1}^{2} & x_{1}^{3} & \cdots &x_{1}^{100} \\ x_{2}^{1} & x_{2}^{2} & x_{2}^{3} & \cdots &x_{2}^{100} \end{matrix} \right] * \left[ \begin{matrix} y^{1}-sigmoid(w_{0}x_{0}^{1}+w_{1}x_{1}^{1}+w_{2}x_{2}^{1}) \\ y^{2}-sigmoid(w_{0}x_{0}^{2}+w_{1}x_{1}^{2}+w_{2}x_{2}^{2}) \\ \cdots \\ y^{100}-sigmoid(w_{0}x_{0}^{100}+w_{1}x_{1}^{100}+w_{2}x_{2}^{100}) \end{matrix} \right] dataM.transpose()error=x01x11x21x02x12x22x03x13x23x0100x1100x2100y1sigmoid(w0x01+w1x11+w2x21)y2sigmoid(w0x02+w1x12+w2x22)y100sigmoid(w0x0100+w1x1100+w2x2100)
与导出结果一致。
运行上面的函数,输出如下:

[[ 4.12414349]
 [ 0.48007329]
 [-0.6168482 ]]

该数组即为特征的回归系数。

画出决策边界

我们设定 0 = w 0 x 1 + w 1 x 2 + w 2 x 3 0=w_{0}x_{1}+w_{1}x_{2}+w_{2}x_{3} 0=w0x1+w1x2+w2x3,其中 x 1 x_{1} x1为1,然后解出形如 y = a x + b y=ax+b y=ax+b的形式,即:
y = − ( w 0 − w 1 x ) / w 2 y=-(w_{0}-w_{1}x)/w_{2} y=(w0w1x)/w2
绘图部分代码如下:

def plotFig():
    import matplotlib.pyplot as plt
    datas,labels=create_data()
    ws=grad(datas,labels)
    print(ws)
    ws=np.array(ws)
    dataArr=np.array(datas)
    data_len=np.shape(datas)[0]     #数据个数
    x1=[];y1=[]
    x2=[];y2=[]
    for i in range(data_len):
        if int(labels[i])==1:       #属于第一类时
            x1.append(dataArr[i][1]);y1.append(dataArr[i][2])
        else:
            x2.append(dataArr[i][1]);y2.append(dataArr[i][2])

    fig=plt.figure()                #把两类数据依次绘制散点图
    ax=fig.add_subplot(111)
    ax.scatter(x1,y1,s=30,c='red',marker='s')
    ax.scatter(x2,y2,s=30,c='green')
    
    x=np.arange(-3.0,3.0,0.1)
    y=(-ws[0]-ws[1]*x)/ws[2]

    ax.plot(x,y)                    #绘制分界函数
    plt.show()

运行出来的图像如下:
Logistics回归算法个人总结_第3张图片
分类大体正确,较好的区分出来了两类数据。

你可能感兴趣的:(机器学习,python)