逻辑回归模型python代码加详细注释

文章参考于https://blog.csdn.net/dQCFKyQDXYm3F8rB0/article/details/79767043
笔者只是对其中的代码做了较为详细的注释,便于初学者理解
与线性回归不同,Logistic 回归没有封闭解。但由于损失函数是凸函数,因此我们可以使用梯度下降法来训练模型。事实上,在保证学习速率足够小且使用足够的训练迭代步数的前提下,梯度下降法(或任何其他优化算法)可以是能够找到全局最小值。
第0步:用 0 (或小的随机值)来初始化权重向量和偏置值
第 1 步:计算输入的特征与权重值的线性组合,这可以通过矢量化和矢量传播来对所有训练样本进行处理:a = X*w + b,其中 X 是所有训练样本的维度矩阵
第 2 步:用 sigmoid 函数作为激活函数,其返回值介于0到1之间:
在这里插入图片描述
第 3 步:计算整个训练集的损失值。
我们希望模型得到的目标值概率落在 0 到 1 之间。因此在训练期间,我们希望调整参数,使得模型较大的输出值对应正标签(真实标签为 1),较小的输出值对应负标签(真实标签为 0 )。这在损失函数中表现为如下形式:
在这里插入图片描述
第 4 步:对权重向量和偏置量,计算其对损失函数的梯度。
一般形式如下:
在这里插入图片描述
第 5 步:更新权重和偏置值。
在这里插入图片描述
在这里插入图片描述

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
np.random.seed(123) #seed( ) 用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed( )值,则每次生成的随即数都相同,如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同

# We will perform logistic regression using a simple toy dataset of two classes
X, y_true = make_blobs(n_samples= 1000, centers=2)#sklearn中的make_blobs函数主要是为了生成数据集的,n_samples是待生成的样本总数,centers是类别数
#print(X.shape)  (1000, 2)

fig = plt.figure(figsize=(8,6))
plt.scatter(X[:,0], X[:,1], c=y_true)#x[:,0]是数组所有行的第一列数据,x[:,1]是数组所有行的第二列数据
plt.title("Dataset")
plt.xlabel("First feature")
plt.ylabel("Second feature")
plt.show()

# Reshape targets to get column vector with shape (n_samples, 1)
y_true = y_true[:, np.newaxis]#np.newaxis是增加维度的,相当于增加一列
# Split the data into a training and test set
X_train, X_test, y_train, y_test = train_test_split(X, y_true)
print(f'Shape X_train: {X_train.shape}')
print(f'Shape y_train: {y_train.shape}')
print(f'Shape X_test: {X_test.shape}')
print(f'Shape y_test: {y_test.shape}')


class LogisticRegression:

    def __init__(self): # 初始化
        pass # 什么也不做,只是防止语句出错

    def sigmoid(self, a): # 激活函数
        return 1 / (1 + np.exp(-a))

    def train(self, X, y_true, n_iters, learning_rate): # 训练样本,n_iters是迭代的次数
        """
        Trains the logistic regression model on given data X and targets y
        """
        # Step 0: Initialize the parameters
        n_samples, n_features = X.shape # shape返回的是维度,就是几行几列,是一个元组
        self.weights = np.zeros((n_features, 1)) # np.zeros返回来一个给定形状和类型的用0填充的数组,weights是指权重
        self.bias = 0 # bias 偏置赋值为0
        costs = [] # 损失数组

        for i in range(n_iters): # 迭代
            # Step 1 and 2: Compute a linear combination of the input features and weights,
            # apply the sigmoid activation function
            y_predict = self.sigmoid(np.dot(X, self.weights) + self.bias) # np.dot矩阵运算或向量内积

            # Step 3: Compute the cost over the whole training set.
            cost = (- 1 / n_samples) * np.sum(y_true * np.log(y_predict) + (1 - y_true) * (np.log(1 - y_predict)))

            # Step 4: Compute the gradients
            dw = (1 / n_samples) * np.dot(X.T, (y_predict - y_true))
            db = (1 / n_samples) * np.sum(y_predict - y_true)

            # Step 5: Update the parameters
            self.weights = self.weights - learning_rate * dw
            self.bias = self.bias - learning_rate * db

            costs.append(cost) # 将每个损失值添加进损失数组
            if i % 100 == 0: # 每过 100 次输出一下损失
                print(f"Cost after iteration {i}: {cost}")

        return self.weights, self.bias, costs

    def predict(self, X):
        """
        Predicts binary labels for a set of examples X.
        """
        y_predict = self.sigmoid(np.dot(X, self.weights) + self.bias)
        y_predict_labels = [1 if elem > 0.5 else 0 for elem in y_predict]

        return np.array(y_predict_labels)[:, np.newaxis]

regressor = LogisticRegression() # 创建逻辑回归实例
w_trained, b_trained, costs = regressor.train(X_train, y_train, n_iters=600, learning_rate=0.009)

fig = plt.figure(figsize=(8,6))
plt.plot(np.arange(600), costs) # 绘制的是随着训练的进行,损失值的变化,plt.plot(x, y):x为x轴数据, y为y轴数据,它可以绘制点和线, 并且对其样式进行控制
plt.title("Development of cost over training")
plt.xlabel("Number of iterations")
plt.ylabel("Cost")
plt.show()

y_p_train = regressor.predict(X_train)
y_p_test = regressor.predict(X_test)

print(f"train accuracy: {100 - np.mean(np.abs(y_p_train - y_train)) * 100}%") # mean()求取均值
print(f"test accuracy: {100 - np.mean(np.abs(y_p_test - y_test))}%")


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 用python写神经网络的代码,可以参考下面的例子:# 导入神经网络库 from tensorflow.keras import Sequential # 定义模型 model = Sequential() # 添model.add(Dense(32, activation='relu', input_dim=32)) model.add(Dense(32, activation='relu')) model.add(Dense(1, activation='sigmoid'))# 编译模型 model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# 训练模型 model.fit(X, y, epochs=32, batch_size=32) ### 回答2: 神经网络是一种机器学习模型,可以用于解决分类或回归问题。下面是一个使用Python编写的简单神经网络代码,并附上注释解释代码的功能和实现方法。 ```python import numpy as np # 为了简化示例,假设我们要解决一个二分类问题 # 定义神经网络类 class NeuralNetwork: def __init__(self, input_size, hidden_size, output_size): # 初始化参数 self.W1 = np.random.randn(input_size, hidden_size) self.b1 = np.zeros((1, hidden_size)) self.W2 = np.random.randn(hidden_size, output_size) self.b2 = np.zeros((1, output_size)) def forward(self, X): # 前向传播计算,输入为X self.z1 = np.dot(X, self.W1) + self.b1 self.a1 = np.tanh(self.z1) self.z2 = np.dot(self.a1, self.W2) + self.b2 self.a2 = self.sigmoid(self.z2) return self.a2 def backward(self, X, y, learning_rate): # 反向传播计算并更新参数 m = X.shape[0] # 样本数 self.dz2 = self.a2 - y self.dW2 = np.dot(self.a1.T, self.dz2) / m self.db2 = np.sum(self.dz2, axis=0, keepdims=True) / m self.dz1 = np.dot(self.dz2, self.W2.T) * (1 - np.power(self.a1, 2)) self.dW1 = np.dot(X.T, self.dz1) / m self.db1 = np.sum(self.dz1, axis=0, keepdims=True) / m # 使用梯度下降法更新参数 self.W2 -= learning_rate * self.dW2 self.b2 -= learning_rate * self.db2 self.W1 -= learning_rate * self.dW1 self.b1 -= learning_rate * self.db1 def sigmoid(self, x): # 定义sigmoid激活函数 return 1 / (1 + np.exp(-x)) # 创建样本数据 X = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 1], [0, 0, 1]]) y = np.array([[1], [0], [1], [0]]) # 创建神经网络实例 nn = NeuralNetwork(3, 4, 1) # 训练神经网络 epochs = 1000 learning_rate = 0.1 for i in range(epochs): # 前向传播计算输出 output = nn.forward(X) # 反向传播更新参数 nn.backward(X, y, learning_rate) # 预测新数据 new_data = np.array([[1, 0, 0]]) prediction = nn.forward(new_data) print(f"新数据的预测结果为:{prediction}") ``` 这个神经网络模型是一个单隐藏层的前馈神经网络,使用tanh作为隐藏层的激活函数,sigmoid作为输出层的激活函数。通过不断调整参数,控制损失函数最小化来实现分类任务。代码中的注释部分给出了对每个关键步骤的解释。 ### 回答3: 下面是一个使用Python编写的简单神经网络代码示例,附上了详细注释,帮助你理解每个步骤的作用。 ```python import numpy as np # 导入NumPy库,用于处理数组和矩阵运算 # 定义神经网络类 class NeuralNetwork: def __init__(self): # 设定随机的初始权重 np.random.seed(1) # 创建3x1的权重矩阵,取值范围[-1, 1] self.synaptic_weights = 2 * np.random.random((3, 1)) - 1 # 定义S型激活函数 def sigmoid(self, x): return 1 / (1 + np.exp(-x)) # 定义S型函数的导数 def sigmoid_derivative(self, x): return x * (1 - x) # 定义神经网络训练函数 def train(self, training_inputs, training_outputs, num_iterations): for iteration in range(num_iterations): # 前向传播 output = self.think(training_inputs) # 计算误差 error = training_outputs - output # 根据误差计算权重调整量 adjustments = np.dot(training_inputs.T, error * self.sigmoid_derivative(output)) # 更新权重 self.synaptic_weights += adjustments # 定义神经网络预测函数 def think(self, inputs): inputs = inputs.astype(float) output = self.sigmoid(np.dot(inputs, self.synaptic_weights)) return output # 创建神经网络对象 neural_network = NeuralNetwork() # 打印初始权重 print("初始权重:") print(neural_network.synaptic_weights) # 提供训练数据 training_inputs = np.array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]]) training_outputs = np.array([[0, 1, 1, 0]]).T # 训练神经网络 neural_network.train(training_inputs, training_outputs, 10000) # 打印训练后的权重 print("训练后的权重:") print(neural_network.synaptic_weights) # 提供新数据进行预测 new_inputs = np.array([1, 0, 0]) prediction = neural_network.think(new_inputs) # 打印预测结果 print("预测结果:") print(prediction) ``` 以上是一个简单的神经网络代码示例,用于实现简单的二进制逻辑门。你可以根据需求调整输入数据、训练次数和初始权重等参数,以适配不同的问题。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值