逻辑回归(LogisticRegression)算法及简单案例

逻辑回归(LogisticRegression)算法及简单案例

大家好,我是W

逻辑回归虽然名字有回归,但是实际上是分类模型,常用于二分类。**回归的意思是:在二维空间中找到一条最佳拟合直线去拟合数据点;在多维空间中找到最佳拟合超平面去拟合数据点,这个寻找拟合的过程就叫做回归。**这篇文章的顺序是:介绍相关概念、逻辑回归原理、案例 - 简单数据集的逻辑回归分类

介绍相关概念

二值型输出分类函数

在我们通过回归得到一个数值时我们需要一个函数给我们做分类,在数学上我们就学过一个分段函数,x>0时,f(x)=1,x<0时,f(x)=0。这就是典型的跳跃函数也叫阶跃函数。

在这里插入图片描述

但是这种函数在从0到1跳跃的瞬间过程不好处理,它不是连续的,所以有缺陷。但是有些函数就有很不错的性质,比如sigmoid、tanh、relu。就拿最常见的sigmoid函数来说,他的方程是:

在这里插入图片描述

其图像是:

在这里插入图片描述

当x=0时,f(x)=0.5,函数在x=0两侧逐渐收敛向0和1两个极端,并且函数单增。有了sigmoid函数,我们无论输入什么值都可以得到(0,1)的数值,然后通过0.5为界分类。

梯度下降法

在高数中我们都学过偏导,而偏导的结果就是梯度。梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。

f(x,y)有两个自变量,其梯度就有x和y两个方向。f分别对x和y求偏导就能得到该函数在该方向上的梯度。

在这里插入图片描述

下面用一个二维坐标系来讲解一下梯度下降法的思想,在二维坐标中有一条sin曲线,变量x在曲线上移动,试图寻找最大值,按照梯度下降(上升)法的思想,只要知道梯度的下降(上升)的方向就能知道x点在sin曲线上移动的方向。

在这里插入图片描述

在上图中,x作为变量,y作为我们的目标值,这样方便理解,在实际运用中变量可能由n个,这时我们就需要在不同维度去求梯度从而使得粒子在不同维度都逼近我们想要的最大(最小)值。**当我们寻找最高点时,使用梯度上升法。假设x=1,在改点对函数求导,得到的是正数,故x应当向正方向移动;当x=2时,得到的是负数,证明在改点继续移动f(x)会越来越小,这与我们预期相违背,所以应当向负方向移动。**梯度下降也是同样的道理。

学习率

粒子(样本点)的移动有一个重要的参数学习率。学习率通常用alpha来表示,即我们每次移动的步长。想想一下,在上图中若步长太大粒子一下在1一下在2的反复横跳,始终无法逼近最高值,那么经过一定次数的训练后停止。显然得到的精度还是无法满足我们要求的,所以学习率一般会很小,但是过分小也会带来训练时间的问题。

拓展到3维空间,在一座山上有x,y,z(x,y),那么分为两个维度x,y来求梯度,粒子分别在x,y上移动两次(相当于画矩形两条边)然后达到下一个位置,这个位置往往会比上一个位置好。

若大家对梯度下降和学习率还有疑问请看梯度下降算法详解,讲不好真的是不好意思=。=

向量相乘、矩阵乘法

在代数中我们学过向量和矩阵的乘法,例如[2,3] * [3,1] = [2,1],2*3的矩阵跟3*1的矩阵相乘得到2*1的矩阵。

矩阵向量相乘本质上就是解方程组,

逻辑回归原理

在了解上面几个概念后把他们串联起来就能理解逻辑回归原理。首先逻辑回归的公式是:

y = w_1*x_1 + w_2*x_2 + ... + w_n*x_n +bias    ---(1)
bias为偏置,可以理解为一元函数的y=ax+b中的b
  • 由于我们有样本,所以x向量([x_1,x_2,…,x_n])已知,我们要做的是调整weights向量([w_1,w_2,…,w_n])使之能够拟合绝大部分样本。
  • 而sigmoid的作用是将每次调整后计算得到的y_predict送入sigmoid做分类从而拿到我们对每个样本的预测标签label_predict。
  • 当然,label_predict跟label_true还是有差别的,label_predict可能会预测错,所以要从新带入(1)式中计算y_predict,重新送入sigmoid…如此反复。

下面这张流程图可能更清楚点:

在这里插入图片描述

案例 - 简单数据集的逻辑回归分类

先看数据集

0.089392	-0.715300	1
1.825662	12.693808	0
0.197445	9.744638	0
0.126117	0.922311	1
-0.679797	1.220530	1
0.677983	2.556666	1
0.761349	10.693862	0
-2.168791	0.143632	1
1.388610	9.341997	0
0.317029	14.739025	0

这个数据集很小,只有十条。第一第二列分别代表x_1,x_2,第三列代表label。数据存在txt文档里,所以显然第一步要加载数据,用合适的数据结构存放。

数据集加载

def load_data_set(file_path):
    """
    加载dataset文件夹中的数据集
    :param file_path: 文件目录
    :return:
    """
    data_matrix = []
    label_list = []
    with open(file_path, "r") as file:
        for line in file:
            line = line.strip().split()
            data_matrix.append([float(line[0]), float(line[1]), 1.0])
            label_list.append(int(line[2]))
    return np.array(data_matrix), np.array(label_list)

sigmoid函数

sigmoid函数非常简单,而且在了解将要传入的数据结构后依然很好写,所以先准备好。

def sigmoid(values):
    """
    sigmoid函数
    :param values: 列表类型 分别计算出值封装成列表返回
    :return: 1.0 / (1.0 + np.exp(-values))
    """
    return 1.0 / (1.0 + np.exp(-values))

梯度上升训练

按照刚刚的流程图可以看到,我们需要初始化weights,然后把矩阵转为合适的形状,然后写循环训练。

而循环的内容无非就是计算y_predict,丢入sigmoid分类,计算偏差,调整weights。在经过训练后返回最终weights。

def gradAscent(data_matrix, label_matrix, alpha=0.001, n=500):
    """
    开始使用梯度上升训练weights
    :param data_matrix: np.array()类型 数据集矩阵
    :param label_matrix: np.array()类型 标签矩阵
    :param alpha: 学习率
    :param n: 训练次数
    :return: weights
    """
    # label_matrix转为列向量
    label_matrix = np.mat(label_matrix).transpose()
    # 初始化weights = [3,1] = 1
    weights = np.ones(shape=(len(data_matrix[0]), 1))
    for i in range(n):
        # [n,1] = [n,m] * [m,1] 矩阵乘法
        # 要把data_matrix从np.array 转为np.mat才能相乘
        values = np.mat(data_matrix) * weights
        # 激活函数后得到类别
        activated_values = sigmoid(values)
        # 计算误差 (以2元函数举例)
        error_list = label_matrix - activated_values
        print(activated_values,error_list)
        # 调整权重weights
        # 因为偏移量error_list是(5,1)所以要把data_matrix转为(3,5),最终得到每个权重需要调整的量
        weights = weights + alpha * data_matrix.transpose() * error_list
    return np.array(weights)

画图

为了更直观地看到点的分布和拟合直线,我们需要用matplotlib画出来。并且大家可以在上面遍历里逐条画出来,看看直线拟合的过程和走向。

def paint(data_matrix, label_matrix, weights):
    """
    画出数据集和拟合直线
    :param data_matrix:
    :param label_matrix:
    :param weights:
    :return:
    """
    point_0 = []
    point_1 = []

    plt.figure(figsize=(5, 5), dpi=200)
    # 遍历把两类点分离出来
    for i in range(len(label_matrix)):
        if label_matrix[i] == 1:
            point_1.append(data_matrix[i])
        else:
            point_0.append(data_matrix[i])
    point_0 = np.array(point_0)
    point_1 = np.array(point_1)
    # 把离散点画出来
    plt.scatter(x=point_0[:, 0], y=point_0[:, 1], c="red")
    plt.scatter(x=point_1[:, 0], y=point_1[:, 1], c="blue")

    # 画拟合曲线
    x = np.arange(-3.0, 3.0, 0.1)
    y = (-weights[2] - weights[0] * x) / weights[1]
    plt.plot(x, y)

    plt.show()

拟合对比

在这里插入图片描述
在这里插入图片描述

项目地址

点击进入github

  • 17
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面我来给你提供一个逻辑回归和K近邻算法案例实战。 首先,我们需要一个数据集。这里我选取了一个著名的鸢尾花数据集,可以通过sklearn库进行导入。 ```python from sklearn.datasets import load_iris iris = load_iris() X = iris.data y = iris.target ``` 接下来,我们需要将数据集划分为训练集和测试集,并进行标准化处理。 ```python from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) sc = StandardScaler() sc.fit(X_train) X_train_std = sc.transform(X_train) X_test_std = sc.transform(X_test) ``` 然后,我们可以使用逻辑回归模型进行分类,并对模型进行评估。 ```python from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score lr = LogisticRegression(random_state=0) lr.fit(X_train_std, y_train) y_pred_lr = lr.predict(X_test_std) print('Accuracy: %.2f' % accuracy_score(y_test, y_pred_lr)) ``` 接下来,我们使用K近邻算法进行分类,并对模型进行评估。 ```python from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train_std, y_train) y_pred_knn = knn.predict(X_test_std) print('Accuracy: %.2f' % accuracy_score(y_test, y_pred_knn)) ``` 以上就是逻辑回归和K近邻算法简单案例实战。通过比较两种算法的分类准确率,可以对它们的性能进行比较和评估。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值