机器学习 - 使用逻辑回归实现分类

逻辑回归是一种数据分析技术,它使用数学来找出两个数据因子之间的关系。然后,使用此关系根据其中一个因子预测另一个因子的值。

本文分为 理论介绍Python 代码实现 两部分

👉 点此直接跳转到代码实现

逻辑回归算法

一般来说逻辑回归用于处理二元分类问题,即

$$ y \subset \{0, 1\} $$

当样本中有多个类别时

$$ y \subset \{0, 1, 2, \dots, n\} $$

Logistic Regression 和 Linear Regression 的原理是相似的,可以简单地描述为以下过程:

  1. 找一个合适的预测函数,一般表示为 $h$ 函数,该函数就是我们需要找的分类函数,它用来预测输入数据的判断结果。这个过程非常关键,需要对数据有一定的了解或分析,知道或者猜测预测函数的“大概”形式,比如是线性函数还是非线性函数。

  2. 构造一个成本函数(损失函数),该函数表示预测的输出($h$)与训练数据类别($y$)之间的偏差,可以是二者之间的差($h - y$)或者是其他的形式。综合考虑所有训练数据的“损失”,将成本求和或者求平均,记为 $J(\theta)$ 函数,表示所有训练数据预测值与实际类别的偏差。

  3. 显然,$J(\theta)$ 函数的值越小表示预测函数越准确(即 $h$ 函数越准确),所以这一步需要做的是找到 $J(\theta)$ 函数的最小值。找到函数的最小值有不同的方法,Logistic Regression 实现时通常使用的是梯度下降法(Gradient Descent)。

逻辑回归模型

预测函数

Logistic Regression 虽然名字里带“回归”,但实际上是一种分类方法,用于两分类问题(即输出只有两种)。根据上述步骤的说明,需要先找到一个预测函数($h$),显然,该函数的输出必须是两个值(分别代表两个类别),所以利用了 Logistic 函数(或称为 Sigmoid 函数),函数形式为

$$ h(x) = \frac{1}{1 + e^{-\theta^T x}} $$

$h_\theta(x)$ 函数的值有特殊的含义,它表示结果取 1 的概率。因此对于输入 $x$,分类结果类别为 1 和类别 0 的概率分布为

$$ P(y = 1 | x; \theta) = h_\theta(x) $$$$ P(y = 0 | x; \theta) = 1 - h_\theta(x) $$

代价函数

$$ J(\theta) = -\frac{1}{m} \sum_{i=1}^{m} \left[ y^{(i)} \log(h(x^{(i)})) + (1 - y^{(i)}) \log(1 - h(x^{(i)})) \right] $$

这里的 $J(\theta)$ 是基于最大似然估计推导得到的。

$$ P(y | x; \theta) = (h_\theta(x))^y (1 - h_\theta(x))^{1 - y} $$

取似然函数为

$$ L(\theta) = \prod_{i=1}^{m} P(y^{(i)} | x^{(i)}; \theta) = \prod_{i=1}^{m} (h_\theta(x^{(i)}))^{y^{(i)}} (1 - h_\theta(x^{(i)}))^{1 - y^{(i)}} $$

对数似然函数为

$$ l(\theta) = \log L(\theta) = \sum_{i=1}^{m} \left[ y^{(i)} \log h_\theta(x^{(i)}) + (1 - y^{(i)}) \log(1 - h_\theta(x^{(i)})) \right] $$

最大似然估计就是要求使 $J(\theta)$ 取最大值时的 $\theta$,其实可以使用梯度上升法求解,求得的 $\theta$ 就是最佳参数。

$$ J(\theta) = -\frac{1}{m} l(\theta) $$

因为乘了一个负的系数 $\frac{1}{m}$,所以 $J(\theta)$ 取最小值时的 $\theta$ 为所求的最佳参数。

梯度下降

求 $J(\theta)$ 的最小值可以使用梯度下降法,根据梯度下降法可得 $\theta$ 的更新过程:

$$ \theta_j := \theta_j - \alpha \cdot \frac{1}{m} \sum_{i=1}^{m} (h(x) - y) x_j^{(i)} $$

其中 $\alpha$ 为学习率。

逻辑回归在形式上更新参数与线性回归相同,实则不同。在线性回归中,$h(x)$ 是一个线性函数,而在逻辑回归中,$h(x)$ 是一个 sigmoid 函数。

Python 代码实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegressionCV
import numpy as np
np.random.seed(10)

if __name__ == '__main__':
    # 使用 sklearn 中的 make_classification 函数构建二分类的数据,样本数量为 100,样本种类为 2
    X, y = make_classification(n_samples=100, n_classes=2, n_features=2, n_informative=2, n_redundant=0, random_state=10)
    
    # 将数据集拆分成测试集与训练集,训练集占所有数据的 80%
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10)
    
    # 实例化一个逻辑回归分类器,使用默认参数
    model = LogisticRegressionCV(cv=5, random_state=10).fit(X_train, y_train)
    
    # 进行模型评估并打印准确率
    accuracy = model.score(X_test, y_test)
    print(f"{accuracy:.1f}")