基本原理

逻辑回归是一种分类模型,常用于解决二分类问题。其基本思想是假设数据服从伯努利分布,基于最大似然估计推导的方法,通过似然函数的对数变化,运用梯度下降的方法求解参数,来达到将数据二分类的目的。
逻辑回归的公式可以表示为:h(x) = g(w*x + b)
其中,w和b是模型参数,x是输入向量,g是sigmoid函数,h(x)表示模型预测为1的概率。
逻辑回归的优化目标是最大化似然函数,即最小化损失函数。损失函数可以表示为:J(w,b) = - log[p(y=1|x,w,b)] - log[p(y=0|x,w,b)]
其中,p(y=1|x,w,b)和p(y=0|x,w,b)分别表示样本点属于类别1和类别0的概率。
为了求解最优的w和b,我们可以通过梯度下降法来迭代更新参数。梯度下降法的迭代公式为:
w = w - α * ∂J(w,b) / ∂w
b = b - α * ∂J(w,b) / ∂b
其中,α是学习率,∂J(w,b) / ∂w和∂J(w,b) / ∂b分别表示损失函数对w和b的梯度。
通过迭代更新w和b,我们可以逐渐逼近最优解,使得模型的预测概率更接近真实概率,从而达到分类的目的。

import numpy as np
# import matplotlib.pyplot as plt

class LogisticRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000):
        """
        初始化逻辑回归模型的参数。

        Parameters:
            learning_rate (float): 学习率,用于控制参数更新的步长。
            n_iterations (int): 迭代次数,控制梯度下降的步数。
        """
        self.learning_rate = learning_rate
        self.n_iterations = n_iterations
        self.theta = None

    def sigmoid(self, z):
        """
        Sigmoid 函数,用于将线性输出映射到 (0, 1) 范围内的概率。

        Parameters:
            z (numpy.ndarray): 线性输出。

        Returns:
            numpy.ndarray: 映射后的概率。
        """
        return 1 / (1 + np.exp(-z))

    def fit(self, X, y):
        """
        训练逻辑回归模型。

        Parameters:
            X (numpy.ndarray): 输入特征矩阵,每行代表一个样本,每列代表一个特征。
            y (numpy.ndarray): 输出变量,每个元素对应于相应样本的输出。

        Returns:
            None
        """
        X_b = np.c_[np.ones((X.shape[0], 1)), X]  # 添加截距项,构造增广矩阵
        self.theta = np.zeros((X_b.shape[1], 1))  # 初始化模型参数

        for _ in range(self.n_iterations):
            z = X_b.dot(self.theta)
            h = self.sigmoid(z)
            gradients = X_b.T.dot(h - y.reshape(-1, 1)) / len(y)
            self.theta = self.theta - self.learning_rate * gradients
            # 使用梯度下降法更新模型参数

    def predict_proba(self, X_new):
        """
        使用训练好的模型进行预测,返回预测的概率。

        Parameters:
            X_new (numpy.ndarray): 新的输入特征,每行代表一个样本,每列代表一个特征。

        Returns:
            numpy.ndarray: 预测的概率。
        """
        X_new_b = np.c_[np.ones((X_new.shape[0], 1)), X_new]  # 添加截距项,构造增广矩阵
        return self.sigmoid(X_new_b.dot(self.theta))

    def predict(self, X_new, threshold=0.5):
        """
        使用训练好的模型进行预测,返回预测的类别。

        Parameters:
            X_new (numpy.ndarray): 新的输入特征,每行代表一个样本,每列代表一个特征。
            threshold (float): 阈值,用于确定类别。默认为0.5。

        Returns:
            numpy.ndarray: 预测的类别。
        """
        proba = self.predict_proba(X_new)
        return (proba >= threshold).astype(int)
        # 使用阈值判断概率,返回二元类别(0或1)

# 示例用法
if __name__ == "__main__":
    # 准备数据
    X_train = np.array([[1], [2], [3], [4], [5]])
    y_train = np.array([0, 0, 1, 1, 1])

    # 创建逻辑回归模型
    model = LogisticRegression()

    # 训练模型
    model.fit(X_train, y_train)

    # 预测新数据的概率
    X_new = np.array([[3.5]])
    proba = model.predict_proba(X_new)
    print(f'预测概率:{proba[0][0]}')

    # 预测新数据的类别
    prediction = model.predict(X_new)
    print(f'预测类别:{prediction[0]}')