机器学习数学基础

机器学习数学基础

总共可以分为五块:高数、线代、概率论与数理统计(考研三大块)、随机过程和mcmc抽样(最后两个严格意义上也属于数理统计的内容)。

本人是应统专业的,后面的就先鸽一下,前面高数线代的内容在这里先补充一下,其实大部分考研也学过,这里就展示下思维导图吧。

高等数学

高数思维导图

线性代数

在这里插入图片描述

随机牛顿法及其代码实现

Rosenbrock函数

Rosenbrock函数是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock在1960年提出,因其函数形状类似香蕉,故别名为香蕉函数:

f ( x , y ) = ( a − x 1 ) 2 + b ( x 2 − x 1 2 ) 2 f(x, y) = (a - x_1)^2 + b(x_2 - x_1^2)^2 f(x,y)=(ax1)2+b(x2x12)2

其中 x = ( x 1 , x 2 ) T ∈ R 2    ; a , b ∈ R \bm{x} = (x_1 , x_2)^T \in R^2 \; ; a,b \in R x=(x1,x2)TR2;a,bR

用python实现该函数:

# 导入第三方库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time
from mpl_toolkits.mplot3d import Axes3D

# Rosenbrock函数
def function(x1, x2, a, b):
    return np.square(a - x1) + b * np.square(x2 - np.square(x1))

# 绘制函数图像
def plot_function(a, b):  
    # 网格数据和函数值
    x = np.arange(-100, 100, 0.1)
    y = np.arange(-100, 100, 0.1)
    x, y = np.meshgrid(x, y)
    z = function(x, y, a, b)

    # 绘制3d图像
    fig = plt.figure()
    ax = plt.axes(projection='3d')

    # 函数图像和找到的最小值点
    ax.plot_surface(x, y, z, alpha=0.3, cmap='winter')

    # 设定显示范围
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')

    # 显示a, b的值
    plt.title('a= %.2f , b= %.2f ' % (a, b))

其图像特点在于当 b b b 符号变为负数或 a = 0 a=0 a=0 时,图像形状就会发生改变:

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

在这里插入图片描述

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

随机牛顿法

随机牛顿法是对牛顿法的改进,它利用多次生成的随机值作为牛顿法的初始值,进行迭代后寻找多个牛顿法结果的最优解,有些类似kmeans++对kmeans的优化。

以求解上面的Rosenbrock函数为例,用python实现牛顿法求其最值:

# 计算函数梯度
def gradient(x1, x2, a, b):
    # 对x1、x2求一阶偏导
    delta_x1 = 4*b*x1**3 - 4*b*x1*x2 + 2*x1 - 2*a
    delta_x2 = -2*b*x1**2 + 2*b*x2
    return np.array([delta_x1, delta_x2]).reshape(-1, 1)

# 计算函数海森矩阵
def Hessian(x1, x2, a, b):
    # 求二阶偏导
    delta_x1x1 = 12*b*x1**2 - 4*b*x2 + 2
    delta_x1x2 = -4*b*x1
    delta_x2x2 = 2*b
    return np.array([[delta_x1x1, delta_x1x2], [delta_x1x2, delta_x2x2]])

# 牛顿法求解函数最小值
def snt(x1, x2, z, newton_times, alpha):    
    # 随机初始化
    rand_init = np.random.randint(0, z.shape[0])
    x1_init, x2_init, z_init = x1[rand_init], x2[rand_init], z[rand_init]
    x_0 = np.array([x1_init, x2_init]).reshape(-1, 1)

    # 进行迭代
    for i in range(newton_times):
        # 计算海森矩阵的逆
        H_inv = np.linalg.inv(Hessian(x1_init, x2_init, a, b))

        # 计算梯度
        grad = gradient(x1_init, x2_init, a, b)

        # 更新参数
        x_i = x_0 - alpha * np.matmul(H_inv, grad)
        x_0 = x_i
        x1_init = x_0[0, 0]
        x2_init = x_0[1, 0]
    
    # 返回终解
    return x_0

随机牛顿求解Rosenbrock函数最小值

随机牛顿中随机优化次数(运行牛顿法的次数)设置为10次,牛顿法的步长设置为0.2,迭代次数设置为1000次,实验代码如下:

# 绘制函数与最值
def plot_data(min_x1, min_x2, min_z, a, b):
    x = np.arange(-100, 100, 0.1)
    y = np.arange(-100, 100, 0.1)
    x, y = np.meshgrid(x, y)
    # 函数值
    z = function(x, y, a, b)
    # 绘制3d图像
    fig = plt.figure()
    ax = plt.axes(projection='3d')

    # 函数图像和找到的最值点
    ax.plot_surface(x, y, z, alpha=0.3, cmap='winter')  
    ax.scatter(min_x1, min_x2, min_z, c='r')

    # 设定显示范围
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
	# 显示a, b的值
    plt.title('a= %.2f , b= %.2f ' % (a, b))

# Rosenbrock函数最值求解
class Rosenbrock():
    def __init__(self):
        self.answers = []
        self.min_answer_z = []

    # 开始
    def start(self):
        # 计算对应函数值
        z = function(x1, x2, a, b)

        # 算法运行开始时间
        start_time = time.time()

        # 记录指定次数随机牛顿法的最终解
        for i in range(times):
            answer = snt(x1, x2, z, newton_times, alpha)
            self.answers.append(answer)
        min_answer = np.array(self.answers)

        # 记录指定次数随机牛顿法的对应的函数值
        for i in range(times):
            self.min_answer_z.append(function(min_answer[i, 0, 0], min_answer[i, 1, 0], a, b))
        
        # 最终优化后的解
        optimal_z = np.min(np.array(self.min_answer_z))
        optimal_z_index = np.argmin(np.array(self.min_answer_z))
        optimal_x1, optimal_x2 = min_answer[optimal_z_index, 0, 0], min_answer[optimal_z_index, 1, 0]

        # 算法运行结束时间
        end_time = time.time()

        # 算法执行时间
        running_time = end_time - start_time

        print('函数最小值%.2f在(%.2f, %.2f)处取得' % (optimal_z, optimal_x1, optimal_x2))
        print('优化的时间:%.2f秒!' % running_time)
        plot_data(optimal_x1, optimal_x2, optimal_z, a, b)

# 开始执行算法
if __name__ == '__main__':
    # 函数与优化参数的输入
    a = float(input("请输入a的值:"))
    b = float(input("请输入b的值:"))
    alpha = float(input("请输入随机牛顿法的步长:"))
    newton_times = int(input("请输入随机牛顿法的迭代次数:"))
    times = int(input("请输入需要随机优化的次数:"))
    x1 = np.arange(-100, 100, 0.0001)
    x2 = np.arange(-100, 100, 0.0001)
    Rosenbrock().start()

结果如下图所示:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值