【吴恩达机器学习-week2】多个变量的线性回归问题

文章目录

  • 1.1 目标
  • 2 问题陈述
  • 3 使用多个变量进行模型预测
    • 3.1 逐元素单独预测
    • 3.2 单一预测,向量
  • 4 使用多个变量计算成本
  • 5 使用多个变量的梯度下降
    • 5.1 使用多个变量计算梯度
  • 多个变量的梯度下降
  • 小结

在这个实验中,你将扩展数据结构和之前开发的程序,以 支持多个特征。一些程序已经更新,使得实验看起来很长,但它只是对之前的程序进行了轻微调整,使得复习起来很快。

1.1 目标

  • 扩展我们的回归模型程序,支持多个特征
  • 扩展数据结构,以支持多个特征
  • 重写预测、成本和梯度程序,以支持多个特征
  • 利用NumPy np.dot 来向量化它们的实现,以提高速度和简化操作
import copy, math
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('./deeplearning.mplstyle')
np.set_printoptions(precision=2)  # reduced display precision on numpy arrays
  • 解释一下:np.set_printoptions(precision=2)

    这段代码设置了NumPy打印数组时的选项,其中precision参数设置了打印浮点数时的精度。在这里,precision=2表示浮点数将被打印为小数点后保留两位的形式。

2 问题陈述

您将使用房价预测的示例。训练数据集包含三个示例,具有四个特征(大小、卧室数、楼层数和房龄),如下表所示。请注意,与之前的实验室不同,此处的大小以平方英尺而不是1000平方英尺为单位。这会导致一个问题,您将在下一个实验室中解决!

大小(平方英尺)卧室数量楼层数房龄(年)价格(1000美元)
21045145460
14163240232
8522135178

您将使用这些值构建一个线性回归模型,以便然后可以预测其他房屋的价格。例如,一个面积为1200平方英尺,有3间卧室,1层楼,40年历史的房子。

请运行以下代码单元格以创建您的x_trainy_train变量。

X_train = np.array([[2104, 5, 1, 45], [1416, 3, 2, 40], [852, 2, 1, 35]])
y_train = np.array([460, 232, 178])

2.1 包含我们示例的矩阵 X

与上面的表类似,示例存储在一个 NumPy 矩阵 X_train 中。矩阵的每一行表示一个示例。当您有 m m m 个训练示例(在我们的示例中为三个)和 n n n 个特征(在我们的示例中为四个)时, X \mathbf{X} X 是一个维度为 ( m , n ) (m,n) (m,n) 的矩阵(m 行,n 列)。

X = ( x 0 ( 0 ) x 1 ( 0 ) ⋯ x n − 1 ( 0 ) x 0 ( 1 ) x 1 ( 1 ) ⋯ x n − 1 ( 1 ) ⋯ x 0 ( m − 1 ) x 1 ( m − 1 ) ⋯ x n − 1 ( m − 1 ) ) \mathbf{X} = \begin{pmatrix} x^{(0)}_0 & x^{(0)}_1 & \cdots & x^{(0)}_{n-1} \\ x^{(1)}_0 & x^{(1)}_1 & \cdots & x^{(1)}_{n-1} \\ \cdots \\ x^{(m-1)}_0 & x^{(m-1)}_1 & \cdots & x^{(m-1)}_{n-1} \end{pmatrix} X= x0(0)x0(1)x0(m1)x1(0)x1(1)x1(m1)xn1(0)xn1(1)xn1(m1)

符号说明:

  • x ( i ) \mathbf{x}^{(i)} x(i) 是包含示例 i 的向量。 x ( i ) \mathbf{x}^{(i)} x(i) = ( x 0 ( i ) , x 1 ( i ) , ⋯ , x n − 1 ( i ) ) = (x^{(i)}_0, x^{(i)}_1, \cdots,x^{(i)}_{n-1}) =(x0(i),x1(i),,xn1(i))
  • x j ( i ) x^{(i)}_j xj(i) 是示例 i i i 中的第 j j j 个元素。括号中的上标表示示例编号,而下标表示元素。

显示输入数据。

# data is stored in numpy array/matrix
print(f"X Shape: {X_train.shape}, X Type:{type(X_train)})")
print(X_train)
print(f"y Shape: {y_train.shape}, y Type:{type(y_train)})")
print(y_train)#print
X Shape: (3, 4), X Type:<class 'numpy.ndarray'>)
[[2104    5    1   45][1416    3    2   40][ 852    2    1   35]]
y Shape: (3,), y Type:<class 'numpy.ndarray'>)
[460 232 178]

2.2 参数向量 w \mathbf{w} w b b b

  • w \mathbf{w} w 是一个包含 n n n 个元素的向量。

    • 每个元素包含与一个特征相关联的参数。

    • 在我们的数据集中, n n n 是 4。

    • 符号上,我们将其绘制为列向量

      w = ( w 0 w 1 ⋯ w n − 1 ) \mathbf{w} = \begin{pmatrix} w_0 \\ w_1 \\ \cdots\\ w_{n-1} \end{pmatrix} w= w0w1wn1

  • b b b 是一个标量参数。

b_init = 785.1811367994083
w_init = np.array([ 0.39133535, 18.75376741, -53.36032453, -26.42131618])
print(f"w_init shape: {w_init.shape}, b_init type: {type(b_init)}")#print
w_init shape: (4,), b_init type: <class 'float'>

3 使用多个变量进行模型预测

模型使用多个变量进行预测的线性模型如下所示:

f w , b ( x ) = w 0 x 0 + w 1 x 1 + . . . + w n − 1 x n − 1 + b (1) f_{\mathbf{w},b}(\mathbf{x}) = w_0x_0 + w_1x_1 +... + w_{n-1}x_{n-1} + b \tag{1} fw,b(x)=w0x0+w1x1+...+wn1xn1+b(1)

或者使用向量表示:

f w , b ( x ) = w ⋅ x + b (2) f_{\mathbf{w},b}(\mathbf{x}) = \mathbf{w} \cdot \mathbf{x} + b \tag{2} fw,b(x)=wx+b(2)

其中 ⋅ \cdot 表示向量的点乘。

为了演示点乘,我们将使用 (1) 和 (2) 实现预测。

3.1 逐元素单独预测

我们先前的预测是将一个特征值乘以一个参数,然后加上一个偏差参数。对于多个特征的预测,直接扩展我们先前的预测实现是使用循环遍历每个元素,执行乘以其参数的操作,然后在末尾加上偏差参数。

def predict_single_loop(x, w, b): n = x.shape[0] # 得到特征值的个数p = 0for i in range(n):p_i = x[i] * w[i]  p = p + p_i         p = p + b                return p
x_vec = X_train[0,:]
print(f"x_vec shape {x_vec.shape}, x_vec value: {x_vec}")# make a prediction
f_wb = predict_single_loop(x_vec, w_init, b_init)
print(f"f_wb shape {f_wb.shape}, prediction: {f_wb}")#print
x_vec shape (4,), x_vec value: [2104    5    1   45]
f_wb shape (), prediction: 459.9999976194083
  • 解释一下:x_vec = X_train[0,:]

    x_vec = X_train[0,:] 这行代码表示从训练数据集 X_train 中提取第一个样本,即第一行,以向量的形式存储在变量 x_vec 中。

x_vec 的形状是 (4,),表示一个包含 4 个元素的 1-D NumPy 向量。而结果 f_wb 是一个标量。

3.2 单一预测,向量

注意到上述的方程 (1) 可以使用向量点乘来实现,就像 (2) 中那样。我们可以利用向量运算来加速预测。

回想一下在 Python/Numpy 实验中,NumPy 的 np.dot() 函数可以用来执行向量点乘。

def predict(x, w, b): p = np.dot(x, w) + b     return p    
# get a row from our training data
x_vec = X_train[0,:]
print(f"x_vec shape {x_vec.shape}, x_vec value: {x_vec}")# make a prediction
f_wb = predict(x_vec,w_init, b_init)
print(f"f_wb shape {f_wb.shape}, prediction: {f_wb}")#print
x_vec shape (4,), x_vec value: [2104    5    1   45]
f_wb shape (), prediction: 459.9999976194083

结果和形状与之前使用循环的版本相同。在接下来的操作中,将使用 np.dot。预测现在是一个单独的语句。大多数例程将直接实现它,而不是调用单独的预测例程。

4 使用多个变量计算成本

具有多个变量的代价函数的方程为:

J ( w , b ) = 1 2 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) 2 (3) J(\mathbf{w},b) = \frac{1}{2m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)})^2 \tag{3} J(w,b)=2m1i=0m1(fw,b(x(i))y(i))2(3)

其中:

f w , b ( x ( i ) ) = w ⋅ x ( i ) + b (4) f_{\mathbf{w},b}(\mathbf{x}^{(i)}) = \mathbf{w} \cdot \mathbf{x}^{(i)} + b \tag{4} fw,b(x(i))=wx(i)+b(4)

与之前的实验室不同, w \mathbf{w} w x ( i ) \mathbf{x}^{(i)} x(i)现在是向量,而不是标量,支持多个特征。

def compute_cost(X, y, w, b): m = X.shape[0] # 样本的个数cost = 0.0for i in range(m):                                f_wb_i = np.dot(X[i], w) + b           #(n,)(n,) = scalar (see np.dot)cost = cost + (f_wb_i - y[i])**2       #scalarcost = cost / (2 * m)                      #scalar    return cost
# Compute and display cost using our pre-chosen optimal parameters. 
cost = compute_cost(X_train, y_train, w_init, b_init)
print(f'Cost at optimal w : {cost}')#print
Cost at optimal w : 1.5578904428966628e-12

5 使用多个变量的梯度下降

多个变量的梯度下降算法如下:

重复 直到收敛: { w j = w j − α ∂ J ( w , b ) ∂ w j 对于 j = 0..n-1 b = b − α ∂ J ( w , b ) ∂ b } \begin{align*} \text{重复}&\text{直到收敛:} \; \lbrace \newline\; & w_j = w_j - \alpha \frac{\partial J(\mathbf{w},b)}{\partial w_j} \tag{5} \; & \text{对于 j = 0..n-1}\newline &b\ \ = b - \alpha \frac{\partial J(\mathbf{w},b)}{\partial b} \newline \rbrace \end{align*} 重复}直到收敛:{wj=wjαwjJ(w,b)b  =bαbJ(w,b)对于 j = 0..n-1(5)

其中, n n n 是特征数量,参数 w j w_j wj b b b 同时更新,其中

∂ J ( w , b ) ∂ w j = 1 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) x j ( i ) ∂ J ( w , b ) ∂ b = 1 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) \begin{align} \frac{\partial J(\mathbf{w},b)}{\partial w_j} &= \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)})x_{j}^{(i)} \tag{6} \\ \frac{\partial J(\mathbf{w},b)}{\partial b} &= \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)}) \tag{7} \end{align} wjJ(w,b)bJ(w,b)=m1i=0m1(fw,b(x(i))y(i))xj(i)=m1i=0m1(fw,b(x(i))y(i))(6)(7)

  • m m m 是数据集中的训练示例数量
  • f w , b ( x ( i ) ) f_{\mathbf{w},b}(\mathbf{x}^{(i)}) fw,b(x(i))是模型的预测值,而 y ( i ) y^{(i)} y(i) 是目标值

5.1 使用多个变量计算梯度

下面是计算方程(6)和(7)的实现。有许多方法可以实现这个。在这个版本中,有一个

  • 外循环遍历所有m个示例。
    • 可以直接计算示例的 ∂ J ( w , b ) ∂ b \frac{\partial J(\mathbf{w},b)}{\partial b} bJ(w,b) 并累积
    • 在第二个循环中遍历所有n个特征:
      • 分别为每个 w j w_j wj 计算 ∂ J ( w , b ) ∂ w j \frac{\partial J(\mathbf{w},b)}{\partial w_j} wjJ(w,b)
def compute_gradient(X, y, w, b): m,n = X.shape           #(number of examples, number of features)dj_dw = np.zeros((n,))dj_db = 0.for i in range(m):                             err = (np.dot(X[i], w) + b) - y[i]   for j in range(n):                         dj_dw[j] = dj_dw[j] + err * X[i, j]    dj_db = dj_db + err       dj_dw = dj_dw / m                                dj_db = dj_db / m                                return dj_db, dj_dw
  • 解释一下:dj_dw = np.zeros((n,))

    这行代码创建了一个大小为(n,)的全零数组,其中 n 是特征的数量。这个数组用于存储每个特征对应的梯度值,初始时全部为零。

#Compute and display gradient 
tmp_dj_db, tmp_dj_dw = compute_gradient(X_train, y_train, w_init, b_init)
print(f'dj_db at initial w,b: {tmp_dj_db}')
print(f'dj_dw at initial w,b: \n {tmp_dj_dw}')#print
dj_db at initial w,b: -1.6739251501955248e-06
dj_dw at initial w,b: 
[-2.73e-03 -6.27e-06 -2.22e-06 -6.92e-05]

多个变量的梯度下降

下面的例程实现了上面的方程(5)。

def gradient_descent(X, y, w_in, b_in, cost_function, gradient_function, alpha, num_iters): J_history = [] # 用于存储每次迭代后计算得到的代价函数的数值。w = copy.deepcopy(w_in)  #avoid modifying global w within functionb = b_infor i in range(num_iters):# Calculate the gradient and update the parametersdj_db,dj_dw = gradient_function(X, y, w, b)   ##None# Update Parameters using w, b, alpha and gradientw = w - alpha * dj_dw               ##Noneb = b - alpha * dj_db               ##None# Save cost J at each iterationif i<100000:      # prevent resource exhaustion J_history.append( cost_function(X, y, w, b))# Print cost every at intervals 10 times or as many iterations if < 10if i% math.ceil(num_iters / 10) == 0:print(f"Iteration {i:4d}: Cost {J_history[-1]:8.2f}   ")return w, b, J_history #return final w,b and J history for graphing
# initialize parameters
initial_w = np.zeros_like(w_init)
initial_b = 0.# some gradient descent settings
iterations = 1000 # 迭代次数
alpha = 5.0e-7 # 学习率# run gradient descent 
w_final, b_final, J_hist = gradient_descent(X_train, y_train, initial_w, initial_b,compute_cost, compute_gradient, alpha, iterations)print(f"b,w found by gradient descent: {b_final:0.2f},{w_final} ")m,_ = X_train.shapefor i in range(m):print(f"prediction: {np.dot(X_train[i], w_final) + b_final:0.2f}, target value: {y_train[i]}")# print
Iteration    0: Cost  2529.46   
Iteration  100: Cost   695.99   
Iteration  200: Cost   694.92   
Iteration  300: Cost   693.86   
Iteration  400: Cost   692.81   
Iteration  500: Cost   691.77   
Iteration  600: Cost   690.73   
Iteration  700: Cost   689.71   
Iteration  800: Cost   688.70   
Iteration  900: Cost   687.69   
b,w found by gradient descent: -0.00,[ 0.2   0.   -0.01 -0.07] 
prediction: 426.19, target value: 460
prediction: 286.17, target value: 232
prediction: 171.47, target value: 178
# plot cost versus iteration  
fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12, 4))
ax1.plot(J_hist)
ax2.plot(100 + np.arange(len(J_hist[100:])), J_hist[100:])
ax1.set_title("Cost vs. iteration");  ax2.set_title("Cost vs. iteration (tail)")
ax1.set_ylabel('Cost')             ;  ax2.set_ylabel('Cost') 
ax1.set_xlabel('iteration step')   ;  ax2.set_xlabel('iteration step') 
plt.show()
  • 解释一下:fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12, 4))

    这行代码使用Matplotlib创建了一个具有两个子图的图形对象。让我来解释一下参数:

    • fig: 这是整个图形对象的实例。
    • (ax1, ax2): 这是一个包含两个子图对象的元组,分别称为 ax1ax2。您可以在每个子图上绘制数据。
    • plt.subplots(1, 2, constrained_layout=True, figsize=(12, 4)): 这是一个函数调用,用于创建子图。具体地:
      • 1, 2 表示我们希望创建一个包含1行和2列的子图网格。
      • constrained_layout = True 是一个布尔参数,用于启用自动布局调整,以确保子图之间的间距和相对大小是合理的。
      • figsize=(12, 4) 指定了图形的尺寸,宽度为12英寸,高度为4英寸。

    这行代码将返回一个包含图形对象和子图对象的元组 (fig, (ax1, ax2))。您可以使用 ax1ax2 对象分别绘制两个子图中的数据。

  • 解释一下:ax2.plot(100 + np.arange(len(J_hist[100:])), J_hist[100:])

    这行代码使用 ax2 对象绘制损失函数的历史记录,但是仅包含从索引100开始的数据。让我逐步解释:

    • ax2.plot(...): 这是 ax2 对象的 plot 方法,用于绘制图形。
    • 100 + np.arange(len(J_hist[100:])): 这是 x 轴的值。它是从 100 开始的索引值,直到损失函数历史记录的末尾。np.arange(len(J_hist[100:])) 创建一个从 0 开始的索引数组,然后通过添加100来将其偏移。
    • J_hist[100:]: 这是损失函数历史记录的切片,从索引100 开始,一直到末尾。这是 y 轴的值,表示从第100次迭代开始的损失函数值。

在这里插入图片描述

小结

在这个实验中:

  • 重新开发了多变量线性回归的例程。
  • 利用了 NumPy 的 np.dot向量化实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/689655.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

静态IP设置:小白必看攻略

在现代网络环境中&#xff0c;IP地址是连接互联网的基石。它就像网络世界中的门牌号&#xff0c;让数据能够在庞大的网络海洋中准确找到目标。其中&#xff0c;静态IP地址由于其固定不变的特性&#xff0c;在某些特殊应用场景下尤为重要。那么&#xff0c;如何设置静态IP地址呢…

Spring-Bean 作用域

作用域 作用域案例 public class BeanScopeDemo {AutowiredQualifier("singletonPerson")Person person;AutowiredQualifier("prototypePerson")Person person1;AutowiredQualifier("prototypePerson")Person person2;AutowiredSet<Person&g…

FFmpeg常用API与示例(四)——过滤器实战

1.filter 在多媒体处理中&#xff0c;filter 的意思是被编码到输出文件之前用来修改输入文件内容的一个软件工具。如&#xff1a;视频翻转&#xff0c;旋转&#xff0c;缩放等。 语法&#xff1a;[input_link_label1]… filter_nameparameters [output_link_label1]… 1、视…

住宅ip与数据中心ip代理的区别是什么

代理通常意味着“替代”。它是用户设备和目标服务器之间的中介&#xff0c;允许在不同的IP地址下上网。代理ip根据来源分类可分住宅ip与数据中心ip&#xff0c;二者之间区别是什么呢&#xff1f; 住宅ip是由互联网服务提供商(ISP)提供给家庭的IP地址。出于这个原因&#xff0c…

笨方法自学python(三)-数学计算

数字和数学计算 这章练习里有很多的数学运算符号。我们来看一遍它们都叫什么名字 plus 加号-minus 减号/ slash 斜杠*asterisk 星号% percent 百分号< less-than 小于号greater-than 大于号< less-than-equal 小于等于号 greater-than-equal 大于等于号 print ("I …

LeetCode/NowCoder-链表经典算法OJ练习1

目录 说在前面 题目一&#xff1a;移除链表元素 题目二&#xff1a;反转链表 题目三&#xff1a;合并两个有序链表 题目四&#xff1a;链表的中间节点 SUMUP结尾 说在前面 dear朋友们大家好&#xff01;&#x1f496;&#x1f496;&#x1f496;数据结构的学习离不开刷题…

企业网络需求及适合的解决方案

近年来&#xff0c;企业网络通信需求可谓五花八门&#xff0c;变幻莫测。它不仅为企业的生产、办公、研发、销售提供全面赋能&#xff0c;同时也让企业业务规模变大成为了可能。 在当前的技术格局下&#xff0c;中大型企业常见的技术方案有很多&#xff0c;而同时也有各自不可替…

【2024亚马逊云科技峰会】Amazon Bedrock + Llama3 生成式AI实践

在 4 月 18 日&#xff0c;Meta在官网上公布了旗下最新大模型Llama 3。目前&#xff0c;Llama 3已经开放了80亿&#xff08;8B&#xff09;和700亿&#xff08;70B&#xff09;两个小参数版本&#xff0c;上下文窗口为8k&#xff0c;据称&#xff0c;通过使用更高质量的训练数据…

零代码平台助力中国石化江苏油田实现高效评价体系

概述&#xff1a; 中国石化集团江苏石油勘探局有限公司面临着评价体系依赖人工处理数据、计算繁琐且容易出错的挑战。为解决这一问题&#xff0c;他们决定借助零代码平台明道云开发江苏油田高质量发展经济指标评价系统。该系统旨在实现原始数据批量导入与在线管理、权重及评分…

线路和绕组中的波过程(三)

本篇为本科课程《高电压工程基础》的笔记。 本篇为这一单元的第三篇笔记。上一篇传送门。 冲击电晕对线路上波过程的影响 实际中的导线存在电阻&#xff0c;而且还有对地电导&#xff0c;会消耗一部分能量。但是因为雷击所涉及的传输距离很短&#xff0c;所以几乎可以忽略这…

39-5 入侵检测系统(IDS)- 安装配置IDS(注意我没安装成功,阅读需谨慎)

官网:Snort Rules and IDS Software Download 参考: (这位大佬分享了安装包下载链接):https://www.cnblogs.com/taoyuanming/p/12722263.html (安装过程参考这位大佬):Snort 安装与配置(CentOS 7)_centos 7 snort-CSDN博客一、安装 IDS(我这里在 CentOS 7 虚拟机中安…

iOS Failed to create provisioning profile.

错误描述 错误情况参考这张图 解决方案 修改Bundle Identifier就可以解决这个错误&#xff0c;找不到位置可以看图 &#xff08;具体解决的原理与证书有关&#xff0c;个人不是非常熟悉&#xff0c;还望大神告知&#xff09;