机器学习5 逻辑回归

一、简介

逻辑回归是线性分类器(线性模型)—— 主要用于二分类问题

主要应用场景:

  • 是否为垃圾邮件
  • 是否患病
  • 金融诈骗
  • 虚假账号

二、理论概述

1.基本假设:逻辑回归的基本假设是因变量(输出变量)与自变量(输入变量)之间存在一个线性关系。

2.线性组合:通过对输入特征进行线性组合,得到一个分数(score),表示自变量对因变量的影响。线性组合可以表示为:
        Score = w0 + w1x1 + w2x2 + ... + wn*xn
        其中,w0, w1, w2, ..., wn 是权重(或系数),x1, x2, ..., xn 是输入特征。

3.逻辑函数(Sigmoid函数):线性组合得到的分数需要经过逻辑函数(也称为Sigmoid函数)转换,将其映射到(0, 1)的概率范围内。Sigmoid函数的公式如下:
sigmoid(x) = 1 / (1 + exp(-x))
其中,exp(x) 表示e的x次方,e是自然对数的底数。

4.预测概率:通过将线性组合的分数输入逻辑函数,得到一个在0到1之间的概率值。通常,大于等于0.5的概率值被认为属于正类(类别1),小于0.5的概率值被认为属于负类(类别0)。

5.损失函数:为了训练模型,需要定义一个损失函数来衡量预测值与实际值之间的差异。逻辑回归中常用的损失函数是对数损失函数(Log Loss),也称为交叉熵损失函数。

6.参数估计:通过最小化损失函数,使用梯度下降等优化算法来估计权重(系数)的值,使得模型能够更好地拟合训练数据,从而提高预测的准确性。

转化成公式

1、输入

这是线性回归输出的结果,我们一般可以写成矩阵形式。如下:

权重和偏置分别用矩阵表示之后,将上面的式子可以写成下面的:

逻辑回归的输入就是一个线性回归的结果,但是很明显,这样的函数图像是类似一条斜线,难以达到我们想要的(0或1)的取值所以我们引入了一个特殊的函数:

2、sigmoid函数

公式:

图象:

通过函数sigmoid的作用,我们可以将输出的值限制在区间[0, 1]上,p(x)则可以用来表示概率p(y=1|x),即当一个x发生时,y被分到1那一组的概率。可是,等等,我们上面说y只有两种取值,但是这里却出现了一个区间[0, 1],这是什么鬼??其实在真实情况下,我们最终得到的y的值是在[0, 1]这个区间上的一个数,然后我们可以选择一个阈值,通常是0.5,当y>0.5时,就将这个x归到1这一类,如果y<0.5就将x归到0这一类。但是阈值是可以调整的,比如说一个比较保守的人,可能将阈值设为0.9,也就是说有超过90%的把握,才相信这个x属于1这一类。

三、代码实现

import numpy as np
import matplotlib.pyplot as plt

# 生成数据集
np.random.seed(0)
X1 = np.random.randn(100, 2) - [2, 2]  # Class 0
X2 = np.random.randn(100, 2) + [2, 2]  # Class 1
X = np.vstack((X1, X2))
y = np.hstack((np.zeros(100), np.ones(100)))

# 定义逻辑回归模型
class LogisticRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000):
        self.learning_rate = learning_rate #学习率,即更新的步长
        self.n_iterations = n_iterations #迭代次数

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    def fit(self, X, y):
        #拟合函数,用于训练模型参数
        self.weights = np.zeros(X.shape[1]) 
        #初始化权重为零向量:创建一个和特征数量相同长度的全零向量,并将其赋值给逻辑回归模型的权重self.weights。这样初始化的权重向量将在模型的训练过程中进行调整,以便最终得到合适的分类边界。
        self.bias = 0 #初始化偏置为0

        for _ in range(self.n_iterations):
            linear_model = np.dot(X, self.weights) + self.bias #计算线性模型
            y_predicted = self.sigmoid(linear_model) #计算预测值

            dw = (1 / X.shape[0]) * np.dot(X.T, (y_predicted - y)) #计算权重的梯度向量:
            #y_predicted是模型对样本的预测值,是一个包含所有样本预测结果的向量,y是样本的真实标签,(y_predicted - y)计算了每个样本的预测误差。
            #X是输入特征的矩阵,每一行代表一个样本,每一列代表一个特征,X.T表示X的转置矩阵。
            #(1 / X.shape[0])是为了归一化梯度,其中X.shape[0]表示样本的数量。
            db = (1 / X.shape[0]) * np.sum(y_predicted - y) #计算偏置(即截距)的梯度

            self.weights -= self.learning_rate * dw #更新权重
            self.bias -= self.learning_rate * db #更新偏置

    def predict(self, X): #对输入数据进行分类预测
        linear_model = np.dot(X, self.weights) + self.bias #计算线性模型
        y_predicted = self.sigmoid(linear_model) #计算预测概率
        y_predicted_cls = [1 if i > 0.5 else 0 for i in y_predicted] #根据概率分类
        return y_predicted_cls

# 实例化逻辑回归模型
model = LogisticRegression(learning_rate=0.1, n_iterations=1000)

# 划分训练集和测试集
indices = np.random.permutation(X.shape[0])
training_idx, test_idx = indices[:150], indices[150:]
X_train, X_test = X[training_idx, :], X[test_idx, :]
y_train, y_test = y[training_idx], y[test_idx]

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

# 在测试集上进行预测
y_pred = model.predict(X_test)

# 绘制训练集和测试集的散点图
plt.scatter(X_train[y_train == 0][:, 0], X_train[y_train == 0][:, 1], color='r', label='Class 0 (Train)')
plt.scatter(X_train[y_train == 1][:, 0], X_train[y_train == 1][:, 1], color='b', label='Class 1 (Train)')
plt.scatter(X_test[y_test == 0][:, 0], X_test[y_test == 0][:, 1], color='r', marker='x', label='Class 0 (Test)')
plt.scatter(X_test[y_test == 1][:, 0], X_test[y_test == 1][:, 1], color='b', marker='x', label='Class 1 (Test)')
plt.legend()
plt.title('Generated Classification Dataset')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')

# 绘制决策边界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = np.array(Z).reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)

plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值