逻辑回归原理及代码实现

1.sigmoid函数

        公式: 

         自变量取值为任意实数,值域[0,1]

        解释:将任意的输入映射到了[0,1]区间 ,我们在线性回归中可以得到一个预测值,再将该值映射到Sigmoid 函数中这样就完成了由值到概率的转换,也就是分类任务

        预测函数:

         其中,

         分类任务:

         整合:

        解释:对于二分类任务(0,1),整合后y取0只保留 ,y取1只保留

         似然函数:

         对数似然:

         此时应用梯度上升求最大值,引入

         转换为梯度下降任务

        求导过程:

参数更新: 

多分类的softmax:  

 2.代码实现

       

import numpy as np
from utils.features import prepare_for_training
from scipy.optimize import minimize
from utils.hypothesis import sigmoid


class LogisticRegression:
    def __init__(self, data, labels, polynomial_degree=0, sinusoid_degree=0, normalize_data=False):

        (data_processed, features_mean,
         features_deviation) = prepare_for_training(data, polynomial_degree, sinusoid_degree,
                                                    normalize_data)
        self.data = data_processed
        self.labels = labels
        self.unique_labels = np.unique(labels)
        self.features_mean = features_mean
        self.features_deviation = features_deviation
        self.polynomial_degree = polynomial_degree
        self.sinusoid_degree = sinusoid_degree
        self.normalize_data = normalize_data
        # 数据预处理
        num_unique_labels = len(np.unique(labels))
        num_features = self.data.shape[1]
        self.theta = np.zeros((num_unique_labels, num_features))

    def train(self, n_iterations=500):
        cost_histories = []
        num_features = self.data.shape[1]
        for label_index, unique_label in enumerate(self.unique_labels):
            current_initial_theta = np.copy(self.theta[label_index].reshape(num_features, 1))
            current_lables = (self.labels == unique_label).astype(float)
            (theta, cost_history) = LogisticRegression.gradient_descent(self.data, current_initial_theta,
                                                                          current_lables, n_iterations)
            self.theta[label_index]=theta.T
            cost_histories.append(cost_history)
        return self.theta,cost_histories

    @staticmethod
    def gradient_descent(data, current_initial_theta, current_lables, n_iterations):
        cost_history = []
        num_fratures = data.shape[1]
        result = minimize(
            # 优化的目标
            lambda x: LogisticRegression.cost_function(data, current_lables, x.reshape(num_fratures,1)),
            # 初始化的权重参数
            current_initial_theta,
            # 选择优化策略
            method='CG',
            # 梯度下降迭代计算公式
            jac=lambda x: LogisticRegression.gradient_step(data, current_lables, x.reshape(num_fratures,1)),
            callback=lambda x: cost_history.append(
                LogisticRegression.cost_function(data, current_lables, x.reshape(num_fratures,1))),
            options={
                "maxiter": n_iterations
            }
        )

        if not result.success:
            raise ArithmeticError('Can not minimize cost function' + result.message)
        theta = result.x.reshape(num_fratures,1)
        return theta,cost_history

    @staticmethod
    def cost_function(data, label, theta):
        num_examples = data.shape[0]
        prediction = LogisticRegression.hypothesis(data, theta)
        y_true_cost = np.dot(label[label == 1].T, np.log(prediction[label == 1]))
        y_false_cost = np.dot(1 - label[label == 0].T, np.log(1 - prediction[label == 0]))
        cost = (-1 / num_examples) * (y_false_cost + y_true_cost)
        return cost

    @staticmethod
    def hypothesis(data, theta):
        predictions = sigmoid(np.dot(data, theta))
        return predictions

    @staticmethod
    def gradient_step(data, label, theta):
        num_examples = data.shape[0]
        prediction = LogisticRegression.hypothesis(data, theta)
        label_diff = prediction - label
        gradients = (1 / num_examples) * np.dot(data.T, label_diff)
        return gradients.T.flatten()

    def predict(self,data):
        num_examples = data.shape[0]
        data_processed = prepare_for_training(data, self.polynomial_degree, self.sinusoid_degree,
                                              self.normalize_data)[0]
        prediction = LogisticRegression.hypothesis(data_processed, self.theta.T)
        arg = np.argmax(prediction,axis=1)
        class_prediction = np.empty(arg.shape,dtype=object)
        for index,unique_label in enumerate(self.unique_labels):
            class_prediction[arg == index] = unique_label
        return class_prediction.reshape((num_examples,1))

3.测试代码 

1.数据展示

        如图所示,我们使用了一个环形的数据分布进行测试,要想进行比较准确的分类,决策边界需要一个圆形

 2.训练数据

        我们使用类中的train函数进行训练,代码及损失变化情况如下:

 

 

训练结果分类精度达到88.9831%,结果相当不错!!! 

 让我们绘制一下决策边界把!

  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
逻辑回归是一种用于分类问题的机器学习算法,其原理是基于线性回归的思想,通过使用逻辑函数(也称为sigmoid函数)将预测结果映射到[0,1]之间的概率值。以下是一个使用Python实现逻辑回归的示例代码: ```python import numpy as np import matplotlib.pyplot as plt # 定义sigmoid函数 def sigmoid(z): return 1 / (1 + np.exp(-z)) # 定义损失函数 def loss(h, y): return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean() # 定义逻辑回归模型 class LogisticRegression: def __init__(self, lr=0.01, num_iter=100000, fit_intercept=True, verbose=False): self.lr = lr self.num_iter = num_iter self.fit_intercept = fit_intercept self.verbose = verbose def add_intercept(self, X): intercept = np.ones((X.shape[0], 1)) return np.concatenate((intercept, X), axis=1) def fit(self, X, y): if self.fit_intercept: X = self.add_intercept(X) # 初始化权重参数 self.theta = np.zeros(X.shape[1]) for i in range(self.num_iter): z = np.dot(X, self.theta) h = sigmoid(z) gradient = np.dot(X.T, (h - y)) / y.size self.theta -= self.lr * gradient if(self.verbose == True and i % 10000 == 0): z = np.dot(X, self.theta) h = sigmoid(z) print(f'loss: {loss(h, y)}') def predict_prob(self, X): if self.fit_intercept: X = self.add_intercept(X) return sigmoid(np.dot(X, self.theta)) def predict(self, X, threshold=0.5): return self.predict_prob(X) >= threshold # 示例:使用逻辑回归对二分类数据进行训练和预测 from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split # 生成二分类数据集 X, y = make_classification(n_samples=100, n_features=2, n_informative=2, n_redundant=0, random_state=42) # 将数据集划分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建逻辑回归模型并进行训练 model = LogisticRegression(lr=0.1, num_iter=300000) model.fit(X_train, y_train) # 在测试集上进行预测 y_pred = model.predict(X_test) # 计算准确率 accuracy = (y_pred == y_test).mean() print(f'Accuracy: {accuracy}') ``` 这段代码首先定义了sigmoid函数和损失函数,然后实现了一个LogisticRegression类,其中包含了fit方法用于训练模型,以及predict_prob和predict方法用于预测。最后,示例代码使用sklearn库生成了一个二分类数据集,将数据集划分为训练集和测试集,并使用逻辑回归模型进行训练和预测。最后计算了预测的准确率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

樱花的浪漫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值