学习笔记: 机器学习经典算法-逻辑回归(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)
目录
相关文章
|
26天前
|
机器学习/深度学习 算法 知识图谱
【机器学习】逻辑回归原理(极大似然估计,逻辑函数Sigmod函数模型详解!!!)
【机器学习】逻辑回归原理(极大似然估计,逻辑函数Sigmod函数模型详解!!!)
|
26天前
|
机器学习/深度学习 存储 自然语言处理
【机器学习】基于逻辑回归的分类预测
【机器学习】基于逻辑回归的分类预测
|
26天前
|
机器学习/深度学习 算法
【机器学习】逻辑回归介绍(逻辑回归应用场景,原理,损失及优化详解!!!)
【机器学习】逻辑回归介绍(逻辑回归应用场景,原理,损失及优化详解!!!)
|
3月前
|
机器学习/深度学习 人工智能 算法
【人工智能】机器学习、分类问题和逻辑回归的基本概念、步骤、特点以及多分类问题的处理方法
机器学习是人工智能的一个核心分支,它专注于开发算法,使计算机系统能够自动地从数据中学习并改进其性能,而无需进行明确的编程。这些算法能够识别数据中的模式,并利用这些模式来做出预测或决策。机器学习的主要应用领域包括自然语言处理、计算机视觉、推荐系统、金融预测、医疗诊断等。
56 1
|
3月前
|
机器学习/深度学习 算法
【机器学习】SVM面试题:简单介绍一下SVM?支持向量机SVM、逻辑回归LR、决策树DT的直观对比和理论对比,该如何选择?SVM为什么采用间隔最大化?为什么要将求解SVM的原始问题转换为其对偶问题?
支持向量机(SVM)的介绍,包括其基本概念、与逻辑回归(LR)和决策树(DT)的直观和理论对比,如何选择这些算法,SVM为何采用间隔最大化,求解SVM时为何转换为对偶问题,核函数的引入原因,以及SVM对缺失数据的敏感性。
65 3
|
3月前
|
机器学习/深度学习 算法
【机器学习】支持向量机SVM、逻辑回归LR、决策树DT的直观对比和理论对比,该如何选择(面试回答)?
文章对支持向量机(SVM)、逻辑回归(LR)和决策树(DT)进行了直观和理论上的对比,并提供了在选择这些算法时的考虑因素,包括模型复杂度、损失函数、数据量需求、对缺失值的敏感度等。
54 1
|
3月前
|
机器学习/深度学习
【机器学习】逻辑回归LR的推导及特性是什么,面试回答?
逻辑回归(LR)的推导和特性的详细解释,包括其作为二分类模型的基本原理、损失函数(对数损失函数),以及决策树的特性,如不需要先验假设、高效性、易解释性、对缺失值的不敏感性,以及对冗余属性的鲁棒性。
38 1
|
6月前
|
机器学习/深度学习 存储 搜索推荐
利用机器学习算法改善电商推荐系统的效率
电商行业日益竞争激烈,提升用户体验成为关键。本文将探讨如何利用机器学习算法优化电商推荐系统,通过分析用户行为数据和商品信息,实现个性化推荐,从而提高推荐效率和准确性。
233 14
|
6月前
|
机器学习/深度学习 算法 数据可视化
实现机器学习算法时,特征选择是非常重要的一步,你有哪些推荐的方法?
实现机器学习算法时,特征选择是非常重要的一步,你有哪些推荐的方法?
108 1
|
6月前
|
机器学习/深度学习 算法 搜索推荐
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)

热门文章

最新文章