1.1 什么是机器学习

​ Machine learning algorithms:

​ -Supervised learning

​ -Unsupervised learning

​ (Reinforcement learning)


1.2 Supervised learning 监督学习

x(input) ------> y(output/label) (输入输出间的映射关系)

​ 给算法数据集(input),数据集中有正确答案,通过数据集训练模型(model),最后让算法通过自动学习进而可以给出更多的正确答案(output)。

image-20231221233742160

Regression(回归)
Classification(分类)
Regression(回归) Algorithm:

​ 从无数的可能中预测一种可能的结果输出。

image-20231221231321565


Classification(分类) Algorithm:

​ 与Regression(回归)不同的是,分类方法只试图预测一小部分可能的输出或类别。

eg:

​ 癌症预测,通过肿瘤的大小判断,输出要么为良性,要么为恶性。

image-20231221233033954

​ 当然也可能有多种可能性,例如也可以通过输入的图片,判断是狗或猫…

image-20231221233327434

​ 有时候可能会不止一种特征,例如判断癌症阶段时,需要通过患者的年龄和肿瘤大小两个方面来进行判断,此时需要算法判断出一种边界值来区分癌症具体数据的某一个阶段(粉线):

image-20231221233550339


1.3 Unsupervised learning 无监督学习

​ 给定数据仅带有输入x而没有输出标签y,通过算法在数据中找到一定的结构或模式,由算法自己决定如何分组。

image-20231221235504127

Clustering(聚类)
Anomaly detection(异常检测)
Dimensionality reduction(降维)

Clustering(聚类) Algorithm:

获取没有标签的数据,并尝试自动将它们分组到集群中。

对用户进行分类,确定其目标用户。

image-20231221234952342


Jupyter Notebooks

pip install jupyterlab
pip install notebook
jupyter lab
jupyter notebook

2.1 Linear Regression(线性回归)

例子:预测房子价格和面积大小的关系,其中每一个数据点对应一个房子的面积与价格的关系,需要回答某一间房子能卖多少钱。模型需要通过数据集画出一个数据拟合后的直线,进而在特定的面积下得到大致对应的预测价格。

image-20231223014009825

​ 可视化数据除了图表外,还有数据表:

image-20231223014157806


Some Terminology

​ Train set(训练集): Data used to train the model
​ x : “input” variable
​ “input” feature
​ y : “output” variable
​ “target” variable
​ m : number of training examples
​ (x, y) : single training example
​ (x(i) ,y(i)) : i th training example

image-20231223015623053


线性回归方程

线性回归方程就是具有只一个变量的线性回归。只具有一个输入变量的线性模型还被称为单变量线性回归(univariate linear regression) 。

为了训练模型,我们需要输入一系列的训练集给学习算法,然后通过监督学习算法,将生成一个方程,假设方程(f)。其工作是通过输入的x,进而得出一个假设的y*(y-hat)*的值。

image-20231223020521927

重点是,我们应该如何得到函数f。例如如下函数
f ( x ) = w x + b f(x) = wx + b f(x)=wx+b
我们需要得出的重点是,w和b的值是多少

image-20231223021245270


实验代码

image-20231223134009535

一些导入的库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # matplotlib.pyplot是一些命令行风格函数的集合,使matplotlib以类似于MATLAB的方式工作。
import seaborn as sns
sns.set(context="notebook", style="whitegrid", palette="deep")	# 初始化一系列参数
A=np.eye(5)   #输出单位对角矩阵
print(A)

image-20231223134223720

df = pd.read_csv('ex1data1.txt',names=['人口','利润'])    # header = None表示没有表头  
#pd.read_csv的作用是将csv文件读入并转化为数据框形式,有非常多的参数,用到时可查阅文档。

在读取文件后,此时df中应该存放了数据,并且按照将两列数据的内容按列名 人口、利润 进行了区分

读前5行数据:

df.head() #读前5行
#括号内可填写要读取的前n行,如果不填,默认为n=5

image-20231223134204098

df.info() #查看索引、数据类型和内存信息

image-20231223134315809


绘制散点图观察原始数据
sns.lmplot('人口','利润',data=df,size=6,fit_reg = False)
#fit_reg:拟合回归参数,如果fit_reg=True则散点图中则出现拟合直线
plt.show()

image-20231223134804048


2.2 Cost Function(代价函数)

代价函数基本定义

代码函数将告诉我们模型的运行情况。

在线性方程中,w和b称为模型的参数,参数是我们在训练期间通过调整来改进模型的变量。

image-20231223151559057

根据所选择的参数的不同,可以得到不同的x的函数f。

image-20231223151903616

在线性回归中,所要做的是选择参数w和b的值,以便从函数f所获得的直线以某种方式更好的拟合数据。重点问题是,如何找到w和b的值,以便于许多可能的所有训练示例xi和yi的预测y-hati更接近于真实目标yi

image-20231223152023152

如何衡量一条直线与训练数据的拟合程度?

​ 首先,需要一个代价函数,代价函数会采用预测y-hat并通过取y-hat减去y将其与目标y进行对比。y和h-hat之间的差距成为error(误差),计算全部误差的平方的和,最后将其除以m,而且,一般机器学习中的成本函数是除以2m,额外的2只是为了让我们后面的计算看起来更整洁

Cost function: Squared error cost function(平方误差成本函数)

tips:
	m = number of training examples

image-20231223174348000

等价于

image-20231223174602306

image-20231223174746970


Cost Function Intuition(代价函数直观理解)

​ 目前为止:

image-20231223232250779

根据已知的f(x)绘制简化后的 J(x) 的图像:

​ 1. 当w=0时,从代价函数的表达式可以看出,J(w) = 0,图像如下

image-20231223232959568

2. 当w=0.5时,同样通过带入代价函数来进行计算得到 J(0.5)约等于0.58,如图

image-20231223233316288

  1. 当w=0时,同样,如图

在这里插入图片描述

同理,可以取很多w可能的值,进行一系列的计算。对于w的每个值,最终可以得到一条不同的线以及 w 对应的代价函数 J ,进而可以得到代价函数的可视化图像如下所示,从其中可以看到,当w=1时,代价函数最小:

image-20231223234218286

所以,应该如何选择产生函数f的w值,进而更好的拟合数据呢?

答:选择一个使 w 的 J 尽可能小的 w 值

image-20231223234154097

线性回归的目标是:找到参数 w 或 w 和 b,使得承办函数 J 的值最小。


可视化的代价函数

当模型包含 w 和 b 两个参数时,代价函数的可视化图形更像是一个类似碗状的三维图像。

image-20231224005233379

等价函数的另一种图像,等高线图,该图可以看出,三个不同的点所对应的代价函数的值是相同的(等高)。并且,等高线图的中心点,就是等价函数最小的点(mininum)。

image-20231224010056476

可视化例子

通过不同的 w 和 b 取值的例子,我们可以看出,当最后的代价函数值越靠近中心点的变量取值,他的拟合效果越好:

image-20231224010449888

image-20231224010554502

image-20231224010621538

image-20231224010812069

实验代码

代价函数:

image-20231226005459223

基于代价函数的算式,当模型为:

image-20231226005518567

此时的代码实现:

def compute_cost(x, y, w, b): 
    """
    Computes the cost function for linear regression.
    
    Args:
      x (ndarray (m,)): Data, m examples 
      y (ndarray (m,)): target values
      w,b (scalar)    : model parameters  
    
    Returns
        total_cost (float): The cost of using w,b as the parameters for linear regression
               to fit the data points in x and y
    """
    # number of training examples
    m = x.shape[0] #表示一维数组的长度
    
    cost_sum = 0 
    for i in range(m): 
        f_wb = w * x[i] + b   
        cost = (f_wb - y[i]) ** 2  
        cost_sum = cost_sum + cost  
    total_cost = (1 / (2 * m)) * cost_sum  

    return total_cost

3.1 Gradient Descent(梯度下降)

​ 用于求函数最小值的算法,求代价函数 J(w,b) 的最小值。

​ 使用梯度下降算法,就是设置 w,b 为一个初始值,每次都稍微改变参数 w 和 b 的值以尝试降低 J(w,b) ,直到希望 代价函数 J(w,b) 稳定在或接近最小值。

image-20231224225857271

​ 想象站在一个山上,对于自己的360度的方向,需要选择一个方向迈出一步,确保这一步比其他各个方向下降的都要快,然后到达下一个点后以此类推,最终下降到最低点。并且,如果从不同的(w,b)作为起点,最后降低到的最低点不同,这些谷底被称为local mininum(局部极小值)。

image-20231224230835979

3.2 Implementing Gradient Descent(实现梯度下降)

​ 如前一节中所说的,需要对变量的值一直进行调整,以得到最小的代价函数。因此需要一系列的公式来一步步计算出最合适的w,梯度下降算法公式为:

image-20231224233452150

​ 从公式的理解来看,α表示的是w或b每下降一步的步幅,J(w,b)对于w或d的偏导数则表示下降的方向,就是一步一步下降直到代价函数收敛(到达局部极小值)。但是,我们最希望的是能够同时更新 w 和 b 的值,在同时更新时找到局部极小值,需要以下方式:

image-20231224234101103


3.3 Gradient Descent Intuition

​ 对于梯度下降的函数的直观理解,即是通过函数的导数一步步下降,可以看出代价函数就是沿着图像某点的斜率的方向一步步下降。(其实就是一些微积分的导数部分的内容…)

image-20231226000135359

3.4 Learning Rate(学习率)

​ α 的选择在梯度下降中也扮演着重要的角色。

  1. 当 α 太小时。每次下降都之迈出很小很小的一步,结果就是最终虽然降低了代价函数,但是计算了很多很多步,速度很慢。

image-20231226000408301

  1. 当 α 过大时。可能会导致本来已经很接近最小值的代价函数,反而增大没办法更加靠近最小值。另一种说法是,可能会导致大交叉无法收敛,甚至会发散。

image-20231226000708526

试想一种场景,当此时的w已经到了最小值时,由于在极小值点的斜率为0,也就是说导数为0,因此w的值其实并不会改变。

在这里插入图片描述

**当学习率(α)固定时,可以达到最小值。**以下是例证:

​ 因为每次下降时,某一点的斜率都会越来越小,在斜率越来越小时,每次减少的值也会越来越小,最终得到最小值。

image-20231226001419342

3.5 Gradient Descent for Linear Regression(线性回归中的梯度下降)

联立线性回归算法的模型函数、代价函数以及梯度下降算法,可以得到:

image-20231226004143315

3.6 Running Gradient Descent

image-20231226004742903

对于这一类的梯度下降,每下降一步都使用所有的训练数据的叫做"Batch" gradient descent。

image-20231226005035034

实验代码

同样,数据集仅两组数据

image-20231226015537965

对其进行导入

# Load our data set
x_train = np.array([1.0, 2.0])   #features
y_train = np.array([300.0, 500.0])   #target value

代价函数方程:

#Function to calculate the cost
def compute_cost(x, y, w, b):
   
    m = x.shape[0] 
    cost = 0
    
    for i in range(m):
        f_wb = w * x[i] + b
        cost = cost + (f_wb - y[i])**2
    total_cost = 1 / (2 * m) * cost

    return total_cost

接下来就是梯度下降部分,此处选择线性方程来进行预测:

image-20231226015741148

对于该线性方程,所选择的代价函数:

image-20231226015809009

在梯度下降算法中,w和b的更新方式:

image-20231226015854971

其中:

image-20231226015916106

代码部分:

对于梯度的计算,也就是求偏导后的代价函数如下,此处w和b的初始值都取为0:

def compute_gradient(x, y, w, b): 
    """
    Computes the gradient for linear regression 
    Args:
      x (ndarray (m,)): Data, m examples 
      y (ndarray (m,)): target values
      w,b (scalar)    : model parameters  
    Returns
      dj_dw (scalar): The gradient of the cost w.r.t. the parameters w
      dj_db (scalar): The gradient of the cost w.r.t. the parameter b     
     """
    
    # Number of training examples
    m = x.shape[0]    
    dj_dw = 0
    dj_db = 0
    
    for i in range(m):  
        f_wb = w * x[i] + b 
        dj_dw_i = (f_wb - y[i]) * x[i] 
        dj_db_i = f_wb - y[i] 
        dj_db += dj_db_i
        dj_dw += dj_dw_i 
    dj_dw = dj_dw / m 
    dj_db = dj_db / m 
        
    return dj_dw, dj_db

对于梯度下降函数:

def gradient_descent(x, y, w_in, b_in, alpha, num_iters, cost_function, gradient_function): 
    """
    Performs gradient descent to fit w,b. Updates w,b by taking 
    num_iters gradient steps with learning rate alpha
    
    Args:
      x (ndarray (m,))  : Data, m examples 
      y (ndarray (m,))  : target values
      w_in,b_in (scalar): initial values of model parameters  
      alpha (float):     Learning rate
      num_iters (int):   number of iterations to run gradient descent
      cost_function:     function to call to produce cost
      gradient_function: function to call to produce gradient
      
    Returns:
      w (scalar): Updated value of parameter after running gradient descent
      b (scalar): Updated value of parameter after running gradient descent
      J_history (List): History of cost values
      p_history (list): History of parameters [w,b] 
      """
    
    w = copy.deepcopy(w_in) # 通过深复制方式给w赋值,避免修改初始值w_in
    # 用于存储每次迭代的代价函数和 J 和 参数 w,用于后续绘图
    J_history = []
    p_history = []
    b = b_in
    w = w_in
    
    for i in range(num_iters):
        # 用 gradient_function 计算梯度并更新参数
        dj_dw, dj_db = gradient_function(x, y, w , b)     

        # 用学习率更新参数
        b = b - alpha * dj_db                            
        w = w - alpha * dj_dw                            

        # 保存每次迭代的cost
        if i<100000:      # prevent resource exhaustion 
            J_history.append( cost_function(x, y, w , b))
            p_history.append([w,b])
        # 每隔10次打印一次cost,如果<10次,则打印多次cost
        if i% math.ceil(num_iters/10) == 0:
            print(f"Iteration {i:4}: Cost {J_history[-1]:0.2e} ",
                  f"dj_dw: {dj_dw: 0.3e}, dj_db: {dj_db: 0.3e}  ",
                  f"w: {w: 0.3e}, b:{b: 0.5e}")
 
    return w, b, J_history, p_history #return w and J,w history for graphing

运行:

# initialize parameters
w_init = 0
b_init = 0
# some gradient descent settings
iterations = 10000
tmp_alpha = 1.0e-2
# run gradient descent
w_final, b_final, J_hist, p_hist = gradient_descent(x_train ,y_train, w_init, b_init, tmp_alpha, iterations, compute_cost, compute_gradient)
print(f"(w,b) found by gradient descent: ({w_final:8.4f},{b_final:8.4f})")

得到最终的w和b,并且可以观察到过程中w、b以及J在每迭代1000次后的变化:

image-20231226022248822

在课程内有提到,由于在代价函数不断减小的过程中,其图像斜率不断减小,因此到最后每次减小的幅度也会下降。

image-20231226162527679

这一过程可以通过绘图直观感受:

# plot cost versus iteration  
fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12,4))
ax1.plot(J_hist[:100])
ax2.plot(1000 + np.arange(len(J_hist[1000:])), J_hist[1000:])
ax1.set_title("Cost vs. iteration(start)");  ax2.set_title("Cost vs. iteration (end)")
ax1.set_ylabel('Cost')            ;  ax2.set_ylabel('Cost') 
ax1.set_xlabel('iteration step')  ;  ax2.set_xlabel('iteration step') 
plt.show()

image-20231226162610979

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐