python小白之路:第十六章 逻辑回归模型(一)

逻辑回归 Logistic Regression

1 原理

1.1 分类问题

目标是面对某种事物,估计它的可能性,判断属于哪种已知的样本类,比如买不买某种东西、是不是垃圾邮件等。类别的数量可以有很多,所以按数量可以分为二分类(binary classification)和多元分类(multiclass classification)。但是对于多分类问题也可以通过OvR、OvO等一些策略方法转为二分类问题。

1.1.1 OvR(One vs Rest)

一对剩余的所有,也可能叫OvA。总之思路就是假如有四个类别,选中一个类别One,剩余的三个都看作是其他类别Rest,于是四个类别的问题就变成了One和Rest的问题。因此,每有一个这样的One就会有对应的一个二分类,所以按照假设,我们得到了四个二分类问题。

进一步的,在训练过程中,将数据集分成4份,每一份都转换为对应的二分类数据集。然后将每一份都使用一个单独的分类器进行训练,就会得到相对应的测试样本为对应的One的概率。最后,我们选取概率值最大的类别作为测试样本的最终类别。

1.1.2 OvO(One vs One)

一对一。思路是假如有四个类别,直接挑出两个,然后对这两个进行二分类。于是,就会有 C 4 2 C_4^2 C42 =6个两两分类问题,即6个二分类任务。进而得到6个分类结果,然后对结果进行投票来选择分类结果数量最多的类别作为最终类别。

1.1.3 逻辑回归

OvO和OvR根据任务数量在时间上有差异;OvO分类结果会更加准确,因为其保留了真实的类别信息,而OvR将剩余的类别都保留混淆了类别信息。

#sklearn的逻辑回归模型的multi_class超参数可设置分类方式

LogisticRegression(multi_class='ovr') 
LogisticRegression(multi_class='multinomial') 

逻辑回归是一种解决二分类问题的机器学习方法,即给定输入的x,判断它的标签是A还是B。

1.2 具体过程
1.2.1 如何二分类

可以设置一个阈值,如果预测的数值大于阈值,那么就属于A;反之属于B。

还可以去预测标签为A的概率,若概率大于0.5,则认为是A;反之是B。

1.2.2 如何得到概率

概率的区间是[0,1],但线性模型 f ( x ) = w T x f(x)=w^Tx f(x)=wTx 的值域是 ( − ∞ , + ∞ ) (-\infty,+\infty) (,+) 。所以需要把线性模型的预测进一步处理,找到一个值域在[0,1]区间的模型。于是选择了sigmoid函数。

1.2.3 Sigmoid函数

公式如下:
g ( z ) = 1 1 + e − z g(z) = \frac {1} {1+e^{-z}} g(z)=1+ez1
函数图像如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sOGnN6EN-1602667869838)(D:\kaikeba\第十六章 逻辑回归模型\第一节 逻辑回归模型\sigmoid函数图像.png)]

由图像可以看出,sigmoid函数是一个值域为[0,1]的“s”形曲线,且 lim ⁡ x → − ∞ g ( z ) = 0 \lim\limits_{x\rightarrow-\infty}{g(z)}=0 xlimg(z)=0 lim ⁡ x → + ∞ g ( z ) = 1 \lim\limits_{x\rightarrow+\infty}{g(z)}=1 x+limg(z)=1 。在 ( − ∞ , + ∞ ) (-\infty,+\infty) (,+) 上单调增。

求导有:
g ′ ( z ) = − ( 1 1 + e − z ) 2 ∗ ( − 1 ) ∗ ( e − z ) = e − z ( 1 + e − z ) 2 = 1 + e − z − 1 ( 1 + e − z ) 2 = 1 1 + e − z − 1 ( 1 + e − z ) 2 = 1 1 + e − z ( 1 − 1 1 + e − z ) = g ( z ) ( 1 − g ( z ) ) g'(z) = -(\frac{1}{1+e^{-z}})^2*(-1)*(e^{-z})\\ = \frac{e^{-z}}{({1+e^{-z}})^2}\\ =\frac{1+e^{-z}-1}{({1+e^{-z}})^2}\\ = \frac{1}{{1+e^{-z}}}-\frac{1}{({1+e^{-z}})^2}\\ = \frac{1}{{1+e^{-z}}}(1-\frac{1}{{1+e^{-z}}})\\ =g(z)(1-g(z)) g(z)=(1+ez1)2(1)(ez)=(1+ez)2ez=(1+ez)21+ez1=1+ez1(1+ez)21=1+ez1(11+ez1)=g(z)(1g(z))

1.2.4 逻辑回归模型

z = w T x z=w^Tx z=wTx 代入sigmoid函数,就得到了逻辑回归模型:
y = g ( w T x ) = 1 1 + e − w T x y = g(w^Tx) = \frac{1}{1+e^{-w^Tx}} y=g(wTx)=1+ewTx1

2 损失函数

为了得到训练好的参数w,我们应该最优化模型的损失函数。

2.1 似然(likelihood)

概率是特定环境下某种事件发生的可能性,是在结果产生之前的预测。

似然与其相反,是在确定的结果下推测产生这个结果的可能环境即参数。

比如抛硬币,根据硬币均匀的性质我们推测任何一面朝上的概率均为50%。当随机抛掷一枚硬币1000次,结果500次朝上,500次朝下,那么就容易判断这枚硬币性质均匀,两面朝上概率50%。

因此,设 θ \theta θ 为参数,x表示结果,那么概率为:
P ( x ∣ θ ) P(x|\theta) P(xθ)
相对应的似然为:
L ( θ ∣ x ) L(\theta |x) L(θx)
则两者在数值上有:
L ( θ ∣ x ) = P ( x ∣ θ ) L(\theta |x)=P(x|\theta) L(θx)=P(xθ)
机器学习中更关注似然函数最大值,因为我们的目的是预测某种事件发生的概率,因此我们希望得到导致这个概率的最有可能的条件,即根据已知的事件来找出产生这种结果的最有可能的参数,即似然函数最大值。

2.2 损失函数

损失函数衡量当前的模型输出结果跟实际的输出结果之间的差距,那么根据似然和概率的关系,这里的损失函数的值等于事件发生的总概率,损失函数就是似然函数,因为我们更关注似然函数的最大值,但损失的含义和最大有点不搭,所以给似然函数前加个负号,这样似然函数取最大即损失函数最小。

由于标签只有0和1,因此对于输入的一个样本,看成一个事件的话,设标签为1的概率是p,则
P y = 1 = 1 1 + e − w T x = p P y = 0 = 1 − p P_{y=1} = \frac{1}{1+e^{-w^Tx}} = p\\ P_{y=0} = 1-p Py=1=1+ewTx1=pPy=0=1p
那么事件发生的概率就是:
P ( y ∣ x ) = f ( x ) = { p     y = 1 1 − p y = 0 P(y|x) = f(x) = \begin{cases} \quad p \qquad \ \ \ y=1 \\ 1-p\qquad y=0 \end{cases} P(yx)=f(x)={p   y=11py=0
P ( y i ∣ x i ) = p y i ( 1 − p ) 1 − y i P(y_i|x_i) = p^{y_i}(1-p)^{1-y_i} P(yixi)=pyi(1p)1yi

因此,当有一组采集得到的N个数据 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . ( x n , y n ) } \{(x_1,y_1),(x_2,y_2),...(x_n,y_n) \} {(x1,y1),(x2,y2),...(xn,yn)} ,他们的总概率,即采集到这组样本的概率:

P 总 = P ( y 1 ∣ x 1 ) P ( y 2 ∣ x 2 ) . . . P ( y n ∣ x n ) = ∏ i = 1 n p y i ( 1 − p ) 1 − y i P_总 = P(y_1|x_1)P(y_2|x_2)...P(y_n|x_n)\\ = \prod_{i=1}^np^{y_i}(1-p)^{1-y_i} P=P(y1x1)P(y2x2)...P(ynxn)=i=1npyi(1p)1yi
两边取对数有:
F ( w ) = ln ⁡ ( P 总 ) = ln ⁡ ( ∏ i = 1 n p y i ( 1 − p ) 1 − y i ) = ∑ i = 1 n ln ⁡ [ p y i ( 1 − p ) 1 − y i ] = ∑ i = 1 n [ y i ln ⁡ p + ( 1 − y i ) ln ⁡ ( 1 − p ) ] F(w) = \ln(P_总) = \ln(\prod_{i=1}^np^{y_i}(1-p)^{1-y_i})\\ =\sum_{i=1}^n\ln[{p^{y_i}(1-p)^{1-y_i}]}\\ =\sum_{i=1}^n[y_i\ln{p}+(1-y_i)\ln(1-p)] F(w)=ln(P)=ln(i=1npyi(1p)1yi)=i=1nln[pyi(1p)1yi]=i=1n[yilnp+(1yi)ln(1p)]

F ( w ) F(w) F(w) 就是逻辑回归模型的损失函数,因此现在的问题就变为了找到 w ∗ w^* w 使得 F ( w ) F(w) F(w) 取最大,即 − F ( w ) -F(w) F(w) 取最小。

3 梯度下降法求解

为求出 w ∗ w^* w ,使用梯度下降法。

3.1 梯度下降法

多元函数 f ( x ) = f ( x 1 , x 2 , . . . , x n ) f(x) = f(x_1,x_2,...,x_n) f(x)=f(x1,x2,...,xn) ,其梯度为:
∇ f ( x ) = ( ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , . . . , ∂ f ( x ) ∂ x n ) \nabla f(x) = \left(\frac {\partial f(x)}{\partial x_1},\frac {\partial f(x)}{\partial x_2},...,\frac {\partial f(x)}{\partial x_n}\right) f(x)=(x1f(x),x2f(x),...,xnf(x))
不难看出梯度方向是函数增长速度最快的方向,反之是函数减少速度最快的方向,因为它是由函数对各个x求偏导(在对应x上的切线方向)得到的。

因此如果要计算一个函数的最小值,可以从一个初始点 x ( 0 ) = ( x 1 ( 0 ) , . . . , x n ( 0 ) ) x^{(0)}=(x_1^{(0)},...,x_n^{(0)}) x(0)=(x1(0),...,xn(0)) 开始,基于学习率 η \eta η > 0(可以理解为前进的幅度),当 i ≥ 0 i\geq 0 i0 时,沿梯度反方向即下降方向不断迭代:
x 1 ( i + 1 ) = x 1 ( i ) − η   ⋅   ∂ f ( x ( i ) ) ∂ x 1 , . . . x n ( i + 1 ) = x n ( i ) − η   ⋅   ∂ f ( x ( i ) ) ∂ x n . x_1^{(i+1)} = x_1^{(i)}-\eta \ \cdot \ \frac {\partial f(x^{(i)})}{\partial x_1} ,\\ ...\\ x_n^{(i+1)} = x_n^{(i)}-\eta \ \cdot \ \frac {\partial f(x^{(i)})}{\partial x_n}. x1(i+1)=x1(i)η  x1f(x(i)),...xn(i+1)=xn(i)η  xnf(x(i)).
因此, x i + 1 = g ( x ( i ) ) x^{i+1} = g(x^{(i)}) xi+1=g(x(i))

迭代关系为:
g ( x ) = x − η ∇ f ( x ) g(x) = x - \eta \nabla f(x) g(x)=xηf(x)

3.2 求解

​ 为消除样本个数的影响,损失函数的形式稍微改变为损失函数除以样本个数:
F ( w ) = − 1 N ∑ i = 1 n [ y i ln ⁡ p + ( 1 − y i ) ln ⁡ ( 1 − p ) ] F(w) = -\frac{1}{N}\sum_{i=1}^n[y_i\ln{p}+(1-y_i)\ln(1-p)] F(w)=N1i=1n[yilnp+(1yi)ln(1p)]
根据复合函数的链式求导法则:
∇ F ( w ) = F ′ ( p )   ∗   p ′ ( w ) \nabla F(w) = F'(p)\ * \ p'(w) F(w)=F(p)  p(w)
F ′ ( p ) F'(p) F(p)
F ’ ( p ) = − 1 N ∑ i = 1 n ( y i p − 1 − y i 1 − p ) F’(p) = -\frac{1}{N}\sum_{i=1}^n\left(\frac{y_i}{p}-\frac{1-y_i}{1-p}\right) F(p)=N1i=1n(pyi1p1yi)
p ′ ( w ) p'(w) p(w) :
p = 1 1 + e − w T x p ′ ( w ) = p ( 1 − p ) x p = \frac{1}{1+e^{-w^Tx}}\\ p'(w) = p(1-p)x p=1+ewTx1p(w)=p(1p)x
∇ F ( w ) \nabla F(w) F(w) :
∇ F ( w ) = − 1 N ∑ i = 1 n [ y i ( 1 − p ) − p ( 1 − y i ) ] x i = − 1 N ∑ i = 1 n ( p − y i ) x i \nabla F(w) =-\frac{1}{N}\sum_{i=1}^n[y_i(1-p)-p(1-y_i)]x_i\\ =-\frac{1}{N}\sum_{i=1}^n(p-y_i)x_i F(w)=N1i=1n[yi(1p)p(1yi)]xi=N1i=1n(pyi)xi
初始化一个 w 0 w_0 w0 ,然后给定一个步长 α \alpha α ,通过不断修改 w t w_t wt ,利用梯度下降的方法,不断迭代,直到达到指定的次数或梯度为0。

迭代过程:
w t + 1 = w t − α ∇ F ( w t ) = w t − α 1 N ∑ i = 1 n ( p − y i ) x i w_{t+1} = w_t - \alpha \nabla F(w_t) \\ = w_t -\alpha\frac{1}{N}\sum_{i=1}^n(p-y_i)x_i wt+1=wtαF(wt)=wtαN1i=1n(pyi)xi

4 代码实现

以scikit-learn上的乳腺癌数据集为例:

from sklearn import datasets # 导入数据集
from sklearn.model_selection import train_test_split,GridSearchCV # 导入用于切分数据集的api和用于寻找最优模型和参数的网格搜索
from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
from sklearn.pipeline import Pipeline # 导入管道
from sklearn.preprocessing import PolynomialFeatures,StandardScaler # 导入用于构造多项式特征的api和将数据归一化处理的api
import numpy as np

cancer = datasets.load_breast_cancer() # 导入指定的数据集

X = cancer.data   # 获得数据
y = cancer.target  # 获得标签

print(X.shape)  # (569, 30) 569个样本,每个样本有30个特征
print(y[y==1].shape[0],y[y==0].shape[0]) # (357, 212)

X_train,X_test,y_train,y_test = train_test_split(
    X,y,test_size=0.2,random_state=666
    ) # 按照8:2分割数据集,得到训练集和测试集

def pipeRegression(degree=1,penalty='l2',C=0.1,solver='lbfgs'):
    return Pipeline([
        ('poly',PolynomialFeatures(degree=degree)),
        ('scaler',StandardScaler()),
        ('logist_regression',LogisticRegression(penalty=penalty,C=C,solver=solver))
        ]) # 利用管道机制,把构造多项式特征、归一化、逻辑回归模型封装到一起

print(pipeRegression().get_params()) # 可以查看所有参数

param_grid = [
    {
        'poly__degree':[ i for i in range(1,3)], # 构造的多项式特征数量
        'logist_regression__penalty':['l1','l2'], # 逻辑回归中为了防止过拟合选择的正则化方法
        'logist_regression__C':[i for i in np.linspace(0.1,1,10)], # 正则化中的参数
        'logist_regression__solver':['liblinear','lbfgs','newton-cg','sag'] # 正则化对应的逻辑回归损失函数的优化算法

}
]  # 网格搜索要寻找的超参数范围设置

gs_pipe = GridSearchCV(pipeRegression(),param_grid) # 实例化一个网格搜索对象

gs_pipe.fit(X_train,y_train) #调用fit方法进行训练

print(gs_pipe.best_estimator_) # 获取训练得到的最优模型
print(gs_pipe.best_params_)  # 获取最优的超参数
print(gs_pipe.best_score_)   # 获取最优的预测准确度
print(gs_pipe.best_estimator_.score(X_test,y_test)) # 输出最优模型在测试集上的得分
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值