机器学习——逻辑回归

一、简介

        逻辑回归(Logistic Regression)是一种广泛应用于统计学和机器学习领域的分类方法,尤其在二分类问题中表现突出。它预测的是一个事件发生的概率,即模型的输出是一个介于0和1之间的值,通常这个输出被解释为属于某个类别的概率。

注意:逻辑回归虽然名字中有回归二字,但是它不是回归算法,而是分类算法。

二、基本原理

分类的本质:在空间中找到一个决策边界来完成分类的决策

逻辑回归:线性回归可以预测连续值,但是不能解决分类问题,我们需要根据预测的结果判定其属于正类还是负类。逻辑回归模型通过一个线性函数将特征变量的线性组合映射到一个S型曲线(sigmoid function)上,从而得到一个概率值。

        逻辑回归在二分类问题上表现出色,对于处理二分类问题。由于分成两类,我们便让其中一类标签为0,另一类为1。因此我们需要一个函数,对于输入的每一组数据,都能映射成0~1之间的数。并且如果函数值大于0.5,就判定属于1,否则属于0。而且函数中需要待定参数,通过利用样本训练,使得这个参数能够对训练集中的数据有很准确的预测。

1.线性预测

        一个二分类问题给的条件:分类标签Y {0,1},特征自变量X{x1,x2,……,xn},需要根据我们现在手头上有的特征X来判别它应该是属于哪个类别(0还是1),因此我们需要找一个模型,即一个关于X的函数来得出分类结果(0或1)。

        如果数据是有两个指标,可以用平面的点来表示数据,其中一个指标为x轴,另一个为y轴;从本质上来说,逻辑回归训练后的模型是平面的一条直线(p=2),或是平面(p=3),超平面(p>3)。并且这条线或平面把空间中的散点分成两半,属于同一类的数据大多数分布在曲线或平面的同一侧。

        逻辑回归中,我们先找一个线性模型来由X预测Y

z = w^{T} x + b

        但是很明显,这样的函数图像是类似一条斜线,使用线性的函数来拟合规律后取阈值的办法是行不通的,行不通的原因在于拟合的函数太直,离群值(也叫异常值)对结果的影响过大。

        并且,线性模型也难以达到我们想要的二分类(0或1)的取值。

        通过求出函数z,线性回归便完成了使用输入的特征矩阵X得到了一组连续型的标签值y_pred的操作,接下来我们需要让这条直线变弯,并且将其控制在0~1之间,将特征变量的线性组合映射到一个S型曲线(sigmoid function)上,从而得到一个概率值。

2.sigmoid函数

        Sigmoid函数是一种广泛应用于逻辑回归中的数学函数,它将任意实数映射到(0, 1)区间内,使其成为表示概率的理想选择。在逻辑回归中,Sigmoid函数用于将线性回归模型的输出转换为概率形式。

Sigmoid函数的数学表达式通常写作:

g(z) = \frac{1}{1+e^{-z}}

        

特点

平滑曲线:Sigmoid函数是一个平滑的S型曲线,它在 𝑧接近正无穷时趋近于1,在 𝑧 接近负无穷时趋近于0。

连续性:Sigmoid函数在整个实数域上都是连续的,这使得它在数学处理和优化算法中非常有用。

非线性:尽管Sigmoid函数看起来像是线性函数的简单扩展,但它实际上是一个非线性函数,这使得它能够用于非线性回归和分类问题。

中心在(0, 0.5):Sigmoid函数的中心点在(0, 0.5),这意味着当输入 𝑧=0 时,输出为0.5。

单调递增:Sigmoid函数在其定义域内是单调递增的,即随着 𝑧 的增加,𝜎(𝑧) 也增加。

图像

将线性模型的结果,投影到sigmoid函数上

三、求解参数

1.极大似然估计

极大似然估计是数理统计中参数估计的一种重要方法。其思想就是一个事件发生了,那么发生这个事件的概率就是最大的。对于样本i,其类别为。对于样本i,可以把看成是一种概率。yi对应是1时,概率是h(xi),即xi属于1的可能性;yi对应是0时,概率是1-h(xi),即xi属于0的可能性 。那么它构造极大似然函数

其中i从0到k是属于类别1的个数k,i从k+1到n是属于类别0的个数n-k。由于y是标签0或1,所以上面的式子也可以写成:

这样无论y是0还是1,其中始终有一项会变成0次方,也就是1,和第一个式子是等价的。

为了方便,我们对式子取对数。因为是求式子的最大值,可以转换成式子乘以负1,之后求最小值。同时对于n个数据,累加后值会很大,之后如果用梯度下降容易导致梯度爆炸。所以可以除以样本总数n。

求最小值方法很多,机器学习中常用梯度下降系列方法。也可以采用牛顿法,或是求导数为零时w的数值等。

2.梯度下降

        梯度下降(Gradient Descent)是一种优化算法,用于最小化一个函数,通常用于机器学习中的参数优化问题。其基本思想是,从某个初始点开始,沿着函数的梯度(即导数)的反方向进行迭代搜索,每次迭代都会更新当前点的位置,直到找到一个局部最小值。如图,

梯度下降算法的步骤通常包括:

  1. 初始化参数:选择一个初始点作为参数的起始值。
  2. 计算梯度:在当前参数的位置上计算目标函数的梯度,即导数。
  3. 更新参数:根据梯度和学习率(一个超参数,控制步长的大少)更新参数。
  4. 迭代:重复步骤2和3,直到满足停止条件,如梯度足够小、达到预定迭代次数或参数更新量很小。

四、代码实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# 设置随机种子
seed_value = 2023
np.random.seed(seed_value)

# Sigmoid激活函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 定义逻辑回归算法
class LogisticRegression:
    def __init__(self, learning_rate=0.003, iterations=100):
        self.learning_rate = learning_rate # 学习率
        self.iterations = iterations # 迭代次数

    def fit(self, X, y):
        # 初始化参数
        self.weights = np.random.randn(X.shape[1])
        self.bias = 0

        # 梯度下降
        for i in range(self.iterations):
            # 计算sigmoid函数的预测值, y_hat = w * x + b
            y_hat = sigmoid(np.dot(X, self.weights) + self.bias)

            # 计算损失函数
            loss = (-1 / len(X)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))

            # 计算梯度
            dw = (1 / len(X)) * np.dot(X.T, (y_hat - y))
            db = (1 / len(X)) * np.sum(y_hat - y)

            # 更新参数
            self.weights -= self.learning_rate * dw
            self.bias -= self.learning_rate * db

            # 打印损失函数值
            if i % 10 == 0:
                print(f"Loss after iteration {i}: {loss}")

    # 预测
    def predict(self, X):
        y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
        y_hat[y_hat >= 0.5] = 1
        y_hat[y_hat < 0.5] = 0
        return y_hat
    
    # 精度
    def score(self, y_pred, y):
        accuracy = (y_pred == y).sum() / len(y)
        return accuracy

# 导入数据
iris = load_iris()
X = iris.data[:, :2]
y = (iris.target != 0) * 1

# 划分训练集、测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=seed_value)

# 训练模型
model = LogisticRegression(learning_rate=0.03, iterations=1000)
model.fit(X_train, y_train)

# 结果
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)

score_train = model.score(y_train_pred, y_train)
score_test = model.score(y_test_pred, y_test)

print('训练集Accuracy: ', score_train)
print('测试集Accuracy: ', score_test)

# 可视化决策边界
x1_min, x1_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
x2_min, x2_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, 100), np.linspace(x2_min, x2_max, 100))
Z = model.predict(np.c_[xx1.ravel(), xx2.ravel()])
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.show()

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值