专栏首页大数据建模的一点一滴徒手撸算法 | 逻辑回归

徒手撸算法 | 逻辑回归

逻辑回归是线性回归的改进,通过特定的连接函数将实数范围压缩到(0, 1)范围内,从而实现分类的目的。

01

逻辑回归模型

1)逻辑回归的一般形式

其中,x=(x0, x1, x2, ..., xp)T,θm=(θm0, θm1, θm2, ..., θmp)T,x0是恒为1的变量,θm0是截距项,选择类别M的概率作为分母项,不过实际上分母项的选择可以是任意的,并且不同选择的结果都是等价的。

将上式做一下变换:

M个类别的概率和为1,所以:

从而可得每个类别的概率模型:

从上式很容易看出该模型取值在(0, 1)之间,各类别概率之和为1。为了简化书写,令Φ=(θ1, θ2, ..., θM-1),并且

2)当M取值为2时,即为最常见的二分类问题,逻辑回归模型只有一个函数式。当G=1时,令y=1,当G=2时,令y=0;令β=θ1,且β=(β0, β1, ..., βp)T,则Φ=β;令

则二分类问题逻辑回归模型如下:

02

损失函数

1)逻辑回归的损失函数可以通过极大似然值法推导出来, 称之为对数似然损失,如下式:

2)二分类问题的损失函数更为简化,y为目标变量,取值为1或0:

03

优化算法

接下来主要看二分类问题逻辑回归的优化算法,仍然采用小批量梯度下降法求解参数值,令每次迭代的小批量样本为B,|B|为小批量样本的大小,则小批量样本上的平均损失为:

参数β的梯度为:

下面推导

的值:

因此:

可以看出和线性回归的梯度即为极为相似。 小批量梯度下降法下参数β的迭代公式为:

04

算法实现

1)构造数据

创建二分类问题数据集

from sklearn.datasets import make_classification
import numpy as np
import random
##### 生成数据集
# 设置预测变量个数
num_features = 5 
# 设置样本个数
num_samples = 10000
# 创建预测变量和类别标签
features, labels = make_classification(n_samples=num_samples,
                           n_features=num_features,
                           n_informative=num_features,
                           n_redundant=0,
                           n_repeated=0,
                           n_classes=2,
                           weights=[0.7, 0.3],
                           flip_y=0.01,
                           random_state=9999)

# 加入恒为1的x0变量
inputs = np.concatenate((np.ones((num_samples, 1)), features), axis=1)
# 转换labels的形状,便于后面矩阵运算
labels = labels.reshape((-1, 1))

2)设置数据集上小批量样本迭代函数

def batch_iter(X, y, batch_size):
    num_samples = len(X)
    indices = list(range(num_samples))
    random.shuffle(indices)
    X_iter = []
    y_iter = []
    for i in range(0, num_samples, batch_size):
        j = np.array(indices[i: min(i + batch_size, num_samples)])
        X_iter.append(X[j])
        y_iter.append(y[j])
    return zip(X_iter, y_iter)

3)定义逻辑回归模型

# 使用dot函数做矩阵乘法
def lr(X, β):
    return np.exp(np.dot(X, β))/(1+np.exp(np.dot(X, β)))

4)初始化模型参数

# 将系数初始化成均值为0、标准差为0.01的正态随机数
β = np.random.normal(scale=0.01, size=(num_features+1, 1))

5)训练模型

# 设置学习率
η = 0.03 
# 设置迭代次数,每一次迭代都会通过小批量方式遍历所有样本
num_epochs = 5
# 设置小批量样本大小
batch_size = 100
for epoch in range(num_epochs):
    # 通过小批量样本上的梯度更新参数,X和y分别是小批量样本的变量和标签
    for X, y in batch_iter(inputs, labels, batch_size):
        # 估计类别1的概率
        p_1 = lr(X, β)
        # 计算参数β的梯度,这里应用矩阵乘法实现并行运算
        grad_β = np.dot(X.T, p_1-y)/len(X)
        # 更新参数β
        β -= η*grad_β

查看参数估计值

print(β)
[[-0.36033302]
 [ 0.27190985]
 [ 0.353429  ]
 [ 0.27806906]
 [-0.13492305]
 [ 0.54404067]]

6)预测概率

labels_pred = lr(inputs, β)
labels_pred
array([[0.21602106],
       [0.12966306],
       [0.9286301 ],
       ...,
       [0.15740949],
       [0.93437218],
       [0.14647787]])

7)预测效果,KS计算查看链接Python实现KS

# 将 labels_pred、labels转换成一维数组
labels_pred = labels_pred.reshape((len(labels_pred),))
labels = labels.reshape((len(labels),))
# KS值
PlotKS(labels_pred, labels, 100, 0)

以上,如有发现错误之处,请留言指出。自己写的东西有时怎么看都检查不出错误之处,但其他人看一眼就可能识别出错误,或者隔一段时间自己再回头看,错误之处也能被轻易发现。

相关文章链接

逻辑回归理论基础

本文分享自微信公众号 - 大数据建模的一点一滴(bigdatamodeling),作者:小石头

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 徒手撸算法 | 线性回归

    其中,x1, x2, ..., xp是预测变量,x0恒为1;θ1, θ2, ..., θp是预测变量系数(权重或参数),θ0是偏置项(截距),令θ=(θ0, θ...

    小石头
  • Python | 缺失的处理

    等同于DataFrame.isnull,用于判断各个值是否为缺失,若为缺失返回True值,若为非缺失返回False值,最后返回相同结构的数据框,用法如下:

    小石头
  • 类别变量-卡方分箱

    建模中遇到类别变量时,经常将其转为哑变量进行处理,但若类别变量的属性过多,会生成过多的哑变量,从而导致维度增加,并且很多情况下,只有部分哑变量进入模型,可能损...

    小石头
  • LeetCode动画 | 128.最长连续序列

    今天分享一个LeetCode题,题号是128,标题是最长连续序列,题目标签是并查集和数组。

    我脱下短袖
  • LeetCode图解 | 128.最长连续序列

    今天分享一个LeetCode题,题号是128,标题是最长连续序列,题目标签是并查集和数组。

    五分钟学算法
  • [预训练语言模型专题] BART & MASS 自然语言生成任务上的进步

    BART和MASS都是2019年发布的,面向生成任务,基于Transformer神经翻译结构的序列到序列模型。分别由Facebook 和微软亚洲研究院提出。他们...

    朴素人工智能
  • 使用MySQL正则表达式 __MySQL必知必会

    正则表达式作用是匹配方本,将一个模式(正则表达式)与一个文本串进行比较。 MySQL用WHERE子句对正则表达式提供了初步的支持,允许你指定用正则表达式过滤SE...

    wangxl
  • Leetcode: Convert Sorted Array to Binary Search Tree

    题目: Given an array where elements are sorted in ascending order, convert it to...

    卡尔曼和玻尔兹曼谁曼
  • 第6章 I/O复用:select和poll函数

    I/O复用:一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪,它就通知进程。 同步I/O:导致请求的进程阻塞,直到I/O操作完成。 异...

    _gongluck
  • python查看api文档

    py3study

扫码关注云+社区

领取腾讯云代金券