【机器学习】Logistic回归学习笔记(二) 梯度上升优化算法

机器学习实战(Machine Learning in Action)

CH05 logistic regression 学习笔记(一)梯度上升优化算法

import numpy as np
import math
%matplotlib inline
import matplotlib.pyplot as plt
def loadDataSet():
    dataMat = []
    labelMat = []
    with open('testdata.txt', 'r') as fr:
        for line in fr.readlines():
            lineArr = line.strip().split()
            dataMat.append([1, float(lineArr[0]), float(lineArr[1])])
            labelMat.append(int(lineArr[2]))
    return dataMat, labelMat

加载数据

返回 dataMat(list) 和 labelMat(list)

dataMat.len 为 (dataSize)(float)

labelMat.len 为 (dataSet)(int)

def sigmoid(inX):
    return 1.0/(1 + np.exp(-inX))

sigmoid 函数

σ ( z ) = 1 1 + e − z \sigma(z) = {{1}\over{1 + e^{-z}}} σ(z)=1+ez1

值得注意的是 σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z)(1 - \sigma(z)) σ(z)=σ(z)(1σ(z))

sigmoid 函数经常被用于二分类,当 σ ( z ) < 0.5 \sigma(z) < 0.5 σ(z)<0.5 时,被认为 P = 0 P = 0 P=0。而 σ ( z ) ≥ 0.5 \sigma(z) \ge 0.5 σ(z)0.5 时,被认为 P = 1 P = 1 P=1

在 logistic regression 里,我们把每个特征乘于一个回归系数,然后相加,将得到的总和带进 σ ( z ) \sigma(z) σ(z) 中,得到一个 0 ∼ 1 0 \sim 1 01 的值。

z = ω 0 x 0 + ω 1 x 1 + ⋯ + ω n x n z = \omega_{0}x_{0} + \omega_{1}x_{1} + \cdots + \omega_{n}x_{n} z=ω0x0+ω1x1++ωnxn,如果采用向量的写法可以写成 z = w T x z = w^{T}x z=wTx

其中, ω \omega ω 是回归系数(权重)的了列向量,而 x x x 是输入的特征值列向量。

因此我们现在剩下的问题就是如何求解回归系数(权重 ω \omega ω)。

def gradAscent(dataMatIn, classLabels):
    dataMatrix = np.mat(dataMatIn)
    labelMat = np.mat(classLabels).transpose()
    m, n = np.shape(dataMatrix)
    alpha = 0.001
    maxCycles = 100
    weights = np.ones((n, 1))
    for k in range(maxCycles):
        h = sigmoid(dataMatrix * weights)
        error = labelMat - h
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights

梯度上升(gradient ascent)


梯度

梯度是一个向量,表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该方向变化最快(梯度的方向),变化率最大(梯度的模)。

我们将梯度记为 ∇ \nabla ,则 f ( x , y ) f(x,y) f(x,y) 的梯度为 ∇ f ( x , y ) = [ ∂ f ( x , y ) ∂ x ∂ f ( x , y ) ∂ y ] \nabla f(x,y) = \begin{bmatrix}\partial f(x,y)\over \partial x \\ \partial f(x,y) \over \partial y \end{bmatrix} f(x,y)=[xf(x,y)yf(x,y)]

表示我们现在需要沿着 x x x 轴移动 ∂ f ( x , y ) ∂ x \partial f(x,y)\over \partial x xf(x,y),沿着 y y y 轴移动 ∂ f ( x , y ) ∂ y \partial f(x,y)\over \partial y yf(x,y) 。( f ( x , y ) f(x,y) f(x,y) 要在这些点上有意义且可微)

但是我们上面的式子中,只给出了梯度的方向和变化率,并没有给出步长,因此我们还要定义一个步长 α \alpha α α \alpha α 也会被称之为学习率(learning rate)。


最优化权重

在本节中,我们讨论的分类为二分类,因此类别非0即1。
我们设 x x x 为输入的特征向量, ξ \xi ξ 为类别。

我们定义 P ( ξ = 1 ∣ x ) = σ ( z ) P(\xi = 1|x) = \sigma(z) P(ξ=1x)=σ(z)

显然 P ( ξ = 0 ∣ x ) = 1 − P ( ξ = 1 ∣ x ) = 1 − σ ( z ) = σ ( − z ) P(\xi = 0|x) = 1 - P(\xi = 1|x) = 1 - {\sigma(z)} = \sigma(-z) P(ξ=0x)=1P(ξ=1x)=1σ(z)=σ(z)

因此,对于第 i i i 个样本,有
P ( ξ = ξ i ∣ x i ) = P ( ξ = 0 ∣ x i ) 1 − ξ i P ( ξ = 1 ∣ x i ) ξ i = ( 1 − σ ( z i ) ) 1 − ξ i σ ( z i ) ξ i P(\xi = \xi_{i}|x_i) = P(\xi = 0|x_i)^{1-\xi_i}P(\xi = 1|x_i)^{\xi_i}=(1-\sigma(z_i))^{1-\xi_i}\sigma(z_i)^{\xi_i} P(ξ=ξixi)=P(ξ=0xi)1ξiP(ξ=1xi)ξi=(1σ(zi))1ξiσ(zi)ξi

由于各个样本之间是相互独立的,联合概率为各个样本的乘积。因此我们可以得到关于权重向量 ω \omega ω 的最大似然函数
L ( ω ) = ∏ i = 1 n ( 1 − σ ( z ) ) 1 − ξ i ( σ ( z ) ) ξ i ( n  为样本总数) \mathscr{L}(\omega) = \prod^n_{i = 1}(1-\sigma(z))^{1-\xi_i}(\sigma(z))^{\xi_i} \quad\text{($n$ 为样本总数)} L(ω)=i=1n(1σ(z))1ξi(σ(z))ξi(n 为样本总数)

两边同时取对数,得
l n   L ( ω ) = ∑ i = 1 n l n ( ( 1 − σ ( z ) ) 1 − ξ i σ ( z ) ξ i ) = ∑ i = 1 n ( ( 1 − ξ i ) l n ( 1 − σ ( z ) ) + ξ i l n   σ ( z ) ) = ∑ i = 1 n ( ( 1 − ξ i ) l n   σ ( − z i ) + ξ i l n   σ ( z i ) ) \begin{aligned} ln\ \mathscr{L}(\omega) & = \sum_{i=1}^{n}ln((1-\sigma(z))^{1-\xi_i}\sigma(z)^{\xi_i})\\ & = \sum_{i=1}^{n}((1-\xi_i)ln(1-\sigma(z)) + \xi_iln\ \sigma(z))\\ & = \sum_{i=1}^{n}((1-\xi_i)ln\ \sigma(-z_i) + \xi_iln\ \sigma(z_i))\\ \end{aligned} ln L(ω)=i=1nln((1σ(z))1ξiσ(z)ξi)=i=1n((1ξi)ln(1σ(z))+ξiln σ(z))=i=1n((1ξi)ln σ(zi)+ξiln σ(zi))
L ( ω ) \mathscr{L}(\omega) L(ω) 最大时,此时的 ω \omega ω 为回归系数最优解。

显然,若存在一个 ω \omega ω 使得 L ( ω ) \mathscr{L}(\omega) L(ω) 取得最大值,同样也可使 l n   L ( ω ) ln\ \mathscr{L}(\omega) ln L(ω) 取最大值。
因此,求解 l n   L ( ω ) ln\ \mathscr{L}(\omega) ln L(ω) 的最大值与求解 L ( ω ) \mathscr{L}(\omega) L(ω) 的最大值是等效的。

现在的问题转换为求 l n   L ( ω ) ln\ \mathscr{L}(\omega) ln L(ω) 的最大值。

我们使用梯度上升求 ω \omega ω 的最大值,即 ω : = ω + α ∇ l n   L ( ω ) \omega := \omega +\alpha \nabla ln\ \mathscr{L}(\omega) ω:=ω+αln L(ω)

对于 ω \omega ω 的第 j j j 个分量 ω j \omega_j ωj, 有 ω j : = ω j + α ∂ l n   L ( ω ) ∂ ω j \omega_j := \omega_j + \alpha {\partial ln\ \mathscr{L}(\omega) \over {\partial \omega_j}} ωj:=ωj+αωjln L(ω)
∂ l n   L ( ω ) ∂ ω j = ∑ i = 1 n ( − ( 1 − ξ i ) ( 1 − σ ( − z i ) ) + ξ i ( 1 − σ ( z i ) ) ) ∂ z i ∂ ω j = ∑ i = 1 n ( ( ξ i − 1 ) σ ( z i ) + ξ i ( 1 − σ ( z i ) ) ) x j = ∑ i = 1 n ( ξ i − σ ( z i ) ) x j \begin{aligned}\\ {\partial ln\ \mathscr{L}(\omega) \over {\partial \omega_j}} & = \sum_{i=1}^n (-(1-\xi_i)(1 - \sigma(-z_i)) +\xi_i(1-\sigma(z_i))){\partial z_i \over \partial \omega_j}\\ & = \sum_{i=1}^n ((\xi_i - 1)\sigma(z_i) +\xi_i(1-\sigma(z_i)))x_j\\ & = \sum_{i=1}^n (\xi_i - \sigma(z_i))x_j\\ \end{aligned} ωjln L(ω)=i=1n((1ξi)(1σ(zi))+ξi(1σ(zi)))ωjzi=i=1n((ξi1)σ(zi)+ξi(1σ(zi)))xj=i=1n(ξiσ(zi))xj

∂ l n   L ( ω ) ∂ ω j = x T ( ξ − σ ( z ) ) {\partial ln\ \mathscr{L}(\omega) \over {\partial \omega_j}} = x^T(\xi-\sigma(z)) ωjln L(ω)=xT(ξσ(z))
上述代码中,我们令 e r r o r = ξ − σ ( z ) error = \xi - \sigma(z) error=ξσ(z)

最后我们可以得到梯度上升的式子为 ω : = ω + α x T ( ξ − σ ( z ) ) \omega := \omega + \alpha x^T(\xi-\sigma(z)) ω:=ω+αxT(ξσ(z))

def plotBestFit(weights):
    dataMat, labelMat = loadDataSet()
    dataArr = np.array(dataMat)
    n = np.shape(dataArr)[0]
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    for i in range(n):
        if int(labelMat[i] == 1):
            xcord1.append(dataArr[i, 1])
            ycord1.append(dataArr[i, 2])
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s = 30, c = 'red', marker = 's')
    ax.scatter(xcord2, ycord2, s = 30, c = 'green')
    x = np.arange(-5.0, 5.0, 0.1)
    y = (-weights[0] - weights[1] * x)/weights[2]
    ax.plot(x, y)
    plt.show()
dataArr, labelMat = loadDataSet()
weights = gradAscent(dataArr, labelMat)
print(weights)
plotBestFit(weights.getA())
[[ 1.65879592]
[ 0.2642799]
[-0.30190436]]

【机器学习】Logistic回归学习笔记(二) 梯度上升优化算法_第1张图片

你可能感兴趣的:(【机器学习】Logistic回归学习笔记(二) 梯度上升优化算法)