线性回归、逻辑回归、梯度下降

多元线性回归推导过程
多元线性回归求解过程 解析解求解
梯度下降与随机梯度下降概念及推导过程
逻辑回归(logistics regression)

笔记

1.线性回归是回归问题,通过学习来预测给定一组数据的输出结果;逻辑回归是分类问题,通过学习来预测给定一组数据的分类情况(0还是1)
2.逻辑回归在线性回归的基础上用sigmoid函数把输出映射到0-1区间
3.梯度下降是求解线性回归和逻辑回归的方法,通过计算损失函数梯度来使损失函数以最快的速度降低

梯度下降求解逻辑回归实例

本案例来自唐宇迪机器学习课程,通过两门课程x1,x2的成绩来预测学生是否被录取,目标是求解出矩阵θ使z=θ0+θ1x1+θ2x2代表最终的预测结果。数据分布如图:
在这里插入图片描述
首先定义sigmoid函数、预测模型、损失函数,其中:
X为n*3矩阵,第一列均为1,二三列表示两门课程成绩
y为n*\1矩阵,表示是否被录取
θ为1*3矩阵,初始值均为0

def sigmoid(z):
    return 1 / (1 + np.exp(-z))
def model(X, theta):
    return sigmoid(np.dot(X, theta.T))
theta = np.zeros([1, 3])
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

比较三种不同的停止策略:
1.按迭代次数,达到一定次数停止
2.按损失函数之差,损失函数不再有明显减小停止
3.按梯度,θ减小到一定值停止

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

比较三种不同的梯度下降策略:
1.批量梯度下降(BGD),每次都取所有样本
2.随机梯度下降(SGD),每次只取一个样本
3.小批量梯度下降(mini-batch),每次取一部分样本

import numpy.random
import time
#洗牌,使 SGD 和 mini-batch 每次输入数据都不同
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

批量梯度下降迭代结果

#迭代次数5000停止,学习率为1e-6
descent(orig_data, theta, 100, STOP_ITER, thresh=5000, alpha=0.000001)
#损失函数之差小于1e-6停止,学习率为1e-3
descent(orig_data, theta, 100, STOP_COST, thresh=0.000001, alpha=0.001)
#梯度小于0.05停止,学习率为1e-3
descent(orig_data, theta, n, STOP_GRAD, thresh=0.05, alpha=0.001)


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

随机梯度下降迭代结果

#迭代次数5000停止,学习率为1e-3,可见学习率太高会导致结果不收敛
descent(orig_data, theta, 1, STOP_ITER, thresh=5000, alpha=0.001)
#学习率降为2e-6
descent(orig_data, theta, 1, STOP_ITER, thresh=15000, alpha=0.000002)

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

小批量梯度下降迭代结果

#迭代次数15000停止,学习率为1e-3,依旧不收敛
descent(orig_data, theta, 16, STOP_ITER, thresh=15000, alpha=0.001)

在这里插入图片描述

数据预处理

对数据预处理后,迭代效果会更好,在较高的学习率下也可以得到收敛的结果

#对数据进行标准化
from sklearn import preprocessing as pp
scaled_data = orig_data.copy()
scaled_data[:, 1:3] = pp.scale(orig_data[:, 1:3])

descent(scaled_data, theta, 100, STOP_ITER, thresh=5000, alpha=0.001)
descent(scaled_data, theta, 100, STOP_GRAD, thresh=0.02, alpha=0.001)
descent(scaled_data, theta, 1, STOP_GRAD, thresh=0.002/5, alpha=0.001)
descent(scaled_data, theta, 16, STOP_GRAD, thresh=0.002*2, alpha=0.001)


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

发布了17 篇原创文章 · 获赞 0 · 访问量 561

猜你喜欢

转载自blog.csdn.net/kybxdkybxd/article/details/103493291