第11关 手把手实现逻辑算法_人工智能课程 - 小象学院

课程目录 小象学院 - 人工智能

关注公众号【Python家庭】领取1024G整套教材交流群学习商务合作。整理分享了数套四位数培训机构的教材,现免费分享交流学习,并提供解答、交流群

你要的白嫖教程,这里可能都有喔~

恭喜你闯进了第11关,让我们继续探索机器学习的奥秘,体验算法的魔力Amazing~

通过上一关的学习,我们已经掌握了逻辑回归的损失函数:

找损失函数的目的是:通过计算损失函数的最小值,找到使逻辑回归模型输出最好预测结果的参数的最优解

梯度下降法

本关我们将使用之前学习的大招——梯度下降法找到损失函数的全局最优解,也就是找到使损失函数取得最小值的参数值。然后再实现一个属于我们自己的逻辑回归算法模型。

此时此刻我要告诉你一个好消息:逻辑回归的这个损失函数没有局部最优解,只存在唯一的全局最优解

听到这个好消息后,是不是瞬间看到了希望,不再为这个复杂的大公式发愁掉头发啦!

那就让我们撸起袖子,开始干!

损失函数的表达式

通常在使用梯度下降法求解损失函数最优参数解之前,为了方便求导,通常会对损失函数公式再除以一个 m(m就是样本的数量),相当于乘以​​。得到逻辑回归最终的损失函数公式:

经过前面的学习,我们已经知道对于数据集中的第i个样本使用逻辑回归进行预测的话,得到的预测概率的计算公式是:

使用的计算公式替换掉损失函数中的得到:

符号含义

我们来分析下公式中的这些看着就脑袋疼的字母的含义:

m:表示数据集中样本的数量;

:表示数据集中第i个样本的标签,表示样本所属类别;

:是Sigmoid函数,表示数据集中第i个样本的特征向量。

很明显这个公式里的未知变量只有,我们要做的事情就是要找到一个合适的向量使损失函数值最小。

对损失函数求导

接下来我们使用梯度下降法求解逻辑回归损失函数中的系数

在使用梯度下降法的求解过程中,需要对求导数,也就是求梯度,这里我直接给出逻辑回归损失函数的梯度计算公式:

还记得之前我们学习过的使用梯度下降法寻找一个函数的极值点的过程吗?我们来回忆一下。

1)在函数曲线上行选取一个初始点;

2)从初始点开始,向函数值减小的方向移动,这一步是对函数中的未知变量求导,也就是计算梯度,导数的正方向指向函数值增大的方向,要是向函数值减小的方向移动,就要在计算出来的导数(梯度)之前加个负号,这样就表示向导数的负方向移动,也就是函数值减小的方向;

3)移动的时候,要设置移动的步长,也就是学习率,梯度与学习率的乘积决定了移动的方向和移动的距离。

4)检查移动到了极值点,如果没有到达极值点,循环执行第2、3步。

代码实现

sigmoid函数代码实现

定义一个sigmoid函​​,使用numpy提供的exp函数可以直接计算出以e为底,-t为指数的幂运算

AI_11_0_1

import numpy as np
'''
sigmoid函数
参数:
    t:sigmoid函数中e的指数
返回值:
    返回一个列向量,向量中一个元素对应一个样本的预测概率值
'''
def sigmoid(t):
    return 1. / (1. + np.exp(-t)) 

损失函数代码实现

定义逻辑回归损失函数

AI_11_0_2

import numpy as np
'''
逻辑回归的损失函数J
参数:
    theta:函数中每个特征前的系数组成的向量
    X:样本特征数据集
    y:样本标签数据集  
'''
def J(theta, X, y):
    # 调用sigmoid函数,得到样本的预测概率值p_hat
    t = X.dot(theta) #使用numpy提供的 .dot 矩阵乘法,实现X中的每个特征与其对应的theta中的系数相乘
    p_hat = sigmoid(t)
    
    # 根据损失函数公式计算,len(y)表示数据集中样本数量,也就是公式中的m,除以len(y)就是除以m
    return - np.sum(y*np.log(p_hat) + (1-y)*np.log(1-p_hat)) / len(y)

损失函数的梯度代码实现

定义损失函数函数对求导,也就是定义计算梯度的函数,

AI_11_0_3

'''
计算梯度

参数:
    theta:函数中每个特征前的系数组成的向量
    X:样本特征数据集
    y:样本标签数据集

返回值:
    一个列向量,最终的梯度
'''
def dJ(theta, X, y):
    t = X.dot(theta)
    return X.T.dot(sigmoid(t) - y) / len(y) #X.T矩阵X的转置

梯度下降法代码实现

使用梯度下降法,求出逻辑回归的损失函数取最小值时的

AI_11_0_4

from sys import path
path.append(r"../data/course_util")
from ai_course_11_1 import *

'''
梯度下降法 求出损失函数取最小值时的theta

参数:
    X:样本特征数据集
    y:样本标签数据集 
    initial_theta:手动设置的theta初始值
    eta:学习率,移动的步长
    epsilon:一个非常接近于0的值
    
返回值:
    theta
'''
def gradient_descent(X, y, initial_theta, eta, epsilon=1e-8):
    theta = initial_theta
    while True:
        # 计算梯度
        gradient = dJ(theta, X, y)  # 调用上面定义的计算梯度的函数dJ
        
        #保存上一次的theta
        last_theta = theta
        
        #计算本次的theta
        theta = theta - eta * gradient #本次theta = 上一次的theta - 学习率 * 梯度
        
        #最近的两次损失值进行对比,本次得到的theta带入损失函数得到的损失值 减去 上一次的损失值
        #如果两次的损失差值无限接近0,就证明已经找到了损失函数的最小值
        if (abs(J(theta, X, y) - J(last_theta, X, y)) < epsilon):
            
            #如果找到了损失函数的最小值,直接跳出while循环
            break
            
    # 返回取损失函数最小值时的theta
    return theta

训练模型代码实现

定义训练逻辑回归模型的fit函数

AI_11_0_5

from sys import path
path.append(r"../data/course_util")
from ai_course_11_2 import *

'''
用于训练逻辑回归模型

参数:
    X_train:训练特征数据集
    y_train:训练标签数据集

返回值:
    theta
'''
def fit(X_train,y_train):
    # 给训练数据集X_train添加一列全1的特征,这样做的目的是给每一个样本添加一个X0特征,X0恒等于1
    X = np.hstack([np.ones((len(X_train), 1)), X_train])
    
    # 设置theta的初始值全为0,theta是个向量,向量中每个元素对应样本特征前的一个系数,
    # 所以theta的元素个数与数据集X中的样本的特征个数相等,
    # 通过numpy的zeros函数创建一个与数据集X样本的特征个数相等的一个全零向量
    initial_theta = np.zeros(X.shape[1])
    
    # 设置学习率eta初始值
    eta = 0.01
    
    # 调用上面定义的使用梯度下降法求出损失函数取最小值时的theta
    theta = gradient_descent(X, y_train, initial_theta, eta)
    
    return theta

预测函数代码实现

定义预测函数,使用训练好的逻辑回归模型对新样本进行预测,预测值是0或者1,0和1分别代表两个不同的类别

AI_11_0_6

from sys import path
path.append(r"../data/course_util")
from ai_course_11_2 import *

'''
逻辑回归预测函数

参数:
    X_predict:待预测样本的特征数据集
    theta:通过fit函数训练好的theta
返回值:
    数组,存有待预测样本的所属类别
'''
def predict(X_predict,theta):
    # 给样本添加一个全1列,目的是为了方便矩阵运算
    x_predict_new = np.hstack([np.ones((len(X_predict), 1)), X_predict])
    
    #通过sigmoid函数计算概率,p_hat向量里的元素是针对每个预测样本的预测概率值,概率值是0到1之间的浮点数
    p_hat = sigmoid(x_predict_new.dot(theta))
    
    # 根据p_hat的概率值,划分预测样本对应的类别是0或1
    # 划分的边界值是0.5,p_hat向量里的概率值大于等于0.5的返回True,小于0.5的返回False,
    # 所以通过p_hat >= 0.5操作之后,p_hat向量里的元素就变成了True或False
    # 通过设置array函数的dtype='int',将p_hat向量中的True或False转换成1或者0
    return np.array(p_hat >= 0.5,dtype='int')

计算准确率代码实现

模型训练好了之后,我们还要用测试数据集来测试模型的好坏,那么我们就定义一个计算模型预测准确率的函数。

AI_11_0_7

from sys import path
path.append(r"../data/course_util")
from ai_course_11_3 import *
'''
通过准确率判断模型的好坏

参数:
    x_test:测试特征数据集
    y_test:测试标签数据集
返回值:
    准确率,浮点数
'''
def score(x_test, y_test,theta):
    y_predict = predict(x_test,theta)
    #预测结果与真实值相等的数量/真实值的数量
    return sum(y_predict == y_test)/len(y_test)

到此,我们已经实现了使用梯度下降法,求出逻辑回归的损失函数取最小值时的,并且实现了一个逻辑回归算法的核心部分。

本关的内容融合了上一关的烧脑内容,需要静下心来好好想一想,虽然数学公式有些烧脑,但是不要害怕,我们先掌握解决问题的方法,等有时间慢慢再把数学吃透,千万不要陷入只盯着数学公式不放,陷入死胡同出不来!

虽然在学习机器学习算法的过程中,数学很重要!但是你目前处在的阶段,数学不是最重要的。入门!兴趣!信心!才是最重要的!

相信自己!加油! 今天我们先到这里,拜拜~

 

联系我们,一起学Python吧

分享Python实战代码,入门资料,进阶资料,基础语法,爬虫,数据分析,web网站,机器学习,深度学习等等。


​关注公众号「Python家庭领取1024G整套教材交流群学习商务合作

猜你喜欢

转载自blog.csdn.net/qq_34409973/article/details/115111707