梯度下降及线性回归作业

目录

1.梯度下降作业

 1.手写版本

2.代码版本 

2.线性回归作业 


1.梯度下降作业

1.单元函数

 1.手写版本

2.代码版本 

1.

import numpy as np
import matplotlib.pyplot as plt
# f的函数值
def f(x):
    return x ** 2 * 0.5 -2 * x + 3
def d_f(x):
    return (x - 2)

#定义梯度下降算法
def gradient_descent():
    times = 100 # 迭代次数
    alpha = 0.1 # 学习率
    x =10# 设定x的初始值
    x_axis = np.linspace(-10, 10) #设定x轴的坐标系
    fig = plt.figure(1,figsize=(5,5)) #设定画布大小
    ax = fig.add_subplot(1,1,1) #设定画布内只有一个图
    ax.set_xlabel('X', fontsize=14)
    ax.set_ylabel('Y', fontsize=14)
    ax.plot(x_axis,f(x_axis)) #作图
    #进行迭代
    for i in range(times):
        x1 = x          
        y1= f(x)  
        print("第%d次迭代:x=%f,y=%f" % (i + 1, x, y1))
        x = x - alpha * d_f(x) #更新x
        y = f(x) #更新y
        ax.plot([x1,x], [y1,y], 'ko', lw=1, ls='-', color='coral')
    plt.show()

if __name__ == "__main__":
    gradient_descent()

结果:

 

 2.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#求fx的函数值
def fx(x, y):#定义函数
    return (x - 10) ** 2 + (y - 10) ** 2
def d_fx(x,y):#对x的偏导
    return 2 * (x - 10)
def d_fy(x,y):#对y的偏导
    return 2 * (y - 10)

def gradient_descent():
    times = 100 # 迭代次数
    alpha = 0.1 # 学习率
    x = 20 # x的初始值
    y = 20 # y的初始值

    #绘图操作
    fig = Axes3D(plt.figure()) # 将画布设置为3D
    axis_x = np.linspace(0, 20, 100)#设置X轴取值范围
    axis_y = np.linspace(0, 20, 100)#设置Y轴取值范围
    axis_x, axis_y = np.meshgrid(axis_x, axis_y) #将数据转化为网格数据
    z = fx(axis_x, axis_y)#计算Z轴数值
    fig.set_xlabel('X', fontsize=14)
    fig.set_ylabel('Y', fontsize=14)
    fig.set_zlabel('Z', fontsize=14)
    fig.view_init(elev=60,azim=300)#设置3D图的俯视角度,方便查看梯度下降曲线
    fig.plot_surface(axis_x, axis_y, z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow')) #作出底图
    #计算极值
    for i in range(times):
        x1 = x        
        y1 = y         
        f1 = fx(x, y)  
        print("第%d次迭代:x=%f,y=%f,f=%f" % (i + 1, x1, y1, f1))
        #print(f"第{i+1}次迭代: x={x} y={y} fxy={f1}")
        x = x - alpha * 2 * d_fx(x,y)#更新x
        y = y - alpha * 2 * d_fy(x,y)#更新y
        f = fx(x, y)#更新f
        fig.plot([x1, x], [y1, y], [f1, f], 'ko', lw=2, ls='-')#绘制点
    plt.show()#展示图像

if __name__ == "__main__":
    gradient_descent()

 

2.线性回归作业 

 

# 房屋价格与面积
# 序号:1     2    3    4     5     6     7
# 面积:150  200  250  300   350   400   600  
# 价格:6450 7450 8450 9450 11450 15450 18450 

import matplotlib.pyplot as plt
import matplotlib
from math import pow
from random import uniform
import random

x0 = [150, 200, 250, 300, 350, 400, 600]
y0 = [6450, 7450, 8450, 9450, 11450, 15450, 18450]
# 为了方便计算,将所有数据缩小 100 倍
x = [1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 6.00]
y = [64.50, 74.50, 84.50, 94.50, 114.50, 154.50, 184.50]

# 线性回归函数为 y=theta0+theta1*x
# 参数定义
theta0 = 0.1  # 对 theata0 赋值
theta1 = 0.1  # 对 theata1 赋值
alpha = 0.1  # 学习率
m = len(x)
count0 = 0
theta0_list = []
theta1_list = []

# 使用批量梯度下降法
for num in range(10000):
    count0 += 1
    diss = 0  # 误差
    deriv0 = 0  # 对 theata0 导数
    deriv1 = 0  # 对 theata1 导数
    # 求导
    for i in range(m):
        deriv0 += (theta0 + theta1 * x[i] - y[i]) / m
        deriv1 += ((theta0 + theta1 * x[i] - y[i]) / m) * x[i]
    # 更新 theta0 和 theta1
    for i in range(m):
        theta0 = theta0 - alpha * ((theta0 + theta1 * x[i] - y[i]) / m)
        theta1 = theta1 - alpha * ((theta0 + theta1 * x[i] - y[i]) / m) * x[i]
    # 求损失函数 J (θ)
    for i in range(m):
        diss = diss + (1 / (2 * m)) * pow((theta0 + theta1 * x[i] - y[i]), 2)

    theta0_list.append(theta0 * 100)
    theta1_list.append(theta1)
    # 如果误差已经很小,则退出循环
    if diss <= 100:
        break

theta0 = theta0 * 100  # 前面所有数据缩小了 100 倍,所以求出的 theta0 需要放大 100 倍,theta1 不用变

# 使用随机梯度下降法
theta2 = 0.1  # 对 theata2 赋值
theta3 = 0.1  # 对 theata3 赋值
count1 = 0
theta2_list = []
theta3_list = []

for num in range(10000):
    count1 += 1
    diss = 0  # 误差
    deriv2 = 0  # 对 theata2 导数
    deriv3 = 0  # 对 theata3 导数
    # 求导
    for i in range(m):
        deriv2 += (theta2 + theta3 * x[i] - y[i]) / m
        deriv3 += ((theta2 + theta3 * x[i] - y[i]) / m) * x[i]
    # 更新 theta0 和 theta1
    for i in range(m):
        theta2 = theta2 - alpha * ((theta2 + theta3 * x[i] - y[i]) / m)
        theta3 = theta3 - alpha * ((theta2 + theta3 * x[i] - y[i]) / m) * x[i]
    # 求损失函数 J (θ)
    rand_i = random.randrange(0, m)
    diss = diss + (1 / (2 * m)) * pow((theta2 + theta3 * x[rand_i] - y[rand_i]), 2)

    theta2_list.append(theta2 * 100)
    theta3_list.append(theta3)
    # 如果误差已经很小,则退出循环
    if diss <= 0.001:
        break
theta2 = theta2 * 100

print("批量梯度下降最终得到theta0={},theta1={}".format(theta0, theta1))
print("           得到的回归函数是:y={}+{}*x".format(theta0, theta1))
print("随机梯度下降最终得到theta0={},theta1={}".format(theta2, theta3))
print("           得到的回归函数是:y={}+{}*x".format(theta2, theta3))
# 画原始数据图和函数图
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
plt.plot(x0, y0, 'bo', label='数据', color='black')
plt.plot(x0, [theta0 + theta1 * x for x in x0], label='批量梯度下降', color='red')
plt.plot(x0, [theta2 + theta3 * x for x in x0], label='随机梯度下降', color='blue')
plt.xlabel('x(面积)')
plt.ylabel('y(价格)')
plt.legend()
plt.show()
plt.scatter(range(count0), theta0_list, s=1)
plt.scatter(range(count0), theta1_list, s=1)
plt.xlabel('上方为theta0,下方为theta1')
plt.show()
plt.scatter(range(count1), theta2_list, s=3)
plt.scatter(range(count1), theta3_list, s=3)
plt.xlabel('上方为theta0,下方为theta1')
plt.show()

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值