机器学习实验5——逻辑回归

目录

5-1逻辑回归概述

5-1-1逻辑回归原理

5-1-2sigmoid函数与逻辑回归的假设函数

​编辑

5-1-3梯度上升算法

5-2代码实现

5-2-1实验步骤

1.创建数据集

2.定义sigmoid函数

3.定义梯度上升算法函数

4. 逻辑回归分类散点图和逻辑回归曲线

5.分类测试集数据并计算准确率

5-2-2总代码

5-3实验结果分析

5-3-1实验中遇到的问题

5-3-2实验总结逻辑回归算法的优缺点 


5-1逻辑回归概述

5-1-1逻辑回归原理

逻辑回归(Logistic Regression)是一种分类方法,虽然是命中中不带有分类二字但逻辑回归是应用最为广泛的二分类模型,逻辑回归通过引入Sigmoid函数将线性回归的预测值映射到[0, 1]区间内回归线性分类器。

例如,天色越黑,下雨概率就越大。即值越大,属于某类别的概率也越大。值与概率之间可以互转。


5-1-2sigmoid函数与逻辑回归的假设函数

z=\theta _{0}+\theta _{1}x_{1}+\theta _{2}x_{2}+......+\theta _{n}x_{n}

设平面上的样本,正例标记为1,负例标记为0,逻辑回归模型需要预测样本的标记值,也就是预测未知的样本x,是正例还是负例。

一般来说我们希望逻辑回归的预测结果g(x)的取值范围在[0,1],这样就可以看作是样本x属于某个类别的概率,当g趋近于1时,样本就更可能是正例,当g趋近于0时,样本就更可能是负例。

从而引入sigmoid函数。

Sigmoid函数的形式为:

其中,z 是线性回归的预测值。Sigmoid函数将z 映射到0和1之间,从而表示正类(通常是1)和负类(通常是0)的概率。

图像如下:

5-1-3梯度上升算法

梯度表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(梯度的方向)变化最快,变化率(梯度的模)最大,可理解为导数。
梯度上升和梯度下降是优化算法中常用的两种方法,主要目的是通过迭代找到目标函数的最大值和最小值。
例如:
想象我们在一座很高的山上,怎么才能以最快的速度下山?我们可以先选择坡度最倾斜的方向走一段距离,然后再重新选择坡度最倾斜的方向,再走一段距离。以此类推,我们就可以以最快的速度到达山底。(梯度的方向,就是我们要选择的方向)

我们要得到的是方差最大的数据,即:

由于我们进行过数据的预处理。所以我们的目标就变为了:

映射关系推导
假设xi要映射到新的坐标轴上

在这里我们假设向量w为单位向量
则使之变为:

将映射关系带入
带入映射关系后我们的目标变为了

梯度上升
构建一个函数
现在我们构建一个函数

求导
下面我们开始对f(w)求导

我们的问题就变成了使用上述式子进行梯度上升,接下来我们使用梯度上升的方式优化w,优化得到的w即为可以将数据转换到方差更大的坐标轴上的主成分。

通过这些知识我可以实现一个简单的关于逻辑回归算法的实验,如下

5-2代码实现

5-2-1实验步骤

1.创建数据集

if __name__=='__main__':
    # 输出训练集和测试集
    # 使用make blobs函数,在平面上生成60个随机样本包含两个类别
    x, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.5)
    x_with_intercept = np.c_[np.ones((x.shape[0], 1)), x]

    # 分离出训练集和测试集
    x_train, y_train = x[:50], y[:50]
    x_test, y_test = x[50:], y[50:]
    print("训练集样本:")
    for i in range(len(x_train)):
        print(f"样本 {i+1} - 特征: {x_train[i]}, 标签: {y_train[i]}")

    print("\n测试集样本:")
    for i in range(len(x_test)):
        print(f"样本 {i+1} - 特征: {x_test[i]}, 真实标签: {y_test[i]}")

我们将样本输出看看 

2.定义sigmoid函数

# 定义sigmoid函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

3.定义梯度上升算法函数

# 定义梯度上升算法
def tdss(x, y, alpha=0.01, num_iterations=1000):
    m, n = x.shape
    weights = np.zeros(n)

    for _ in range(num_iterations):
        z = np.dot(x, weights)
        h = sigmoid(z)
        error = y - h
        gradient = np.dot(x.T, error) / m
        weights += alpha * gradient

    return weights

4. 逻辑回归分类散点图和逻辑回归曲线

# 绘制散点图和决策边界
    plt.scatter(x[y == 1, 0], x[y == 1, 1], color='blue', marker='o', label='label1')
    plt.scatter(x[y == 0, 0], x[y == 0, 1], color='red', marker='s', label='label0')

    x_decision = np.array([np.min(x[:, 0]), np.max(x[:, 0])])
    y_decision = -(weights[0] + weights[1] * x_decision) / weights[2]

    plt.plot(x_decision, y_decision, color='green', label='Regression curve')


    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.legend()
    plt.show()

 散点图如下:

5.分类测试集数据并计算准确率

    # 预测
    x_test_with_intercept = np.c_[np.ones((x_test.shape[0], 1)), x_test]
    z_test = np.dot(x_test_with_intercept, weights)
    y_pred = np.round(sigmoid(z_test))
    # 逐个打印测试集的预测和真实标签
    print("逐个打印测试集的预测和真实标签:")
    for i in range(len(y_test)):
        print(f"样本 {i+1} - 真实标签: {y_test[i]}, 预测标签: {y_pred[i]}")

    # 计算准确率
    accuracy = np.mean(y_pred == y_test)
    print("测试集准确率:", accuracy)

输出结果如下:

5-2-2总代码

import numpy as np  # 导入numpy库,用于数学运算
import matplotlib.pyplot as plt  # 导入matplotlib库,用于画图
from sklearn.datasets import make_blobs  # 从sklearn库中导入make_blobs函数,用于生成随机数据

# 定义sigmoid函数
def sigmoid(z):  # 定义一个叫sigmoid的函数,输入参数是z
    return 1 / (1 + np.exp(-z))  # 返回1除以(1加上e的-z次方)

# 定义梯度上升算法
def tdss(x, y, alpha=0.01, num_iterations=1000):  # 定义一个叫tdss的函数,输入参数是x, y, alpha, num_iterations
    m, n = x.shape  # 获取x的形状,赋值给m和n
    weights = np.zeros(n)  # 创建一个全为0的长度为n的数组,赋值给weights

    for _ in range(num_iterations):  # 循环num_iterations次
        z = np.dot(x, weights)  # 计算x和weights的点积,赋值给z
        h = sigmoid(z)  # 使用定义好的sigmoid函数计算z的sigmoid值,赋值给h
        error = y - h  # 计算y和h的差,赋值给error
        gradient = np.dot(x.T, error) / m  # 计算x的转置和error的点积再除以m,赋值给gradient
        weights += alpha * gradient  # 更新weights

    return weights  # 返回weights

if __name__=='__main__':
    # 输出训练集和测试集
    # 使用make blobs函数,在平面上生成60个随机样本包含两个类别
    x, y = make_blobs(n_samples=60, centers=2, random_state=0, cluster_std=0.5)  # 生成包含60个随机样本的数据,赋值给x, y
    x_with_intercept = np.c_[np.ones((x.shape[0], 1)), x]  # 在x前加一列全为1的数据,赋值给x_with_intercept

    # 分离出训练集和测试集
    x_train, y_train = x[:50], y[:50]  # 获取x和y的前50个数据,赋值给x_train, y_train
    x_test, y_test = x[50:], y[50:]  # 获取x和y的后10个数据,赋值给x_test, y_test
    print("训练集样本:")
    for i in range(len(x_train)):  # 遍历训练集的每一个数据
        print(f"样本 {i+1} - 特征: {x_train[i]}, 标签: {y_train[i]}")  # 打印训练集每个样本的特征和标签

    print("\n测试集样本:")
    for i in range(len(x_test)):  # 遍历测试集的每一个数据
        print(f"样本 {i+1} - 特征: {x_test[i]}, 真实标签: {y_test[i]}")  # 打印测试集每个样本的特征和真实标签
    # 训练模型
    weights = tdss(x_with_intercept, y)  # 调用定义好的tdss函数进行模型训练,返回的结果赋值给weights
    # 预测
    x_test_with_intercept = np.c_[np.ones((x_test.shape[0], 1)), x_test]  # 在测试集x_test前加一列全为1的数据,赋值给x_test_with_intercept
    z_test = np.dot(x_test_with_intercept, weights)  # 计算x_test_with_intercept和weights的点积,赋值给z_test
    y_pred = np.round(sigmoid(z_test))  # 使用sigmoid函数计算z_test的sigmoid值并四舍五入,赋值给y_pred
    # 逐个打印测试集的预测和真实标签
    print("逐个打印测试集的预测和真实标签:")
    for i in range(len(y_test)):  # 遍历测试集的每一个数据
        print(f"样本 {i+1} - 真实标签: {y_test[i]}, 预测标签: {y_pred[i]}")  # 打印每个样本的真实标签和预测标签

    # 计算准确率
    accuracy = np.mean(y_pred == y_test)  # 计算预测准确率,赋值给accuracy
    print("测试集准确率:", accuracy)  # 打印测试集准确率
    # 绘制散点图和决策边界
    plt.scatter(x[y == 1, 0], x[y == 1, 1], color='blue', marker='o', label='label1')  # 画散点图,蓝色代表标签1
    plt.scatter(x[y == 0, 0], x[y == 0, 1], color='red', marker='s', label='label0')  # 画散点图,红色代表标签0

    x_decision = np.array([np.min(x[:, 0]), np.max(x[:, 0])])  # 创建一个包含x第一列最小值和最大值的数组,赋值给x_decision
    y_decision = -(weights[0] + weights[1] * x_decision) / weights[2]  # 根据权重计算决策边界的y值,赋值给y_decision

    plt.plot(x_decision, y_decision, color='green', label='Regression curve')  # 画决策边界

    plt.xlabel('X1')  # 设置x轴标签
    plt.ylabel('X2')  # 设置y轴标签
    plt.legend()  # 显示图例
    plt.show()  # 展示图形

5-3实验结果分析

5-3-1实验中遇到的问题

并没有什么特别需要注意的问题,所以我找了一些可以提升准确率和性能的方法:

1.特征选择:选择与预测目标密切相关的特征,可以增强模型的预测能力。可以考虑使用相关性分析、卡方检验、互信息法等特征选择方法,以选择与目标变量相关性较强的特征。
2.数据预处理:对数据进行预处理可以改善模型的性能。数据预处理包括缺失值处理、异常值处理、数据标准化等。可以使用插值、平均值填充、回归等方法处理缺失值;使用箱线图、3σ原则等方法处理异常值;使用Z-score等方法进行数据标准化。
3.模型参数调整:可以通过调整模型参数来提高模型性能。例如,通过调整学习率(或步长)、迭代次数、正则化参数等参数,可以优化模型的收敛速度和预测精度。

5-3-2实验总结逻辑回归算法的优缺点 

优点:

  1. 实现简单:逻辑回归易于理解和实现,不需要太多的调参。
  2. 预测速度快:计算量小,预测速度快。
  3. 结果具有概率解释:可以输出样本属于某个类别的概率。

缺点:

  1. 只能解决二分类问题:逻辑回归只能处理两个类别的分类问题,不适用于多分类问题。
  2. 对特征空间的线性可分性要求较高:如果特征空间的线性可分性较差,逻辑回归的效果可能会受到影响。
  3. 容易受到异常值影响:逻辑回归对异常值比较敏感,需要进行处理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值