python如何实现梯度下降求解逻辑回归

线性回归

1.线性回归函数

似然函数的定义:给定联合样本值X下关于(未知)参数 的函数

似然函数:什么样的参数跟我们的数据组合后恰好是真实值     

2.线性回归似然函数

对数似然:

 3.线性回归目标函数

(误差的表达式,我们的目的就是使得真实值与预测值之前的误差最小)

(导数为0取得极值,得到函数的参数)

逻辑回归

逻辑回归是在线性回归的结果外加一层Sigmoid函数

1.逻辑回归函数

2.逻辑回归似然函数

前提数据服从伯努利分布

对数似然:

引入 转变为梯度下降任务,逻辑回归目标函数

梯度下降法求解

 我的理解就是求导更新参数,达到一定条件后停止,得到近似最优解

代码实现

Sigmoid函数

def sigmoid(z):    
   return 1 / (1 + np.exp(-z))

预测函数

def model(X, theta):    
    return sigmoid(np.dot(X, theta.T))

目标函数

def cost(X, y, theta):    
     left = np.multiply(-y, np.log(model(X, theta)))    
     right = np.multiply(1 - y, np.log(1 - model(X, theta)))    
     return np.sum(left - right) / (len(X))

梯度

def gradient(X, y, theta):    
  grad = np.zeros(theta.shape)    
  error = (model(X, theta)- y).ravel()    
  for j in range(len(theta.ravel())): #for each parmeter        
     term = np.multiply(error, X[:,j])        
     grad[0, j] = np.sum(term) / len(X)    
   return grad

梯度下降停止策略

STOP_ITER = 0
STOP_COST = 1
STOP_GRAD = 2
 
def stopCriterion(type, value, threshold):
    # 设定三种不同的停止策略
    if type == STOP_ITER:  # 设定迭代次数
        return value > threshold
    elif type == STOP_COST:  # 根据损失值停止
        return abs(value[-1] - value[-2]) < threshold
    elif type == STOP_GRAD:  # 根据梯度变化停止
        return np.linalg.norm(value) < threshold

样本重新洗牌

import numpy.random
#洗牌
def shuffleData(data):
    np.random.shuffle(data)
    cols = data.shape[1]
    X = data[:, 0:cols-1]
    y = data[:, cols-1:]
    return X, y

梯度下降求解

def descent(data, theta, batchSize, stopType, thresh, alpha):
    # 梯度下降求解
 
    init_time = time.time()
    i = 0  # 迭代次数
    k = 0  # batch
    X, y = shuffleData(data)
    grad = np.zeros(theta.shape)  # 计算的梯度
    costs = [cost(X, y, theta)]  # 损失值
 
    while True:
        grad = gradient(X[k:k + batchSize], y[k:k + batchSize], theta)
        k += batchSize  # 取batch数量个数据
        if k >= n:
            k = 0
            X, y = shuffleData(data)  # 重新洗牌
        theta = theta - alpha * grad  # 参数更新
        costs.append(cost(X, y, theta))  # 计算新的损失
        i += 1
 
        if stopType == STOP_ITER:
            value = i
        elif stopType == STOP_COST:
            value = costs
        elif stopType == STOP_GRAD:
            value = grad
        if stopCriterion(stopType, value, thresh): break
 
    return theta, i - 1, costs, grad, time.time() - init_time

完整代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import numpy.random
import time
 
 
def sigmoid(z):
    return 1 / (1 + np.exp(-z))
 
 
def model(X, theta):
    return sigmoid(np.dot(X, theta.T))
 
 
def cost(X, y, theta):
    left = np.multiply(-y, np.log(model(X, theta)))
    right = np.multiply(1 - y, np.log(1 - model(X, theta)))
    return np.sum(left - right) / (len(X))
 
 
def gradient(X, y, theta):
    grad = np.zeros(theta.shape)
    error = (model(X, theta) - y).ravel()
    for j in range(len(theta.ravel())):  # for each parmeter
        term = np.multiply(error, X[:, j])
        grad[0, j] = np.sum(term) / len(X)
    return grad
 
 
STOP_ITER = 0
STOP_COST = 1
STOP_GRAD = 2
 
 
def stopCriterion(type, value, threshold):
    # 设定三种不同的停止策略
    if type == STOP_ITER:  # 设定迭代次数
        return value > threshold
    elif type == STOP_COST:  # 根据损失值停止
        return abs(value[-1] - value[-2]) < threshold
    elif type == STOP_GRAD:  # 根据梯度变化停止
        return np.linalg.norm(value) = n:
            k = 0
            X, y = shuffleData(data)  # 重新洗牌
        theta = theta - alpha * grad  # 参数更新
        costs.append(cost(X, y, theta))  # 计算新的损失
        i += 1
 
        if stopType == STOP_ITER:
            value = i
        elif stopType == STOP_COST:
            value = costs
        elif stopType == STOP_GRAD:
            value = grad
        if stopCriterion(stopType, value, thresh): break
 
    return theta, i - 1, costs, grad, time.time() - init_time
 
 
def runExpe(data, theta, batchSize, stopType, thresh, alpha):
    # import pdb
    # pdb.set_trace()
    theta, iter, costs, grad, dur = descent(data, theta, batchSize, stopType, thresh, alpha)
    name = "Original" if (data[:, 1] > 2).sum() > 1 else "Scaled"
    name += " data - learning rate: {} - ".format(alpha)
    if batchSize == n:
        strDescType = "Gradient"  # 批量梯度下降
    elif batchSize == 1:
        strDescType = "Stochastic"  # 随机梯度下降
    else:
        strDescType = "Mini-batch ({})".format(batchSize)  # 小批量梯度下降
    name += strDescType + " descent - Stop: "
    if stopType == STOP_ITER:
        strStop = "{} iterations".format(thresh)
    elif stopType == STOP_COST:
        strStop = "costs change < {}".format(thresh)
    else:
        strStop = "gradient norm = 0.5 else 0 for x in model(X, theta)]
 
 
# 计算精度
scaled_X = scaled_data[:, :3]
y = scaled_data[:, 3]
predictions = predict(scaled_X, theta)
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y)]
accuracy = (sum(map(int, correct)) % len(correct))
print('accuracy = {0}%'.format(accuracy))

逻辑回归的优缺点

优点

  • 形式简单,模型的可解释性非常好。从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大。

  • 模型效果不错。在工程上是可以接受的(作为baseline),如果特征工程做的好,效果不会太差,并且特征工程可以大家并行开发,大大加快开发的速度。

  • 训练速度较快。分类的时候,计算量仅仅只和特征的数目相关。并且逻辑回归的分布式优化sgd发展比较成熟,训练的速度可以通过堆机器进一步提高,这样我们可以在短时间内迭代好几个版本的模型。

  • 资源占用小,尤其是内存。因为只需要存储各个维度的特征值。

  • 方便输出结果调整。逻辑回归可以很方便的得到最后的分类结果,因为输出的是每个样本的概率分数,我们可以很容易的对这些概率分数进行cutoff,也就是划分阈值(大于某个阈值的是一类,小于某个阈值的是一类)。

缺点

  • 准确率并不是很高。因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布。

  • 很难处理数据不平衡的问题。举个例子:如果我们对于一个正负样本非常不平衡的问题比如正负样本比 10000:1.我们把所有样本都预测为正也能使损失函数的值比较小。但是作为一个分类器,它对正负样本的区分能力不会很好。

  • 处理非线性数据较麻烦。逻辑回归在不引入其他方法的情况下,只能处理线性可分的数据,或者进一步说,处理二分类的问题 。

  • 逻辑回归本身无法筛选特征。有时候,我们会用gbdt来筛选特征,然后再上逻辑回归。

以上就是python如何实现梯度下降求解逻辑回归的详细内容,更多请关注昆居客【www.kunjuke.com】。

相关推荐:

Edge浏览器数学求解器怎么用截图识别公式解答_Edge浏览器理科辅助教程

Edge浏览器需先启用数学求解器功能,再通过快捷键截图、边栏框选或上传图片识别公式并求解。 如果您在Edge浏览器中看到网页上的数学公式但无法直接计算,或手头有含公式的截图却不知如何快速调用求解能力,则可能是尚未掌握截图识别的正确路径或未启用对应功能。以下是使用Edge浏览器通过截图方式识别数学公式并获取解答的具体操作方法: 一、启用数学求解器功能 该功能默认处于关闭状态,必须手动开启才能激活截图...

Edge浏览器如何使用数学求解器绘制微积分函数图像_Edge浏览器高级理科工具

Edge中绘制微积分图像需启用数学求解器、使用=y=快捷指令、执行plot()脚本、安装Desmos/GeoGebra扩展或结合标注工具辅助讲解,五种方法覆盖从基础到专业级需求。 如果您在Edge浏览器中尝试绘制微积分相关的函数图像(如导数曲线、定积分区域、原函数族等),但无法获得图形化结果,则可能是由于数学求解器未启用、输入格式不兼容或当前环境不支持高级绘图功能。以下是实现微积分函数图像绘制的多...

Hermes Agent如何实现长期记忆

Hermes Agent 的长期记忆机制通过五层协同实现:一、MEMORY.md 作为温记忆层,存储高价值静态约束;二、外部记忆 Provider(如 mem0)扩展语义检索能力;三、Session Search 基于 SQLite FTS5 实现冷记忆全文检索;四、SKILL.md 沉淀程序性知识;五、USER.md 构建用户画像锚点。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模...

王者荣耀s43打野梯度如何排行

王者荣耀S43赛季打野梯队:新“四大野王”诞生,肉装刺客登顶T0 问AI·马超和赵云崛起的关键因素是什么? S43赛季的打野位,有两件T0级的“轮椅”神装,强度甚至远超巅峰时期的红莲斗篷,它俩就是怒龙剑盾(黄盾)和名刀。 黄盾在多次调整后,已经成为打野的标配,不管是前中期出还是后期出,都有相当不错的效果,毕竟黄盾既有回血和增伤又能快速推塔。 甚至属性上还有150双抗和1100最大生命,相当于同时兼...

OpenClaw如何实现自动内容生产

OpenClaw通过模块化技能编排与多智能体协同实现端到端自动内容生产:构建本地闭环架构、启动研究/创作/SEO/设计Agent协同流程、跨平台格式化发布、定时调度与熔断机制、直连Obsidian草稿箱。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 如果您希望内容创作过程脱离人工重复操作,OpenClaw可通过模块化技能编排与多智能体协同...
· AI · 299268

Hermes Agent如何实现智能客服

Hermes Agent应用于智能客服需配置五大环节:一、启用NLU模块进行意图识别;二、配置会话级上下文缓存维持多轮对话焦点;三、接入结构化知识库实现RAG精准应答;四、绑定消息网关对接飞书等平台;五、注入业务工具链支持自动化操作。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 如果您希望将Hermes Agent应用于智能客服场景,则需...
· AI · 253858

WPS Office 2019如何实现数值四舍五入

在wps office 2019中,实现数值四舍五入有多种高效方式,操作简单且适用场景丰富。 借助函数完成精准四舍五入 ROUND 函数 - 在目标单元格中输入公式:=ROUND(数值, 小数位数)。例如,若需将A1单元格的值保留两位小数并四舍五入,可输入 =ROUND(A1,2),回车后即显示处理结果。 - 参数说明:“小数位数”为正数时,表示保留对应位数的小数;为0时,四舍五入至个位整数;为负...

Edge浏览器如何使用数学求解器识别并解答手写微积分公式_Edge浏览器屏幕截取步骤高级用法

Edge中手写微积分公式识别失败时,需启用手写输入模式、精准截图、混合修正或图像优化:一启用Windows Ink手写转LaTeX;二截图整题并修正OCR结果;三手写主干+键盘补全LaTeX命令;四提升对比度与符号清晰度。 如果您在Edge浏览器中面对手写微积分公式(如纸质习题、课堂笔记或触屏设备上的笔迹),但系统未能准确识别或无法直接调用求解功能,则可能是由于手写输入模式未启用、截图区域不完整或...