逻辑回归

逻辑回归

# 引入库文件方便后面用
import numpy as np
import matplotlib.pyplot as plt

1 线性回归

线性回归的模型是
h ( w ) = w 0 + w 1 x 1 + w 2 x 2 + ⋯ + w n x n = w T x h(w) = w^0 + w^1 x^1+w^2 x^2+\cdots+w^n x^n = \mathbf{w^Tx} h(w)=w0+w1x1+w2x2++wnxn=wTx

线性回归任务是找到一个超平面,使得该平面尽量能够代表给出的数据整体。其通常求 θ \theta θ b b b的代价函数是
J ( w ) = ∑ i 1 2 ( h w ( x i ) − y i ) 2 J(w)=\sum_{i}\frac{1}{2}(h_w(x^i)-y^i)^2 J(w)=i21(hw(xi)yi)2

运用梯度下降方法更新
w : = w − α ∂ ∂ w J ( w ) w:=w - \alpha \frac{\partial}{\partial w}J(w) w:=wαwJ(w)
只考虑第i个样本,对 w w w求导推得
w : = w − α ( y i − h w ( x i ) ) x i w:=w-\alpha(y^i-h_w(x^i))x^i w:=wα(yihw(xi))xi

批梯度下降(Batch Gradient Descent)可以描述成下式

Repeat until convergence{
   w : = α ∑ i = 1 m ( y i − h w ( x i ) ) x i w:=\alpha\sum_{i=1}^m(y^i-h_w(x^i))x^i w:=αi=1m(yihw(xi))xi (for every i)
}

通常批梯度下降当训练数据过大时,计算慢且耗内存,通常实际训练时用随机梯度下降 (Stochastic Gradient Descent)

Loop{
  for i=1 to m,{
     w : = w + α ( y i − h w ( x i ) ) x i w:=w + \alpha(y^i-h_w(x^i))x^i w:=w+α(yihw(xi))xi (for every i)
  }
}

2 逻辑回归

2.1 基本推导

线性回归是拟合问题,感知机是二分类问题,逻辑回归是二分类问题。但是逻辑回归能够通过sigmoid函数映射成某一类概率值。

# 画sigmoid
x = np.linspace(-10,10,100)
y = 1/(1 + np.exp(-x))
plt.plot(x,y)
plt.show()

png

逻辑回归模型为
y = σ ( w T x + b ) ,   w h e r e   σ ( z ) = 1 1 + e ( − z ) y=\sigma(w^Tx+b),\ where\ \sigma(z)=\frac {1} {1 + e^{(-z)}} y=σ(wTx+b), where σ(z)=1+e(z)1

假设sigmoid函数 σ ( z ) \sigma(z) σ(z)表示属于1类的概率,定义
p ( y = 1 ∣ x ; w ) = σ ( w T x + b ) = σ ( z ) p ( y = 0 ∣ x ; w ) = 1 − σ ( z ) p(y=1|x;w)=\sigma(w^Tx+b)=\sigma(z) \\ p(y=0|x;w)=1-\sigma(z) p(y=1x;w)=σ(wTx+b)=σ(z)p(y=0x;w)=1σ(z)

y ^ \hat{y} y^表示我们通过模型计算的值,即 y ^ = σ ( x ) = 1 1 + e − ( w x + b ) \hat{y}=\sigma(x) = \frac{1}{1+e^{-(wx+b)}} y^=σ(x)=1+e(wx+b)1  ,上述二式可以统一写成
p ( y ∣ x ) = y ^ y ( 1 − y ^ ) ( 1 − y ) p(y|x)=\hat{y}^y(1-\hat{y})^{(1-y)} p(yx)=y^y(1y^)(1y)
上式将分类为0和分类和1的概率计算公式合二为一。假设分类器分类足够准确,此时对于一个样本,如果它是属于1类,分类器求出的属于1类的概率应该尽可能大,即 p ( y = 1 ∣ x ) p(y=1 | x) p(y=1x)尽可能接近1;如果它是0类,分类器求出的属于0类的概率应该尽可能大,即 p ( y = 0 ∣ x ) p(y=0 | x) p(y=0x)尽可能接近1。

通过上述公式对二类分类的情况分析,可知我们的目的是求取参数w和b,使得 p ( y ∣ x ) p(y|x) p(yx)对0类和1类的分类结果尽可能取最大值,然而实际上我们定义的代价函数的是求最小值,于是,很自然的,我们想到对 p ( y ∣ x ) p(y|x) p(yx)式子加一个负号,就变成了求最小值的问题,这就得到了逻辑回归中的代价函数。为了方便计算两边取对数得
L ( y ^ − y ) = − l o g p ( y ∣ x ) = − y l o g y ^ − ( 1 − y ) l o g ( 1 − y ^ ) L(\hat{y}-y)=-log p(y|x) = -y log\hat{y} - (1-y)log(1-\hat{y}) L(y^y)=logp(yx)=ylogy^(1y)log(1y^)
对m个样本,则代价函数
J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ i − y i ) J(w,b)=\frac {1}{m}\sum_{i=1}^m L(\hat{y}^i-y^i) J(w,b)=m1i=1mL(y^iyi)

上式对 w w w求偏导得
∂ J ∂ w = 1 m ∑ i = 1 m ( y ^ i − y i ) x i \frac {\partial J}{\partial w} = \frac{1}{m}\sum_{i=1}^m(\hat{y}^i - y^i)x^i wJ=m1i=1m(y^iyi)xi
上式对 b b b求偏导得
∂ J ∂ b = 1 m ∑ i = 1 m ( y ^ i − y i ) \frac {\partial J}{\partial b} = \frac{1}{m}\sum_{i=1}^m(\hat{y}^i - y^i) bJ=m1i=1m(y^iyi)

如果只考虑一个样本的情况,运用链式法则,得
∂ J ∂ w = ( σ ( x ) − y ) x \frac {\partial J}{\partial w} = (\sigma(x) - y)x wJ=(σ(x)y)x


∂ J ∂ b = σ ( x ) − y \frac {\partial J}{\partial b} = \sigma(x) - y bJ=σ(x)y
所以迭代更新规则为
w : = w − α ( σ ( x ) − y ) x w := w - \alpha(\sigma(x) - y)x w:=wα(σ(x)y)x
b : = b − α ( σ ( x ) − y ) b := b - \alpha(\sigma(x) - y) b:=bα(σ(x)y)

至此,我们的推导就都完成了。另一种求w,b的方法是运用概率论中的极大似然估计,这里就不介绍了。下面我们用Python代码来实现一个简单的二维逻辑回归。

2.2 逻辑回归python实现

'''手动创造点数据'''
c1 = np.random.normal(3, 2, (2,100))
c1 = np.r_[c1, np.zeros((1, 100))]  # 标签
c2 = np.random.normal(-3,2, (2,100))
c2 = np.r_[c2, np.ones((1, 100))] # 标签

# 将两类数据拼在一起并打乱样本顺序作为训练数据集
trainset = np.c_[c1,c2]  
index = np.arange(200)
np.random.shuffle(index)
trainset = trainset[:,index]
'''初始化工作'''
w = np.zeros((2, 1))  # 初始化权值
b = 0  # 初始化
X = trainset[0:2,:].reshape(2,200)  # 训练数据
Y = trainset[2,:].reshape(1,200)    # 训练标签
m=200  # 样本数
alpha = 0.1  # 学习率
'''训练'''
for iter in range(100):
    # 前向计算
    Z = np.dot(w.T,X) + b 
    A = 1/(1 + np.exp(-Z))
    # 反向传播
    dz = A - Y
    dw = (1/m)*np.dot(X,dz.T)
    db = (1/m)*np.sum(dz)
    # 更新
    w = w - alpha*dw
    b = b - alpha*db
'''画图'''

# 画原始图
p1 = plt.scatter(c1[0,:], c1[1,:], c='r', marker='o', s=15)
p2 = plt.scatter(c2[0,:], c2[1,:], c='b', marker='x', s=15)

# 画出直线
x1 = np.linspace(-10,10,100)
x2 = -(w[0]*x1 + b)/w[1]
plt.plot(x1, x2, c='g')
plt.legend([p1, p2], ["class 0", "class 1"], loc='upper left')
plt.title("Logistic Regression", fontsize=24)
plt.xlabel("dimension 1", fontsize=14)
plt.ylabel("dimension 2", fontsize=14)
plt.show()

png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值