1.import os

将图导出保存在文件夹里定义保存图片函数

  1. import numpy as np
  2. import pandas as pd
  3. import os #保存文件包
  4. import matplotlib.pyplot as plt

2.定义保存图片函数:

  1. # 根文件夹
  2. root_dir="."
  3. # 创建目录二级目录多层
  4. model_id="linear_model"
  5. def save_fig(file_name):
  6. # 组装文件目录
  7. path=os.path.join(root_dir,"images",model_id)
  8. # 判断路径是否存在
  9. if not os.path.exists(path):
  10. # 不存在就创建path路径
  11. os.makedirs(path)
  12. # 保存文件创建图片文件名
  13. # 文件地址
  14. path=os.path.join(path,file_name)
  15. print("Saving figure",file_name)
  16. plt.savefig(path,format="png",dpi=300)
  17. print(path)

3.生成线性数据: θ+θ1x

特征数据和标签数据用随机数生成.

  1. # 随机种子
  2. # np.random.seed(2)
  3. # 生成训练数据(特征部分)
  4. x=2*np.random.rand(100,1)
  5. # 生成训练数据(特标签部分)
  6. y=4+3*x+np.random.randn(100,1)

4.画出模型数据散点图:

参数rotation=0 坐标轴文字翻转
plt.axis([0,2,0,15]) 设置坐标轴范围
保存图片:save_fig(“linera_scatter.png”)

  1. # rotation 翻转文字
  2. plt.scatter(x,y,color="#fff345")#画图
  3. plt.xlabel("$x_1$",fontsize=16)
  4. plt.ylabel("$y$",fontsize=16,rotation=0)
  5. plt.axis([0,2,0,15])
  6. plt.show()
  7. save_fig("linera_scatter.png")

从个5.png

5.建立模型:#从sklearn包里导入线性回归模型

创建线性回归对象: LinearRegression()
拟合训练数据: linreg.fit(x, y)
做预测 :lin_reg.predict(x_new)
输出截距lin_reg.intercept
,,斜率 linreg.coef

  1. from sklearn.linear_model import LinearRegression

模型数据测验:

  1. # 创建线性回归对象
  2. lin_reg = LinearRegression() # 调用构造函数 pd.DataFrame()
  3. # 拟合训练数据
  4. lin_reg.fit(x, y)
  5. # 输出截距,斜率
  6. lin_reg.intercept_, lin_reg.coef
  7. #预测测试数据
  8. x_new = np.array([[0], [2]]) # 两行一列的数组
  9. #对测试集进行预测
  10. lin_reg.predict(x_new)

数据80条为训练数据20条为测试数据:
导入分割模块:

  1. from sklearn.model_selection import train_test_split

分割数据块为4部分:

  1. x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=20,random_state=0)

预测三步走:

  1. lin_reg=LinearRegression()
  2. lin_reg.fit(x_train,y_train)
  3. lin_reg.predict(x_test)
  4. 对比test集标签
  5. y_test

对模型评分:score

  1. lin_reg.score(x,y)

一.批量梯度下降:

生成俩列特征数据前面填充一列:

  1. x_b = np.hstack((np.ones((100, 1)), x))
  2. x_b

擦擦擦是7.png

  1. # 步长 step
  2. eta = 0.1
  3. # 迭代次数
  4. n_iterations = 1000
  5. # 数据量
  6. m = len(x_b)#数据形状
  7. #初始化参数
  8. theta = np.random.randn(2,1)
  9. # 梯度下降公式及参数更新公式
  10. for _ in range(n_iterations):# 限定迭代次数
  11. gradients = (1/m) * x_b.T.dot(x_b.dot(theta) - y) #梯度求解公式
  12. theta = theta - eta * gradients #更新theta
  1. # 提供画图的横坐标画图
  2. # 测试集数据
  3. x_new=np.array([[0],[2]])
  4. # 做测试的数据np.c_yu\\与stack一样
  5. x_new_b=np.c_[np.ones((2,1)),x_new]
  6. print(x_new)
  7. print(x_new_b)

函数版:
theta_path_bgd = []
列表收集迭代更新的theta,最后画迭代图

  1. # 为了保存每次更新的theta
  2. theta_path_bgd = []
  3. # [1,2] [2,4]收集θ,最后画三个图
  4. def plot_gradient_descent(theta, eta, theta_path=None,):
  5. m = len(x_b)#数据形状
  6. plt.plot(x, y, "r.")#散点图源数据
  7. n_iterations = 1000 #迭代次数
  8. for i in range(n_iterations):
  9. if i < 10:#取前10
  10. # 测试集预测的结果
  11. y_predict = x_new_b.dot(theta) #
  12. # 测试集确定的直线
  13. plt.plot(x_new, y_predict, "b-")
  14. # 使用训练集计算梯度
  15. gradients = 2/m * x_b.T.dot(x_b.dot(theta) - y)
  16. # 参数更新公式
  17. theta = theta - eta * gradients
  18. if theta_path is not None: #把每个theta添加起来
  19. theta_path.append(theta)
  20. plt.xlabel("$x_1$", fontsize=18)
  21. plt.axis([0, 2, 0, 15])
  22. # eta 专业步长符号
  23. # plt.title(r"$\eta = {}$".format(eta), fontsize=16)
  24. plt.title(r"$\alpha = {}$".format(eta), fontsize=16)

画图:

  1. np.random.seed(42)
  2. theta=np.random.randn(2,1)
  3. fig,ax=plt.subplots(1,3,figsize=(12,5))
  4. plt.subplot(131)
  5. plot_gradient_descent(theta, eta=0.02)
  6. plt.ylabel("$y$",rotation=0,fontsize=18)
  7. plt.subplot(132)
  8. plot_gradient_descent(theta, eta=0.1,theta_path=theta_path_bgd)
  9. plt.ylabel("$y1$",rotation=2,fontsize=18)
  10. plt.subplot(133)
  11. plot_gradient_descent(theta, eta=0.5)
  12. plt.ylabel("$y1$",rotation=0,fontsize=18)

环境.png

随机梯度下降

  1. theta_path_sgd=[]
  2. m=len(x_b)
  3. np.random.seed(42)

n_epochs参数控制外层循环遍历次数
内层循环取每个数据

  1. n_epochs=2
  2. eta=0.1
  3. theta=np.random.randn(2,1)
  4. plt.plot(x, y, "r.")#散点图源数据
  5. for epoch in range(n_epochs):
  6. for j in range(m):
  7. if j<10 and epoch==0:
  8. # 测试集预测y
  9. y_predict=x_new_b.dot(theta)
  10. # 测试集确定的直线
  11. plt.plot(x_new, y_predict, "b-")
  12. x1=x_b[j:j+1]
  13. y1=y[j:j+1]
  14. gradients = 2 * x1.T.dot(x1.dot(theta) - y1)
  15. theta = theta - eta * gradients
  16. theta_path_sgd.append(theta)
  17. plt.xlabel("$x_1$", fontsize=18)
  18. plt.axis([0, 2, 0, 15])
  19. # eta 专业步长符号
  20. plt.title(r"$\alpha = {}$".format(eta), fontsize=16)
  21. # boac
  22. save_fig('sgd_plot')

v4.png

小批量梯度下降

注意时间

  1. theta_path_mgd = []
  2. n_iterations = 5
  3. minibatch_size = 20#
  4. np.random.seed(42)
  5. theta = np.random.randn(2,1) # random initialization
  6. for epoch in range(n_iterations):
  7. # # 数据洗牌,产生一个新的随机顺序
  8. # shuffled_indices = np.random.permutation(m)
  9. # x_b_shuffled = x_b[shuffled_indices]
  10. # y_shuffled = y[shuffled_indices]
  11. for i in range(0, m, minibatch_size):
  12. xi = x_b[i:i+minibatch_size]
  13. yi = y[i:i+minibatch_size]
  14. gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi)
  15. eta = 0.1
  16. theta = theta - eta * gradients
  17. theta_path_mgd.append(theta)

将列表数据转化为array

  1. theta_path_bgd = np.array(theta_path_bgd)
  2. theta_path_sgd = np.array(theta_path_sgd)
  3. theta_path_mgd = np.array(theta_path_mgd)

画图:

  1. plt.figure(figsize=(7,4))
  2. plt.plot(theta_path_sgd[:, 0], theta_path_sgd[:, 1], "r-s", linewidth=1, label="Stochastic")
  3. plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1], "g-+", linewidth=2, label="Mini-batch")
  4. plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1], "b-o", linewidth=3, label="Batch")
  5. plt.legend(loc="upper left", fontsize=16)
  6. plt.xlabel(r"$\theta_0$", fontsize=20)
  7. plt.ylabel(r"$\theta_1$ ", fontsize=20, rotation=0)
  8. plt.axis([2.5, 4.5, 2.3, 3.9])
  9. save_fig("gradient_descent_paths_plot")
  10. plt.show()

从9.png