[Machine Learning][Part 5]监督学习——逻辑回归

目录

逻辑回归模型理论

决策边界

Cost Function : 代价函数

梯度下降

 计算逻辑回归梯度值:

计算梯度下降值:


逻辑回归模型理论

        之前文章中提到监督学习的应用可分为两类:线性回归和逻辑回归。和线性回归不同,逻辑回归输出只有0和1。对于一个逻辑回归任务,可以先使用线性回归来预测y。然而我们希望逻辑回归预测模型输出的是0和1,为了达到这个目的,我们使用sigmoid()来把线性回归预测的输出y映射到0和1之间。

sigmoid公式为:

 公式中的z表示的是线性回归模型中输出的结果y。m个training data的情况下,y是一个含m个value的向量。

sigmoid公式代码实现很简单:

def sigmoid(z):
    """
    Compute the sigmoid of z

    Args:
        z (ndarray): A scalar, numpy array of any size.

    Returns:
        g (ndarray): sigmoid(z), with the same shape as z

    """
    g = 1/(1+np.exp(-z))
    return g

用图形表示sigmod的输出样子是:可以看到输出区间始终在0到1之间,输入z越大,越趋近于1,反之趋近于0

图一

逻辑回归的公式与线性回归类似:

一句话总结逻辑回归模型:线性回归模型+sigmoid = 逻辑回归模型

决策边界

逻辑回归输出的是0和1,由于sigmoid函数是在无穷大的时候趋近于1,无穷小的时候趋近于0,。那么0和1的分界点在哪里,如何判断应当输出0还是应当输出1,这就需要设计一个阈值,来区分开这两种输出。

现在假设阈值为0.5

  1. g(z) >=0.5, y=1
  2. g(z)<0.5,    y=0

那边边界点就在g(z)=0.5。由图一可以看出z=0时,g(z) = 0.5。因此边界点z = 0。而z 是线性回归的输出w*x+b。所以得出w*x+b = 0为分界线,即决策边界。

下面用一个例子来实现这条决策边界:

假设有一组training data,每个训练数据包含2个特征值

X = np.array([[0.5, 1.5], [1,1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]])
y = np.array([0, 0, 0, 1, 1, 1]).reshape(-1,1)


fig,ax = plt.subplots(1,1,figsize=(4,4))
plot_data(X, y, ax)

ax.axis([0, 4, 0, 3.5])
ax.set_ylabel('$x_1$')
ax.set_xlabel('$x_0$')
plt.show()

分布入下图:

 逻辑回归模型为:

 假设训练完成之后的w_0=1,w_1=1,b=-3。那么这个模型最终公式是:

 这里同样假设:

  1. g(z) >=0.5, y=1
  2. g(z)<0.5,    y=0

得出来决策边界函数为:

 决策边界图如图二,左下角蓝色部分为y=0,右上角为y=1:

# Choose values between 0 and 6
x0 = np.arange(0,6)

x1 = 3 - x0
fig,ax = plt.subplots(1,1,figsize=(5,4))
# Plot the decision boundary
ax.plot(x0,x1, c="b")
ax.axis([0, 4, 0, 3.5])

# Fill the region below the line
ax.fill_between(x0,x1, alpha=0.2)

# Plot the original data
plot_data(X,y,ax)
ax.set_ylabel(r'$x_1$')
ax.set_xlabel(r'$x_0$')
plt.show()
图二

Cost Function : 代价函数

之前已经实现过线性回归模型的代价函数,那么线性回归的代价模型能不能用到逻辑回归中呢?答案是否定的,因为逻辑回归模型中存在非线性因素,如果直接运用线性模型的代价函数就会出现很多局部最小值,影响最佳w,b组合的寻找。图三中左边是线性回归模型的代价函数,可以看到是凸面的,存在一个最小值,而右图是在逻辑回归模型中应用线性回归的代价函数得到的代价函数结果,可以看到有很多局部最小值,但并非全局最小值。因此线性回归中的代价函数并不能应用到逻辑回归模型中。

图三
图三

因此逻辑回归模型的代价函数使用下面的公式实现:

代码实现为:

def compute_cost_logistic(X, y, w, b):
    """
    Computes cost

    Args:
      X (ndarray (m,n)): Data, m examples with n features
      y (ndarray (m,)) : target values
      w (ndarray (n,)) : model parameters  
      b (scalar)       : model parameter
      
    Returns:
      cost (scalar): cost
    """

    m = X.shape[0]
    cost = 0.0
    for i in range(m):
        z_i = np.dot(X[i],w) + b
        f_wb_i = sigmoid(z_i)
        cost +=  -y[i]*np.log(f_wb_i) - (1-y[i])*np.log(1-f_wb_i)
             
    cost = cost / m
    return cost

验证一下上面的cost function是否正确:

w_tmp = np.array([1,1])
b_tmp = -3
print(compute_cost_logistic(X_train, y_train, w_tmp, b_tmp))

输出为:0.36686678640551745

梯度下降

梯度下降公式:

 

对于逻辑回归模型,𝑓𝐰,𝑏(𝑥(𝑖))是预测模型函数,𝑧=𝐰⋅𝐱+𝑏,𝑓𝐰,𝑏(𝑥)=𝑔(𝑧),

 计算逻辑回归梯度值:

上面公式2和公式3是梯度值的计算公式,首先初始化dj_dwdj_db

计算dj_dw:对于每个训练数据,计算和真实值的误差g(x(i))-y_i,由于训练数据有j个特征值,所以一个训练数据中的j个特征值的误差都要乘以x_j并求和。

def compute_gradient_logistic(X, y, w, b): 
    """
    Computes the gradient for linear regression 
 
    Args:
      X (ndarray (m,n): Data, m examples with n features
      y (ndarray (m,)): target values
      w (ndarray (n,)): model parameters  
      b (scalar)      : model parameter
    Returns
      dj_dw (ndarray (n,)): 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. 
    """
    m,n = X.shape
    dj_dw = np.zeros((n,))                           #(n,)
    dj_db = 0.

    for i in range(m):
        f_wb_i = sigmoid(np.dot(X[i],w) + b)          #(n,)(n,)=scalar
        err_i  = f_wb_i  - y[i]                       #scalar
        for j in range(n):
            dj_dw[j] = dj_dw[j] + err_i * X[i,j]      #scalar
        dj_db = dj_db + err_i
    dj_dw = dj_dw/m                                   #(n,)
    dj_db = dj_db/m                                   #scalar
        
    return dj_db, dj_dw  

计算梯度下降值:

def gradient_descent(X, y, w_in, b_in, alpha, num_iters): 
    """
    Performs batch gradient descent
    
    Args:
      X (ndarray (m,n)   : Data, m examples with n features
      y (ndarray (m,))   : target values
      w_in (ndarray (n,)): Initial values of model parameters  
      b_in (scalar)      : Initial values of model parameter
      alpha (float)      : Learning rate
      num_iters (scalar) : number of iterations to run gradient descent
      
    Returns:
      w (ndarray (n,))   : Updated values of parameters
      b (scalar)         : Updated value of parameter 
    """
    # An array to store cost J and w's at each iteration primarily for graphing later
    J_history = []
    w = copy.deepcopy(w_in)  #avoid modifying global w within function
    b = b_in
    
    for i in range(num_iters):
        # Calculate the gradient and update the parameters
        dj_db, dj_dw = compute_gradient_logistic(X, y, w, b)   

        # Update Parameters using w, b, alpha and gradient
        w = w - alpha * dj_dw               
        b = b - alpha * dj_db               
      
        # Save cost J at each iteration
        if i<100000:      # prevent resource exhaustion 
            J_history.append( compute_cost_logistic(X, y, w, b) )

        # Print cost every at intervals 10 times or as many iterations if < 10
        if i% math.ceil(num_iters / 10) == 0:
            print(f"Iteration {i:4d}: Cost {J_history[-1]}   ")
        
    return w, b, J_history         #return final w,b and J history for graphing

梯度下降测试:

w_tmp  = np.zeros_like(X_train[0])
b_tmp  = 0.
alph = 0.1
iters = 10000

w_out, b_out, _ = gradient_descent(X_train, y_train, w_tmp, b_tmp, alph, iters) 
print(f"\nupdated parameters: w:{w_out}, b:{b_out}")

输出:可以看出结果是不断收敛的

Iteration    0: Cost 0.684610468560574   
Iteration 1000: Cost 0.1590977666870457   
Iteration 2000: Cost 0.08460064176930078   
Iteration 3000: Cost 0.05705327279402531   
Iteration 4000: Cost 0.04290759421682   
Iteration 5000: Cost 0.03433847729884557   
Iteration 6000: Cost 0.02860379802212006   
Iteration 7000: Cost 0.02450156960879306   
Iteration 8000: Cost 0.02142370332569295   
Iteration 9000: Cost 0.019030137124109114   

updated parameters: w:[5.28 5.08], b:-14.222409982019837

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值