逻辑回归实现

逻辑斯谛分布

  • 定义(逻辑斯谛分布):设X是连续随机变量,X服从逻辑斯谛分布是指X具有下列分布函数和密度函数
    F ( x ) = P ( X ≤ x ) = 1 1 + e − ( x − μ ) / γ F(x)=P(X\leq x)=\frac{1}{1+e^{-(x-\mu)/ \gamma}} F(x)=P(Xx)=1+e(xμ)/γ1

f ( x ) = F ′ ( x ) = e − ( x − μ ) / γ γ ( 1 + e − ( x − μ ) / γ ) 2 f(x)=F^{'}(x)=\frac{e^{-(x-\mu)/\gamma}}{\gamma{(1+e^{-(x-\mu)/\gamma})}^2} f(x)=F(x)=γ(1+e(xμ)/γ)2e(xμ)/γ

其中 μ \mu μ为位置参数, γ \gamma γ为形状参数

很多人对这个分布没有直观的理解,话不多说 我们直接上图 这个分布如图所示

import matplotlib.pyplot as plt
import numpy as np
mu=0
gamma=[0.5,1,2]
x_range=np.arange(-10,10,0.1)
fig,(ax1,ax2)=plt.subplots(1,2)
for g in gamma:
    ax1.plot(x_range,1/(1+np.exp(-(x_range-mu)/g)),label=f"$\mu$={mu},$\gamma$={g}")
    ax2.plot(x_range,(np.exp(-(x_range-mu)/g))/(g*(1+np.exp(-(x_range-mu)/g))**2),label=f"$\mu$={mu},$\gamma$={g}")
ax1.legend()
ax2.legend()
ax1.set_title("F(x)")
ax2.set_title("f(x)")
ax1.grid()
ax2.grid()
plt.subplots_adjust(left=0,right=2,top=1,hspace=0.01)

在这里插入图片描述

二项逻辑斯谛回归模型

二项逻辑斯谛回归模型是一种分类模型,由条件概率分布P(Y|X)表示,形式为参数化的逻辑斯谛分布,随机变量X取值实数,随机变量Y取值为0或为1,通过监督学习的方式估计模型参数

  • 定义:(逻辑斯谛回归模型)

P ( Y = 1 ∣ x ) = e x p ( w ⋅ x + b ) 1 + e x p ( w ⋅ x + b ) P(Y=1|x)=\frac{exp(w\cdot x+b)}{1+exp(w \cdot x+b)} P(Y=1x)=1+exp(wx+b)exp(wx+b)

P ( Y = 0 ∣ x ) = 1 1 + e x p ( w ⋅ x + b ) P(Y=0|x)=\frac{1}{1+exp(w \cdot x+b)} P(Y=0x)=1+exp(wx+b)1

x ∈ R n x\in R^n xRn是输入,Y ∈ { 0 , 1 } \in\{0,1\} {0,1}是输出, w ∈ R n w\in R^n wRn和b ∈ R \in R R是参数, w w w称为权重,b称为偏置, w ⋅ x w\cdot x wx w w w x x x的内积
为了考察逻辑斯谛回归模型的特点,一个事件的几率(odds)是指改时间发生的概率与该事件不发生的概率的比值,如果事件发生的概率是p,那么该事件的几率是 p 1 − p \frac{p}{1-p} 1pp,该事件的对数几率(log odds)或logit函数是
l o g i t ( p ) = l o g p 1 − p logit(p)=log\frac{p}{1-p} logit(p)=log1pp
对于逻辑斯谛回归而言 由(3)和(4)可得
l o g P ( Y = 1 ∣ x ) 1 − P ( Y = 1 ∣ x ) = l o g P ( Y = 1 ∣ x ) P ( Y = 0 ∣ x ) = l o g   e x p ( w ⋅ x ) = w ⋅ x log\frac{P(Y=1|x)}{1-P(Y=1|x)}\\=log\frac{P(Y=1|x)}{P(Y=0|x)}=log\ exp(w\cdot x)=w\cdot x log1P(Y=1x)P(Y=1x)=logP(Y=0x)P(Y=1x)=log exp(wx)=wx

在逻辑斯谛回归模型当中,输出Y=1的对数几率是输入x的线性函数或者说输出Y=1的对数几率是由输入线性函数表示的模型,即逻辑斯谛模型回归模型,换一个角度来看,考虑对输入x进行分类的线性函数 w ⋅ x w\cdot x wx其值域为实数域 ,注意这里的x ∈ R n + 1 w ∈ R n + 1 \in R^{n+1} w\in R^{n+1} Rn+1wRn+1,通过逻辑斯谛回归模型定义式将线性函数 w ⋅ x w\cdot x wx转化为概率
P ( Y = 1 ∣ x ) = e x p ( w ⋅ x ) 1 + e x p ( w ⋅ x ) P(Y=1|x)=\frac{exp(w\cdot x)}{1+exp(w \cdot x)} P(Y=1x)=1+exp(wx)exp(wx)

若线性函数的值越接近正无穷概率值就为1,接近于负无穷概率值为0,这样的模型我们成为逻辑斯谛回归模型

模型参数估计

逻辑斯谛回归模型学习时,对于给定的训练数据 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) . . . ( x n , y n ) } T=\{(x_1,y_1),(x_2,y_2)...(x_n,y_n)\} T={(x1,y1),(x2,y2)...(xn,yn)},其中 x i ∈ R n , y i ∈ 0 , 1 } x_i \in R^n,y_i \in{0,1\}} xiRn,yi0,1}可以应用极大似然估计法估计模型参数

设:
P ( Y = 1 ∣ x ) = π ( x ) , P ( Y = 0 ∣ x ) = 1 − π ( x ) P(Y=1|x)=\pi(x),P(Y=0|x)=1-\pi(x) P(Y=1x)=π(x),P(Y=0x)=1π(x)

似然函数为:

∏ i = 1 n [ π ( x i ) ] y i [ 1 − π ( x i ) ] 1 − y i \prod_{i=1}^{n}{[\pi(x_i)]}^{y_i}{[1-\pi(x_i)]}^{1-y_i} i=1n[π(xi)]yi[1π(xi)]1yi

对数似然函数为:
L ( w ) = ∑ i = 1 n [ y i l o g π ( x i ) + ( 1 − y i ) l o g ( 1 − π ( x i ) ) ] L(w)=\sum_{i=1}^{n}[y_ilog\pi(x_i)+(1-y_i)log(1-\pi (x_i))] L(w)=i=1n[yilogπ(xi)+(1yi)log(1π(xi))]

对L(w)求极大值,得到w的估计值(通常用梯度下降法拟牛顿法得到最佳参数 w ^ \hat w w^)
到了这里我们发现 对数似然函数就等于损失函数的相反数
因为我们发现如果 y i = 1 y_i =1 yi=1 ,只有 y i l o g ( π x ( i ) ) y_i log(\pi x(i)) yilog(πx(i))这一项生效,结果为0,若 y i = 0 y_i=0 yi=0则只有 ( 1 − y i ) l o g ( 1 − π ( x i ) 这 一 项 生 效 , 结 果 仍 然 为 0 (1-y_i)log(1-\pi(x_i)这一项生效,结果仍然为0 (1yi)log(1π(xi),0,另外我们用
sigmoid函数代表所谓的逻辑斯谛分布
S i g m o i d ( x ) = 1 1 + e − x Sigmoid(x)=\frac{1}{1+e^{-x}} Sigmoid(x)=1+ex1

损失函数求解

定义函数 J ( w ) = − L ( w ) n J(w)=\frac{-L(w)}{n} J(w)=nL(w)这里我们取平均损失
随机初始化 w = { w 1 , w 2 , . . . w n } 和 学 习 率 η w=\{w_1,w_2,...w_n\}和学习率\eta w={w1,w2,...wn}η
∂ J ∂ w j = ∂ J ∂ L × ∂ L ∂ w j \frac{\partial J}{\partial w_j}=\frac{\partial J}{\partial L}\times\frac{\partial L}{\partial w_j} wjJ=LJ×wjL
= ∂ J ∂ L × ∂ L ∂ π ( x i ) × ∂ π ( x i ) ∂ ( w ⋅ x ) × ∂ ( w ⋅ x ) ∂ w j =\frac{\partial J}{\partial L}\times \frac{\partial L}{\partial \pi(x_i)}\times \frac{\partial \pi(xi)}{\partial (w \cdot x)}\times \frac{\partial (w \cdot x)}{\partial w_j} =LJ×π(xi)L×(wx)π(xi)×wj(wx)
= 1 n ∑ i = 1 n ( − y i π ( x i ) + 1 − y i 1 − π ( x i ) ) ( π ( x i ) ( 1 − π ( x i ) ) ) x j =\frac{1}{n}\sum_{i=1}^n(\frac{-y_i}{\pi(x_i)}+\frac{1-y_i}{1-\pi(x_i)})(\pi (x_i)(1-\pi(x_i)))x_j =n1i=1n(π(xi)yi+1π(xi)1yi)(π(xi)(1π(xi)))xj
= 1 n ∑ i = 1 n ( − y i π ( x i ) + 1 − y i 1 − π ( x i ) ) ( π ( x i ) ( 1 − π ( x i ) ) ) x j =\frac{1}{n}\sum_{i=1}^n(\frac{-y_i}{\pi(x_i)}+\frac{1-y_i}{1-\pi(x_i)})(\pi (x_i)(1-\pi(x_i)))x_j =n1i=1n(π(xi)yi+1π(xi)1yi)(π(xi)(1π(xi)))xj
= 1 n ∑ i = 1 n ( π ( x i ) − y i ) x i j =\frac{1}{n}\sum_{i=1}^n(\pi(x_i)-y_i)x_i^j =n1i=1n(π(xi)yi)xij

其中 π ( x i ) = s i g m o i d ( w ⋅ x ) , x i j 代 表 第 i 个 样 本 第 j 个 特 征 \pi(x_i)=sigmoid(w\cdot x),x_i^j代表第i个样本第j个特征 π(xi)=sigmoid(wx),xijij

代码实现

数据加载

数据集链接 提取码p7gq

import numpy as np
import matplotlib.pyplot as plt
#加载数据集
with open("testData.txt",'r') as reader:
    txt=reader.read()
data=np.array([list(map(eval,item.split())) for item in 
txt.split("\n")])
labels=data[:,2].copy()#获取标签y
y1_index=data[:,2]==0
y2_index=data[:,2]==1
data[:,2]=1#此处其实是把b当成特征常量1
plt.scatter(data[:,0][y1_index],data[:,1][y1_index])
plt.scatter(data[:,0][y2_index],data[:,1][y2_index])

数据分布如图: 我们可以发现这其实不是一个比较好的线性分布

在这里插入图片描述

训练过程

def g(x):#sigmoid 函数
    return 1/(1+np.exp(-x))
w=np.array([7.0,6.0,5.0])
epoches=500#迭代500轮
lr=1#学习率设置为1
nums=len(labels)#获取样本总数
cost_records=[]#记录损失值
for epoche in range(epoches):
    dldw1,dldw2,dldw3=0,0,0
    for num in range(nums):
        dldw1+=(g(w@data[num])-labels[num])*data[num][0]
        dldw2+=(g(w@data[num])-labels[num])*data[num][1]
        dldw3+=(g(w@data[num])-labels[num])*data[num][2]
    cost=np.sum(np.abs(g(data@w.T)-labels))/nums
    cost_records.append(cost)
    lr_update=lr*0.5**(epoche/50)#这里采用指数学习率衰减
    w[0]=w[0]-lr_update*dldw1/nums
    w[1]=w[1]-lr_update*dldw2/nums
    w[2]=w[2]-lr_update*dldw3/nums

验证算法

w ^ ⋅ x = 0 = w 1 x 1 + w 2 x 2 + w 3 ( b ) \hat w\cdot x=0\\=w_1x_1+w_2x_2+w_3(b) w^x=0=w1x1+w2x2+w3(b)
我们随机生成坐标来拟合回归直线

testx=np.arange(-4,4,0.5)
testy=(-w[2]-w[0]*testx)/w[1]
plt.scatter(data[:,0][y1_index],data[:,1][y1_index])
plt.scatter(data[:,0][y2_index],data[:,1][y2_index])
plt.plot(testx,testy)

在这里插入图片描述
效果还是很不错的,其中有几个误分类点,这是因为原始数据的分布不是完美的线性

Loss损失:

plt.plot(list(range(epoches)),cost_records)
plt.title("$Learning Rate: \eta $")

在这里插入图片描述
如有错误,敬请指正

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值