机器学习——带你透彻理解逻辑回归

本文介绍了逻辑回归的基本概念,包括它为何称为分类而非回归,以及Sigmoid函数的作用。文章详细解释了Sigmoid函数在将线性回归结果映射到概率区间的重要性,并通过实例展示了损失函数的推导和优化过程。最后,文章讨论了如何将逻辑回归用于多分类问题的方法。
摘要由CSDN通过智能技术生成

什么是逻辑回归

名字的由来

逻辑回归不是一个回归算法,逻辑回归是一个分类算法。那为什么逻辑回归不叫逻辑分类?因为逻辑回归算法是基于多元线性回归的算法。所以,逻辑回归这个分类算法是线性的分类器,像决策树一系列算法和神经网络算法都是非线性的算法。SVM支持向量机的本质也是线性的,但是可以通过内部的核函数升维来变成非线性的算法。

S曲线

import numpy
import math
import matplotlib.pyplot as plt


def sigmoid(x):
    a = []
    for item in x:
        a.append(1.0 / (1.0 + math.exp(-item)))
    return a


x = numpy.arange(-10, 10, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.title('sigmoid function', fontsize=24)
plt.xlabel('Z', fontsize=14)
plt.show()

Sigmoid的作用

逻辑回归就是在多元线性回归基础上把结果缩放到0到1之间。 h_\theta(x)越接近1越是正例,h_\theta(x)越接近0越是负例,根据中间0.5分为二类。
我们知道分类器的本质就是要找到分界,所以当我们把0.5作为分界时,我们要找的就是\hat{y}=h_\theta(x)=\frac{1}{1+e^-\theta^Tx}=0.5的时候θ的解,即z=\theta^Tx=0时θ的解。

为什么逻辑回归使用sigmoid函数

什么事都要做到知其然,知其所以然,我们知道二分类有个特点就是正例的概率+负例的概率=1。我们一般使用逻辑回归进行二分类,进行二分类的时候,我们得到的结果只有正例或者负例,比如正面或反面,成功或失败,有缺陷或没有缺陷,病人康复或未康复。前面说到逻辑回归是基于线性回归算法的,线性回归算法得到的结果是一个连续的数值,显然这不是我们需要的。这个时候我们就需要使用sigmoid函数将线性回归得到的数值转换到0到1之间的一个概率值。

 为方便 起见,记这两个可能的结果为 0 和 1,下面的定义就是建立在这类试验基础之上的。 如果随机变量 X 只取 0 和 1 两个值,并且相应的概率为:P(X=1)=p,P(X=0)=1-p,0<p<1.
则称随机变量 X 服从参数为 p 的伯努利分布(0-1 分布),若令 q=1-p,则 X 的概率 函数可写:f(x|p)=\begin{cases} p^xq^{1-x} & \text{ if } x=0, 1 \\ 0& \text{ if } x\neq 0,1 \end{cases}
逻辑回归二分类任务中我们会把正例的 label 设置为 1,负例的 label 设置为 0,对于上面公式就是 x=0,1

推导逻辑回归的损失函数

损失函数推导

这里我们依然会用到最大似然估计思想,根据若干已知的 X,y(训练集) 找到一组 W 使得 X 作为已知条件下 y 发生的概率最大。逻辑回归中g(w,x)的输出含义为P(y=1|w,x)
P(y=0|w,x)=1-g(w,x)

 只要让我们的g(w,x)函数在训练集上预测正确的概率最大,g(w,x)就是最好的解。P(true)=\begin{cases} g(w,x_i)& \text{ if } y_i=1 \\ 1-g(w,x_i) & \text{ if } y_i=0 \end{cases}
对与每一条数据预测正确的概率,也可以把下面的公式看成是上面式子的合并形式P(true)=(g(w,x_i))^{y^i}*(1-g(w,x_i))^{1-y^i}
换一下符号重写
P(y=1|x;\theta)=h_\theta(x) \\ P(y=0|x;\theta)=1-h_\theta(x)\\ p(y|x;\theta)=(h_\theta(x))^y(1-h_\theta(x))^{1-y}
我们假设训练样本相互独立,那么似然函数表达式为:
L(\theta)=p(\vec{y}|X;\theta)=\prod_{i=1}^{m}p(y^i|x^i;\theta)=\prod_{i=1}^{m}(h_\theta(x^i))^{y^i}(1-h_\theta(x^i))^{1-y^i}
对似然函数取log,转换为:
l(\theta)=logL(\theta)=\sum_{i=1}^{m}y^ilog h(x^i)+(1-y^i)log(1-h(x^i))
总结,得到了逻辑回归的表达式,下一步跟线性回归类似,构建似然函数,然后最大似然估 计,最终推导出θ的迭代更新表达式。只不过这里用的不是梯度下降,而是梯度上升,因为 这里是最大化似然函数不是最小化似然函数。通常我们一提到损失函数,往往是求最小,这 样我们就可以用梯度下降来求解。最终损失函数就是上面公式加负号的形式:
J(\theta)=-[\sum_{i=1}^{m}y^ilog h(x^i)+(1-y^i)log(1-h(x^i))]

绘制损失函数

from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.preprocessing import scale

data = load_breast_cancer()
# print(data)
x, y = scale(data['data'][:, :2]), data['target']

# 两个维度对应的数据在逻辑回归算法下的最优解
lr = LogisticRegression(fit_intercept=False)
lr.fit(x, y)
# print(lr.coef_)
theta1 = lr.coef_[0, 0]
theta2 = lr.coef_[0, 1]
print(theta1, theta2)


# 已知w1和w2的情况下,传进来数据的x,返回数据的y_predict
def p_theta_function(features, w1, w2):
    z = w1 * features[0] + w2 * features[1]
    result = 1 / (1 + np.exp(-z))
    return result


# 传入一份已知数据的x,y,如果已知w1,w2的情况下,计算对应这份数据的Loss
def loss_function(sample_features, sample_labels, w1, w2):
    result = 0
    # 遍历数据集中的每一条样本,并且计算每一条样本的损失,加到result身上得到整体的数据集的损失
    for features, label in zip(sample_features, sample_labels):
        # 这是计算一条样本的y_predict
        p_result = p_theta_function(features, w1, w2)
        loss_result = -1 * label * np.log(p_result) - (1 - label) * np.log(1 - p_result)
        result += loss_result
    return result


theta1_space = np.linspace(theta1 - 0.6, theta1 + 0.6, 50)
theta2_space = np.linspace(theta2 - 0.6, theta2 + 0.6, 50)

result1_ = np.array([loss_function(x, y, i, theta2) for i in theta1_space])
result2_ = np.array([loss_function(x, y, theta1, i) for i in theta2_space])
plt.figure(figsize=(8, 6))
plt.subplot(2, 2, 1)
plt.plot(theta1_space, result1_)

plt.subplot(2, 2, 2)
plt.plot(theta2_space, result2_)

plt.subplot(2, 2, 3)
theta1_grid, theta2_grid = np.meshgrid(theta1_space, theta2_space)
loos_grid = loss_function(x, y, theta1_grid, theta2_grid)
plt.contour(theta1_grid, theta2_grid, loos_grid)

plt.subplot(2, 2, 4)
# contour()绘画等高线
plt.contour(theta1_grid, theta2_grid, loos_grid, 30)

figs = plt.figure()
ax = Axes3D(fig=figs)
ax.plot_surface(theta1_grid, theta2_grid, loos_grid)

plt.show()

逻辑回归做多分类 

在上面我们主要使用逻辑回归解决二分类问题,那么对于多分类问题我们如何使用逻辑回归来解决呢?
多分类问题是什么,将邮件分为不同类别/标签:工作(y=1),朋友(y=2),家庭(y=3),爱好(y=4) 天气分类:晴天(y=1),多云天(y=2),下雨天(y=3),下雪天(y=4) 医学图示(Medical diagrams):没生病(y=1),感冒(y=2),流感(y=3)。我们使用逻辑回归解决多分类问题的时候,我们将多分类问题转换成二分类问题。比如说我们有1,2,3类,我们把1作为一类,2和3合并在一起作为一类。将三分类转换成三个二分类。

h_\theta^{(2)}(x)=P(y=2|x;\theta)   h_\theta^{(3)}(x)=P(y=3|x;\theta)  h_\theta^{(i)}(x)=P(y=i|x;\theta)
使用不同的函数去预测输入 x,分别计算不同 h(x)的值,然后取其中的最大值。哪个 i 对应 的 h(x)越大,就认为属于哪个。

y=iris["targtet"]
log_reg=LogisticRegression(C=1000,multi_class='ovr',solver='sag',max_iter=1000)

multi_class参数就是 控制进行多分类还是二分类的。

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值