logistic回归

一、介绍#

逻辑回归算法属于监督学习的分类算法,用于解决二分类(0或1)问题
一篇很好的概念介绍https://zhuanlan.zhihu.com/p/28408516

1、sigmoid函数#

逻辑回归引入sigmoid函数进行分类
g(x)=11+ex
当x为0时,值为0.5
当x减小时,值趋近0
当x增大时,值趋近1

Copy
def sigmoid(x): return 1 / (1 + exp(-x))

图如下

2、分类器#

逻辑回归分类器即对每一个特征乘以一个回归系数,然后把所有的值相加,将和带入sigmoid函数中,通过阀值0.5分为两类

3、回归系数#

通过最优化算法找出最佳回归系数——梯度上升法
梯度
f(x,y)=(fx,fy)
即总是指向函数值增长最快的方向,可以用来求函数最大值
设移动为a,那么梯度上升算法的迭代公式为
w=w+af(w)
一直迭代,直至在某个条件下停止(如设定的误差范围)

二、训练算法#

1、梯度上升找最佳系数#

该处代码有数学推导结论,我当时看也是有点懵,找到两篇推导过程,但没看太懂
https://www.cnblogs.com/weiququ/p/9414746.html
https://zhuanlan.zhihu.com/p/28415991

Copy
# data为一个二维列表,每一行代表一条数据,每一列代表一个特征值,初始时第一个特征值初始为1 # label为每条数据对应的类别列表,用0,1区别 def gradAscent(data, label): dataMat = mat(data) label = mat(label).T # 转为矩阵后转置便于矩阵乘 m, n = shape(dataMat) a = 0.001 # a为步长参数 w = ones((n, 1)) # 初始为一个有n行1列的值为1 的列向量,即回归系数初始化为1 # 这里500为迭代次数的参数 for i in range(500): error = label - sigmoid(dataMat * w) # 计算与实际的相差的值 w = w + a * dataMat.T * error # 然后对该系数w用error不断调整 return w

结果如下

数据集来自《机器学习实战第五章》
用到的画图函数如下

Copy
# w为最后得出的参数 def draw(data, label, w): import matplotlib.pyplot as plt dataArr = array(data) m, n = shape(dataArr) x1 = [] y1 = [] x2 = [] y2 = [] for i in range(m): if label[i] == 0: x1.append(dataArr[i, 1]) y1.append(dataArr[i, 2]) else: x2.append(dataArr[i, 1]) y2.append(dataArr[i, 2]) fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(x1, y1, s=30, c='red') ax.scatter(x2, y2, s=30, c='blue') # 画出最优的拟合直线 x = arange(-3, 3, 0.1) y = (-w[0] - w[1] * x) / w[2] ax.plot(x, y) plt.show()

2、随机梯度上升找最佳系数#

用于改进计算复杂度高的问题,每一次仅用一个样本来更新回归系数

Copy
def randGrad(data, label): dataArr = array(data) m, n = shape(dataArr) a = 0.01 w = ones(n) for i in range(m): h = sigmoid(sum(dataArr[i] * w)) error = label[i] - h w = w + a * dataArr[i] * error return w

结果如下

3、改进随机梯度上升找最佳系数#

为了使系数能减少周期波动,快速收敛,每一次随机用一个样本来更新回归系数,且每次都调整步长参数a

Copy
def enRandGrad(data, label): dataArr = array(data) m, n = shape(dataArr) w = ones(n) # 150为迭代的次数参数 for i in range(150): dataIndex = list(range(m)) for j in range(m): a = 4 / (1 + i + j) + 0.01 # 调整步长参数a # 随机选取一个样本更新参数 randIndex = int(random.uniform(0, len(dataIndex))) h = sigmoid(sum(dataArr[randIndex] * w)) error = label[randIndex] - h w = w + a * dataArr[randIndex] * error del (dataIndex[randIndex]) return w

结果如下

数据集里三个系数的变化如下

posted @   启林O_o  阅读(380)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示
CONTENTS