机器学习入门~分类与Logical回归

什么是分类问题?

在这里插入图片描述
〇是否为垃圾邮件。
〇网上交易是否为诈骗交易。
〇肿瘤是恶行还是良性。
在这里插入图片描述

  • 对于这些问题模型,他们的结果都可以视作一个集合y,其中仅包含0(负类)和1(正类)👆。
    当然也有多分类问题,但二分类问题是基础。
  • 一个例子:用线性回归执行分类问题是否可行?
    在这里插入图片描述
    由上图👆,假设我们只有这八个训练样本,假设判定是否为良性的阈值设定为0.5,则阈值小于0.5对应在横轴上的点视为恶行,大于视为阳性,故,这条由线性回归算法得到的曲线看起来可以很好地对恶性良性肿瘤进行分类,但👇,当加入另外一个训练样本之后,明显会得到一条新的线性回归曲线,如果阈值仍设定为0.5,则会误判,故,使用线性回归算法进行分类绝对不是一个好的选择。
    在这里插入图片描述
    在这里插入图片描述
    👆同样的,使用线性回归算法得到的hθ(x)值可能大于1或小于0,不满足分类问题只有0和1两种取值的结果,因此,对于分类问题,通常使用Logistic Regression算法使结果定位在0和1之间。Logistic回归算法是一种分类算法

假设陈述

在这里插入图片描述

  • 👆Logistic回归算法模型:
    想要使hθ(x)的值介于0和1之间,将原来的假设函数hθ(x)由hθ(x) = θTx改为hθ(x) = g(θTx),其中,g(z) = 1/( 1+e-z )(g函数称为Sigmoid函数或Logistic函数)。因此,假设函数hθ(x)可以写作👇:
    在这里插入图片描述
    sigmoid函数曲线👇:
    在这里插入图片描述
  • 对于假设函数hθ(x)输出的解释:
    在这里插入图片描述
    hθ(x)的介于0和1之间,其结果的含义为预测结果为1的概率使多大。
    👆由上图的例子可知,如果特征量由x0和x1,x0 = 1而x1为肿瘤大小,得到hθ(x)的结果为0.7,其含义为肿瘤为恶性的概率为0.7。
    hθ(x)的结果可以视作一个概率,可以表示为P(y = 1 | x;θ),含义为在给定特征量x和参数θ的情况下,y=1的概率为多大,实际上,y = 0的概率于y = 1的概率相加的结果即为1,因此得到其中一个,另一个的结果也可以得知。

决策界限

在这里插入图片描述

  • 前情回顾:hθ(x) = g(θTx),g(x) = 1/( 1 + e-x ),其中,hθ(x)的取值为P(y = 1 | x;θ)。
    我们将hθ(x) >= 0.5 视作 y = 1,而hθ(x) < 0.5 视作 y = 0。
  • 什么时候hθ(x) >= 0.5而什么时候hθ(x) < 0.5?
    在这里插入图片描述
    👆由g(x)的曲线可知,当x的取值大于0时,g(x)的值大于0.5,而对于hθ(x) = g(θTx),当θTx大于等于0时,hθ(x)大于等于0.5。
  • 一个使用Logistic回归的例子:前提是假设我们已经有了拟合好的参数向量θ。
    在这里插入图片描述
    此处视 θ = [ -3,1,1 ]。
    通过之前对hθ(x)预测结果的描述,倘若满足表达式 -3 + x1 + x2 >= 0,即可预测 y = 1,如👇下图所示。
    在这里插入图片描述
    👆同时在图像中得到一条曲线。
    在这里插入图片描述
    洋红色的直线称作决策边界 ( Decision Boundary )。
  • 一个更复杂的例子:非线性决策边界。
    在这里插入图片描述
    👆在多项式回归和线性回归中,我们可以添加额外的高阶多项式项,以更好地拟合训练样本,对于Logistic回归同样可用,因此,加入x12和x22
    此处令 θ = [ -1 0 0 1 1 ]。
    在这里插入图片描述
    👆决策边界变成了一个圆形曲线。
    再次强调,决策边界不是训练集的属性,而是假设函数本身及其参数的属性。
  • 假设我们有更高阶的多项式,能否得到更复杂的决策边界?
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    更高阶的多项式会得到更复杂的决策边界。

代价函数:如何得到拟合Logistic回归算法的参数

在这里插入图片描述
👆这是一个监督学习中Logistic回归模型的拟合问题。我们有一个大小为m的训练集,每一个训练样本由一个 n+1 维的特征向量表示,其中x0 = 1,y的取值非0即1,假设函数与前文相同,为hθ(x) = g(θTx),g(x) = 1/( 1 + e-x ),怎样选取参数θ

  • 前情回顾:线性回归中的代价函数J(θ):平方差代价函数👇
    在这里插入图片描述
    可另表示为:
    在这里插入图片描述
    如果对于Logistic回归也使用同样的代价函数,它会变成参数θ的非凸函数👇。
    在这里插入图片描述
    缺点:
    ① Logistic回归的Sigmoid函数是 g(x) = 1/( 1+e-x ),它是非线性的。
    ② 因此,将Logistic回归的假设函数h代入Cost函数,得到的代价函数J会有许多个局部最优点如上图所示。
    ③ 因此,当使用梯度下降时,不能保证其会收敛到全局最小值。
  • 对于Logistic回归使用的Cost函数:
    在这里插入图片描述
    ①回顾Cost函数:在线性回归中,Cost函数视为每一个训练样本与预测值的差平方,其加和除以样本容量即为方差。
    ②hθ(x) = g(θTx),g(x) = 1/(1+e-x)。
    ③Cost函数图像(y = 1):
    在这里插入图片描述
    在这里插入图片描述
    👆当 y = 1且hθ(x) = 1时,即假设函数预测值为1,且y(y为训练样本的结果值)恰好也为1(即真实值与预测值相等),则代价值Cost = 0,对应于图像上hθ(x) = 1的点。这正是我们希望的情况,因为我们正确预测了输出值y,此时代价为0。
    但是,同样,当hθ(x) 趋于0时,代价趋于∞(代价值激增),这就相当于,假设hθ(x) = 0,即预测值为0,而实际值为1 (预测出现错误),会得到一个趋于无穷的代价值,因此,我们就用这个无穷大的代价惩罚学习算法(因为预测出现了错误)。
    ④Cost函数图像(y = 0):
    在这里插入图片描述
    当h(x)趋于1时激增。

简化代价函数与梯度下降:实现一个完整的Logistic回归算法

在这里插入图片描述

  • Logistic回归的代价函数👆:
    注意:y(训练集的真实结果值)的值非零即一。
  • 代价函数的简化方式:
    由于y的取值非零即一,Cost函数可以写作:
    Cost(hθ(x),y) = - ylog( hθ(x) ) - (1 - y)log( 1 - hθ(x) )
    在这里插入图片描述
    这种表述方式与将Cost函数分为y = 0和y = 1两种形态的表述方式时完全等价的。
    因此,得到代价函数的简化表达方式👇:
    在这里插入图片描述
    此时,假设函数的输出为 y = 1 的概率。y = 0的概率做 与一减法 即可。
  • 得到使代价函数J(θ)取值最小的方法:梯度下降
    在这里插入图片描述
    想要的到最小的代价函数J,需要反复对👇
    在这里插入图片描述
    这个式子进行迭代运算,注意同时更新所有的θj
    其中,偏导数项为:
    在这里插入图片描述
    因此,完整的梯度下降算法为👇:
    在这里插入图片描述
    👆我们可以发现,Logistic回归算法得到最小代价的梯度下降函数与线性回归的梯度下降函数看起来完全相同。但是,它们尽管看起来完全相同,实际上假设函数hθ(x)是不同的,对于线性回归,hθ(x) = θTx,而对于Logistic回归,hθ(x) = g(θTx),g(x) = 1/(1+e-x)。
    注:特征缩放同样可以用于Logistic回归,以提高梯度下降的效率。

Python实现

参考自csdn博主bitcarmanlee,原博文链接。

import numpy as np #引入numpy以进行矩阵运算
def sigmoid(x): #sigmoid函数实现
    return 1 / (1 + np.exp(-x))
def parse_data(): #从外部读入数据,并存储在矩阵中
    data = np.loadtxt('data.csv') #外部文件
    dataMat = data[:, 0:-1]
    classLabels = data[:, -1]
    dataMat = np.insert(dataMat, 0, 1, axis=1)
    return dataMat, classLabels #dataMat为保存特征量x的矩阵
    #classLabels为保存真实输出值y的矩阵
def loss_funtion(dataMat, classLabels, weights): #实现Cost函数的函数,以进行
#梯度下降,此处的参数weights即为向量θ
    m, n = np.shape(dataMat)#m,n记录了矩阵的行和列,是一个二维行向量
    loss = 0.0#代价值
    for i in range(m):#循环,进行了m次循环,m为训练集的大小,也为训练样本矩阵的行数。
        sum_theta_x = 0.0
        for j in range(n):#对列进行循环
        #sum_theta_x存储的是θ^T * X的结果
            sum_theta_x += dataMat[i, j] * weights.T[0, j]
        propability = sigmoid(sum_theta_x)
        loss += -classLabels[i, 0] * np.log(propability) - (1 - classLabels[i, 0]) * np.log(1 - propability) #每一次都计算并合并了Cost函数的值进入J(θ)
    return loss #返回的是J(θ)的值
def grad_descent(dataMatIn, classLabels):#梯度下降
    dataMatrix = np.mat(dataMatIn)  #(m,n)即m行n列的矩阵:训练集
    labelMat = np.mat(classLabels).T#存储y矩阵的转置
    m, n = np.shape(dataMatrix)
    weights = np.ones((n, 1))#设定初始的θ,准备进行梯度下降
    alpha = 0.01 #设定学习率为1
    maxstep = 10000 #设定最大的迭代次数为10000
    eps = 0.0001 #查看是否接近全局最优点,即经过一次迭代,变化如果小于eps,
    #则达到全局最优。
    count = 0 #记录迭代次数
    loss_array = [] #记录每一次迭代的代价,方便绘制代价和迭代次数的关系图,若
    #随着迭代次数的增加,代价下降且趋平趋密,则代表梯度下降函数能正常运行。
    for i in range(maxstep):#迭代
        loss = loss_funtion(dataMatrix, labelMat, weights) #得到此时的代价
        h_theta_x = sigmoid(dataMatrix * weights)#得到假设函数的预测值
        e = h_theta_x - labelMat #e为假设函数预测值与真实值y的差。
        new_weights = weights - alpha * dataMatrix.T * e
        #👆向量化:一次性同时更新所有的θ
        new_loss = loss_funtion(dataMatrix, labelMat, new_weights)
        #👆通过新的θ得到新的代价值
        loss_array.append(new_loss)#将新的代价追加于记录代价的序列中
        if abs(new_loss - loss) < eps:
            break
        else:
            weights = new_weights
            count += 1 #记录迭代次数
    return weights, loss_array
data, labels = parse_data()
r, loss_array = grad_descent(data, labels)
r = np.mat(r).transpose()
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页