20行python搞定逻辑回归

逻辑回归是在工业界广泛应用的分类算法,特点是结构简单,主要有以下优缺点:

pros
1.训练和运行速度都很快
2.实现方便
3.内存占用少
4.可解释性好

cons
1.由于于无法拟合非线性关系,对特征工程的要求较高。
2.对多重共线性数据较为敏感

结构上,逻辑回归和线性回归的区别仅仅在于增加了sigmoid函数(又称逻辑函数),将输出值转化为归一化的数值。

线性回归

$$ Y=X \cdot W+B $$

逻辑回归

$$ Y=\sigma (X \cdot W+B) $$

其中

$$ \sigma(t)=\frac{1}{1+e^{-t}} $$

为sigmoid函数

$$ \hat y=\left\{\begin{array}{ll} 0, & z<0 \\ 0.5, & z="0" 1,>0 \end{array}, \quad z=w^{T} x+b\right. $$

之所以加入sigmoid函数,是因为线性回归的输出值不在0~1之间,也不能拟合离散变量。
而理想的分类函数不可微。对数几率函数则是任意阶可导的凸函数,具有良好数学性质。另外,引入sigmoid函数可以连续地表示可能性的大小,不过输出值并不是数学意义上的“概率”。

模型已经确定,接下来考虑参数,使用统计中极大似然估计的办法。
伯努利分布下的最大似然估计推导出交叉熵损失函数:
假设

$$ \begin{array}{l} P(Y=1 \mid x)=p(x) \\ P(Y=0 \mid x)=1-p(x) \end{array} $$

伯努利分布的概率密度函数

$$ f_{X}(x)=p^{x}(1-p)^{1-x}=\left\{\begin{array}{ll} p & \text { if } x=1 \\ 1-p & \text { if } x=0 \end{array}\right. $$

似然函数

$$ L(w)=\prod\left[p\left(x_{i}\right)\right]^{y_{i}}\left[1-p\left(x_{i}\right)\right]^{1-y_{i}} $$

为了便于计算改写为对数形式,发现与交叉熵完全一致

$$ \ln L(w)=\sum\left[y_{i} \ln p\left(x_{i}\right)+\left(1-y_{i}\right) \ln \left(1-p\left(x_{i}\right)\right)\right] $$

取反后作为损失函数,最大化似然函数等价于最小化损失函数。

$$ J(w)=-\frac{1}{N} \ln L(w) $$

本文中使用梯度下降法寻找最优参数
计算损失函数对于权重的偏导数,证明从略

$$ \frac{\partial J(w)}{\partial w_{i}}=\left(p\left(x_{i}\right)-y_{i}\right) x_{i} $$

详细推导过程可以参考 [1]

更新参数

$$ w_{i}^{k+1}=w_{i}^{k}-\alpha \frac{\partial J(w)}{\partial w_{i}} $$

数学推导完毕,以下是具体实现部分。
完整定义一个可以使用的逻辑回归模型所需的python代码不到20行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import numpy as np

#工具函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))

class LogisticsReg():
def __init__(self,learn_rate=1e-3,niter=1000):
#设定学习率与迭代次数
self.lr=learn_rate
self.iter=int(niter)

def fit(self,x,y):
#插入一列1,与\\(w_0\\)相乘后相当于偏置项b
#这样写能够大大简化代码和求导过程
x=np.insert(x, 0, values=1, axis=1)

#随机初始化w
w=np.random.uniform(size=(x.shape[1]))

for i in range(self.iter):
#计算模型预测值
p = sigmoid(x.dot(w))
#梯度下降
w -= self.lr * x.T.dot(p - y)

self.w=w

def predict(self,x):
#预测时也要插入一列
x=np.insert(x, 0, values=1, axis=1)
return sigmoid(x.dot(self.w))

参考资料
[1] https://blog.csdn.net/jasonzzj/article/details/52017438

20行python搞定逻辑回归

https://heth.ink/LogisticRegression/

作者

YK

发布于

2021-02-09

更新于

2021-02-09

许可协议