学习笔记: 机器学习经典算法-逻辑回归(Logistic Regression)

简介: 机器学习经典算法-个人笔记和学习心得分享

逻辑回归(Logistic Regression) 是目前各行业最常用的分类方法,属于线性回归的拓展。

特点
该算法联系了样本的特征和样本发生概率($\hat p = f(x)$),在运算上由于 概率值 本身是一个数值,因此该方法分类方法被称为回归方法。算法最终得到样例的预测概率值 $\hat p$ 用于 分类问题。所以逻辑回归既可以看作是回归算法,也可以看作是分类算法,通常作为分类算法使用,只可以解决二分类问题
$$ \hat y = \left\{ \begin{aligned} 0,\hat p \le 0.5; \\ 1,\hat p \ge 0.5 \end{aligned} \right. $$

1、逻辑回归的基本原理

逻辑回归源于线性回归的拓展,具体思路是将线性回归的样本输出预测值到样本概率值的一个转换过程。在线性回归$\hat y = f(x) = \theta^T \cdot x_b$中,有预测的样本标记输出值 $\hat y \in (-\infty,\infty)$。为了使样本输出值 $\hat y $ 转换为概率值 $\hat p \in [0,1]$,可通过$Sigmoid$ 函数转换 样本值样本概率 $\hat p = \sigma(\theta^T\cdot x_b)$。

关于Sigmoid 函数
$$\sigma (t) = \frac {1}{1+e^{-t}}$$

Sigmoid 曲线具有如下性质:

  • 函数曲线最左端无限趋近于0,函数曲线最右端无限趋近于1;值域 $\sigma (t) \in (0,1)$,因此很方便地用于表达概率;
  • $ \left \{ \begin{array}. p > 0.5, t>0; \\ p<0.5,t<0 \end{array} \right.$

使用 $Sigmoid$ 函数转换样本值为样本概率 $\hat p = \frac {1}{1+e^{-(\theta^T\cdot x_b)}}$,进一步基于样本概率进行二分类任务 $\hat y = \left\{ \begin{array}. 1, \hat p \ge 0.5; \\0,\hat p \le 0.5. \end{array}\right.$

1.2 逻辑回归的优化目标

对于给定的样本集$X$和样本分类$y$,找到参数$\theta$, 使得用$Sigmoid$ 转换可以最大程度获得样本数据集$X$对应的分类输出$y$。

1.2.1 目标函数的定义

对于二分类问题,样本输出标记取值为离散变量 $y\in \{0,1\}$。使用 $Sigmoid $框架来获取样本特征到样本概率 ,再实现样本离散值标记的转换的时候。由于原始样本标记是一个离散值,而逻辑回归输出标记是一个分类概率值,意味着不能通过与类似线性回归等算法建立预测值与标记值的误差函数作为优化目标。

逻辑回归的损失函数定义建立在离散的样本标记上,定义如下 惩罚函数

$cost = \left\{ \begin{array}. \small {如果 y=1 , \hat p 越小,cost越大} \\ \small {如果 y=0 , \hat p 越大,cost越大}\end{array}\right.$
在进行逻辑回归的时候,如果样本 真值为1,当前$\theta$下的预测概率值$\hat p $越小,则有惩罚越大;如果样本 真值为0,当前$\theta$下的预测概率值$\hat p $越大,则有惩罚越大;从而回归的目标为取得 最小惩罚下 对应的 参数$\theta$值

1.2.2 惩罚函数的选取

$cost = \left\{ \begin{array}. -log(\hat p) \ \ \ \ \ \ \ \ \ \ \ if \ \ \ y = 1 \\ -log(1 - \hat p) \ \ \ \ if \ \ \ y = 0 \end{array}\right.$

  • 当$y = 1$时,使用 $ cost(\hat p) = -log(\hat p)$ 作为惩罚函数,$\hat p \in [0,1]$ ,当 $\hat p \to 0$ 的时候有 惩罚$cost(\hat p) $ 趋于正无穷;只有$\hat p \to 1$ 时惩罚$cost(\hat p) $ 才会变小。
  • 当$y = 0$时,使用 $ cost(\hat p) = -log(1- \hat p)$ 作为惩罚函数,$\hat p \in [0,1]$ ,当 $\hat p \to 1$ 的时候有 惩罚$cost(\hat p) $ 趋于正无穷;只有$\hat p \to 0$ 时惩罚$cost(\hat p) $ 才会变小。

进一步将分条件的 cost 函数联合为一个函数:
$$cost(\hat p) = \left\{ \begin{array}. -log(\hat p) \ \ \ \ \ \ \ \ \ \ \ if \ \ \ y = 1 \\ -log(1 - \hat p) \ \ \ \ if \ \ \ y = 0 \end{array}\right. \rightarrow cost(\hat p) = y*(-log(\hat p)) + (1-y)*(-log(1-\hat p ))$$
当$y =1 ,cost$ 函数仅表示为 $-log(\hat p) \ \ \ \ \ \ $的结果;
当$y =0 ,cost$ 函数仅表示为 $-log(1- \hat p)$的结果。

全数据集X的样本损失函数表达为:
$$J(\theta) = \frac {1}{m} \sum _{i=1}^{m}{cost(\hat p)} = -\frac {1}{m} \sum _{i=1}^{m}{y^{(i)}log(\hat p^{(i)})+(1-y^{(i)}) log(1- \hat p^{(i)})}$$
$$\small {\bf 第(i) 个样本的概率估计值} \ \ \ \ \ \hat p^{(i)} = \sigma (\theta^Tx_b^{(i)}) = \frac {1}{1+e^{-\theta^Tx_b^{(i)}}}$$
回归目标是找到一组$\theta$是的$J(\theta)$得到最小值;逻辑回归的损失函数 无正规方程解,$J(\theta)$ 本质是一个 凸函数(Convex),存在全局最优解,只能用 梯度下降法求解

1.2.3 $J(\theta)$的梯度

对于损失函数$J(\theta)$有如下形式:
$$J(\theta) = -\frac {1}{m} \sum _{i=1}^{m}{y^{(i)}log(\sigma(t))+(1-y^{(i)}) log(1- \sigma(t))} $$

  • 根据求导链式法则对前半部分 $y^{(i)}log(\sigma(t))$ 求导
    首先,令 $t = \theta^Tx_b^{(i)}$
    $\because \sigma (t) = \frac {1}{1+e^{(-t)}} = (1+e^{(-t)})^{-1}$
    $\therefore \sigma (t)' = -1(1+e^{(-t)})^{-2}*e^{(-t)}*(\ln{e^{-1}}) = (1+e^{-t})^{-2} \cdot e^{-t}$
    $\because \log (\sigma {(t)})' = \frac {1}{\sigma (t)} \cdot \sigma {(t)}' = \frac {1}{\sigma (t)} \cdot (1+e^{-t})^{-2} \cdot e^{-t} = (1+e^{-t}) \cdot (1+e^{-t})^{-2} \cdot e^{-t} = (1+e^{-t})^{-1} \cdot e^{-t} = \frac {1+e^{-t} -1}{1+e^{-t}} = 1 - \frac {1}{1+e^{-t}}$
    $\therefore \log (\sigma {(t)})' = 1- \sigma(t)$

$\therefore[y^{(i)}log(\sigma(t))]' = \frac {\partial (y^{(i)} \log(\sigma(\theta^Tx_b^{(i)})))}{\partial(\theta_j)} = y^{(i)}*(1-\sigma(\theta^Tx_b^{(i)}))*x_{b\_j}^{(i)}$

..........................................................................................

  • 根据求导链式法则对后半部分 $(1-y^{(i)})log(1 \sigma(t))$ 求导
    $[\log(1-\sigma(t))]' = \frac {1}{1-\sigma(t)}*(-\sigma(t))' = \frac {1}{1-\sigma(t)}* -(1+e^{-t})^{-2} \cdot e^{-t} = -\frac {1+e^{-t}}{e^{-t}}*(1+e^{-t})^{-2} \cdot e^{-t} = -(1+e^{-t})^{-1} = -\sigma(t)$

$\therefore [(1-y^{(i)})\log(1-\sigma(t))]' = \frac {\partial ((1-y^{(i)})\log(1-\sigma(\theta^Tx_b^{(i)})))}{\partial \theta_j} = (1-y^{(i)})*(-\sigma(\theta^Tx_b^{(i)}))*x_{b\_j}^{(i)}$
..........................................................................................
联合前后部分函数的求导结果为 $\nabla J(\theta_j)$
$\nabla J(\theta_j) = -\frac {1}{m} \sum _{i=1}^{m} y^{(i)}*(1-\sigma(\theta^Tx_b^{(i)}))*x_{b\_j}^{(i)} + (1-y^{(i)})*(-\sigma(\theta^Tx_b^{(i)}))*x_{b\_j}^{(i)}$
$\nabla J(\theta_j) = \frac {1}{m} \sum _{i=1}^{m} (\sigma(\theta^Tx_b^{(i)}) - y^{(i)} )\cdot x_{b\_j}^{(i)} = \frac {1}{m} \sum _{i=1}^{m} (\hat y^{(i)} - y^{(i)} )\cdot x_{b\_j}^{(i)}$
推广到 所有$\theta$
$\nabla J(\theta)= \begin{bmatrix} \partial J/ \partial \theta _{0} \\ \partial J/ \partial \theta _{1} \\ ... \\ \partial J/ \partial \theta _{n} \end{bmatrix} = \frac {1}{m} \begin{bmatrix} \sum_{i=1}^{m}{\sigma ( X_{b}^{(i)}\theta - y^{i}) \cdot ( \ 1 \ )} \\ \sum_{i=1}^{m}{\sigma ( X_{b}^{(i)}\theta - y^{i}) \cdot (x^{i}_1)} \\... \\ \sum_{i=1}^{m}{\sigma ( X_{b}^{(i)}\theta - y^{i}) \cdot (x^{i}_n)} \end{bmatrix} = \frac {1}{m} \cdot X^T_b\cdot (\sigma(X_b\theta) - y)$

逻辑回归损失函数的梯度结果与线性回归极其类似!!!

1.2.4 参数$\theta$ 梯度下降法求解一般过程

### Prepare data
import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
from sklearn.model_selection import train_test_split
Train_X,Test_X,Train_Y,Test_Y = train_test_split(iris.data[iris.target < 2,:2],iris.target[iris.target < 2],test_size= 0.2,random_state=666)
X_b = np.hstack([np.ones((len(Train_X),1)),Train_X])
y = Train_Y

### sigmoid function
def _sigmoid(t):
    return 1 / (np.exp(-t) + 1)

### Loss Function
def J(theta,X_b,y):
    y_hat = _sigmoid(X_b.dot(theta))
    try:
        return - np.sum(y*np.log(y_hat)+(1-y)*np.log(1-y_hat))/len(y)
    except:
        return float('inf') ### 异常检测,如果出现异常返回浮点数最大值float('inf')
### Derivative function
def dJ(X_b,y,theta):
    return X_b.T.dot(_sigmoid(X_b.dot(theta)) - y) / len(X_b)
### Gradient Descent
eta = .000001 ### 学习率
epsilon = 1e-8 ### 定义一个误差范围,当初始点开始滚动,如果当前点位与一点位函数值误差小于定义的epsilon误差范围,认为当前点为就是最优解。
theta_lst = [np.random.randint(10,size = X_b.shape[1])+ np.random.normal(size = X_b.shape[1])] ### 随机化滚落初始点
while True:
    gradient = dJ(X_b,y,theta_lst[-1])
    theta_lst.append(theta_lst[-1] - eta * gradient)

    if(abs(J(theta_lst[-1],X_b,y) - J(theta_lst[-2],X_b,y)) < epsilon):break
    if(len(theta_lst) > 1e4): break       ### 循环1e4次以后如果没有取得最优解将退出循环

print(theta_lst[-1])

1.2.5 scikit-learn 框架下线性分布数据的逻辑回归

import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
from sklearn.model_selection import train_test_split
Train_X,Test_X,Train_Y,Test_Y = train_test_split(iris.data[iris.target < 2,:2],iris.target[iris.target < 2],random_state=666)

from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(Train_X,Train_Y)
log_reg.score(Test_X,Test_Y)
log_reg.decision_function(Test_X) ### 获取 θ^T·x_b 的决策值 ,

2、非线性数据的逻辑回归

对于 线性分布的数据,意味着其样本在特征空间的类别分布可以被 一条直线或(超平面) 所分割,对应 决策边界 表示为线性方程 $\theta^Tx_b = 0$。对于 非线性分布的数据 , 其在特征空间中的类别分布无法被 一条直线或(超平面) 所分割。

多项式回归 一章中,非线性数据的回归问题可以通过构造特征转换为线性回归问题。同理在 逻辑回归 中处理非线性分布数据的判别问题中也可以通过 添加多项式项(构造特征) 再进行 逻辑回归,从而 获得任意形状的决策边界

2.2 scikit-learn 框架下非线性分布数据的逻辑回归

### Prepare data
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(666)
X = np.random.normal(0,1,size = (200,2)) 
y = np.array(X[:,0]**2 +X[:,1] < 1.5 ,dtype='int') ### 令曲线 -x_0^2 - x_1 + 1.5 = 0 下方的样本分类为 1
for _ in range(20):  ### 生成分类噪音
    y[np.random.randint(200)] = 1  

### Darw sample distribution
plt.scatter(X[y == 0 ,0],X[y == 0 ,1])
plt.scatter(X[y == 1 ,0],X[y == 1 ,1])
plt.show()

### Logistic Regression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

def PolynomialLogisticRegression(degree):
    return Pipeline([
        ('poly',PolynomialFeatures(degree=degree)),
        ('std_scaler',StandardScaler()),
        ('logistic_reg',LogisticRegression())
    ])
poly_log_reg = PolynomialLogisticRegression(degree= 2)
poly_log_reg.fit(Train_X,Train_Y)
poly_log_reg.score(Test_X,Test_Y)

3、逻辑回归中添加正则化

对于线性算法,当添加上多项式项时模型复杂度随着随着多项式项阶数(degree)的上升而指数级增大,进而容易发生对 训练集过拟合 的问题,在逻辑回归中也是如此(表现在决策边界的规整情况)。解决模型过拟合问题的常规处理为向模型添加 正则化 ,通过约束参数大小从而提高模型的泛化能力降低方差。

3.2 逻辑回归的正则项

  • 损失函数添加 L1 正则项
    $$C\cdot J(\theta) + L_1 = C\cdot J(\theta) + \sum_{i=1}^{n}{|\theta_i|}$$
  • 向损失函数添加 L2 正则项
    $$C\cdot J(\theta) + \alpha L_2 = C\cdot J(\theta) + \frac {1}{2}\sum_{i=1}^{n}{\theta_i}^2$$

3.3 scikit-learn 框架下的逻辑回归添加正则项

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

def PolynomialLogisticRegression(degree,c,penalty = 'l2'): 
    return Pipeline([
        ('poly',PolynomialFeatures(degree=degree)),
        ('std_scaler',StandardScaler()),
        ('logistic_reg',LogisticRegression(solver= 'liblinear',C = c,penalty = penalty)) ### 参数C 指定正则化约束强度; 参数penalty 指定添加正则项的类别(L1,L2)
    ])
poly_log_reg = PolynomialLogisticRegression(degree= 20,c = .1,penalty='l1',)
poly_log_reg.fit(Train_X,Train_Y)
poly_log_reg.score(Test_X,Test_Y)

4、逻辑回归对多分类问题的解决方案

4.1 OvR (One vs Rest)

将多个类别每次选取一个类(One)设定为 1,其余类别((Rest))则设定为 0 ,从而转换为 多个二分类任务。这样对于 $n$ 个类别就会创建 $n$ 个分类模型,对新样例进行 $n$ 个模型的预测,选择分类得分最高的作为新样例的分类。
缺点:时间复杂度高,效率低。

sklearn的逻辑回归 OvR 多分类支持

from sklearn.linear_model import LogisticRegression
OvR_logreg = LogisticRegression(multi_class='ovr')

4.2 OvO (One vs One)

将多个类别每次挑选其中两个类别构建一个二分类模型,这样对于数据集中的 $n$ 个类别就会组合出$C_{n}^2$ 个 二分类模型,然后分别应用这些分类器对新样例进行预测,最后选择这 $C_{n}^2$ 个分类器对 新样例 的预测结果中出现最多的类别作为新样例的分类。
优点:由于每个分类器都是对两个真实类比的比较,不像 OvR 任务中 Rest 部分存在混杂类别带来的干扰信息,因此 OvO 分类器更倾向于得到新样例的真实类别,也即分类准确度更高。
缺点:时间复杂度比 OvR 还高,效率低。

sklearn的逻辑回归 OvO 多分类支持

from sklearn.linear_model import LogisticRegression
OvO_logreg = LogisticRegression(multi_class='multinomial',solver="newton-cg")

4.3 sklearn 框架下转换二分类机为多分类器

### 创建逻辑回归二分类器
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()

from sklearn.multiclass import OneVsOneClassifier
ovo = OneVsOneClassifier(log_reg) ### 封装逻辑回归二分类器为 ovo 多分类器
ovo.fit((Train_X,Train_Y)
ovo.score(Test_X,Test_Y)

from sklearn.multiclass import OneVsRestClassifier
ovr = OneVsRestClassifier(log_reg) ### 封装逻辑回归二分类器为 ovr 多分类器
ovr.fit((Train_X,Train_Y)
ovr.score(Test_X,Test_Y)
目录
相关文章
|
10月前
|
机器学习/深度学习 数据采集 人工智能
【机器学习算法篇】K-近邻算法
K近邻(KNN)是一种基于“物以类聚”思想的监督学习算法,通过计算样本间距离,选取最近K个邻居投票决定类别。支持多种距离度量,如欧式、曼哈顿、余弦相似度等,适用于分类与回归任务。结合Scikit-learn可高效实现,需合理选择K值并进行数据预处理,常用于鸢尾花分类等经典案例。(238字)
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
1865 6
|
机器学习/深度学习 数据采集 人工智能
20分钟掌握机器学习算法指南
在短短20分钟内,从零开始理解主流机器学习算法的工作原理,掌握算法选择策略,并建立对神经网络的直观认识。本文用通俗易懂的语言和生动的比喻,帮助你告别算法选择的困惑,轻松踏入AI的大门。
1020 8
|
机器学习/深度学习 存储 Kubernetes
【重磅发布】AllData数据中台核心功能:机器学习算法平台
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。
|
机器学习/深度学习 人工智能 自然语言处理
AI训练师入行指南(三):机器学习算法和模型架构选择
从淘金到雕琢,将原始数据炼成智能珠宝!本文带您走进数字珠宝工坊,用算法工具打磨数据金砂。从基础的经典算法到精密的深度学习模型,结合电商、医疗、金融等场景实战,手把手教您选择合适工具,打造价值连城的智能应用。掌握AutoML改装套件与模型蒸馏术,让复杂问题迎刃而解。握紧算法刻刀,为数字世界雕刻文明!
555 6
|
机器学习/深度学习 人工智能 算法
机器学习算法的优化与改进:提升模型性能的策略与方法
机器学习算法的优化与改进:提升模型性能的策略与方法
2662 13
机器学习算法的优化与改进:提升模型性能的策略与方法
|
机器学习/深度学习 算法 数据安全/隐私保护
基于机器学习的人脸识别算法matlab仿真,对比GRNN,PNN,DNN以及BP四种网络
本项目展示了人脸识别算法的运行效果(无水印),基于MATLAB2022A开发。核心程序包含详细中文注释及操作视频。理论部分介绍了广义回归神经网络(GRNN)、概率神经网络(PNN)、深度神经网络(DNN)和反向传播(BP)神经网络在人脸识别中的应用,涵盖各算法的结构特点与性能比较。
|
机器学习/深度学习 算法 网络安全
CCS 2024:如何严格衡量机器学习算法的隐私泄露? ETH有了新发现
在2024年CCS会议上,苏黎世联邦理工学院的研究人员提出,当前对机器学习隐私保护措施的评估可能存在严重误导。研究通过LiRA攻击评估了五种经验性隐私保护措施(HAMP、RelaxLoss、SELENA、DFKD和SSL),发现现有方法忽视最脆弱数据点、使用较弱攻击且未与实际差分隐私基线比较。结果表明这些措施在更强攻击下表现不佳,而强大的差分隐私基线则提供了更好的隐私-效用权衡。
477 14
|
人工智能 编解码 算法
使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理
使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理
736 0
|
算法
PAI下面的gbdt、xgboost、ps-smart 算法如何优化?
设置gbdt 、xgboost等算法的样本和特征的采样率
740 2

热门文章

最新文章