机器学习周报(四)--逻辑回归和机器学习任务

本文介绍了逻辑回归的基本原理,包括线性加权求和、sigmoid函数和交叉熵损失函数。通过对比逻辑回归与生成性学习,探讨了它们的差异。文章还讨论了如何解决过拟合问题,以及在模型选择中如何运用N折交叉验证。此外,提供了逻辑回归的Python代码实现,并展示了训练过程中的损失函数变化。
摘要由CSDN通过智能技术生成

摘要

本周学习了逻辑回归的基本原理以及对应梯度下降实现的代码,对于逻辑回归,其基本原理是将输入特征通过线性加权求和,并经过sigmoid函数转化为0-1之间的值,从而得到样本为正的概率,最后通过交叉熵损失函数优化模型预测结果。通过对比逻辑回归和生成性学习,知道了两者的不同,不能直接说逻辑回归就是最好的,生成性学习通常会假设一个概率分布,这相当于提前进行了判断,无论哪种分类方法好需要根据实际来选择。还学习了机器学习任务攻略的三个步骤:定义函数、计算 loss、优化,以及如何解决过拟合、局部最小值和鞍点的概念与判断方法,以及如何挑选适合的模型。在机器学习中,需要对预测目标建立函数,并通过计算 loss 来评估模型的好坏,并使用优化方法找出参数使 loss 最小的过程。

Abstract

This week, I learned the basic principle of logistic regression and the code of corresponding gradient descent implementation. For logistic regression, the basic principle is to convert the input features into a value between 0 and 1 through linear weighted summation and sigmoid function, so as to obtain the probability that the sample is positive, and finally optimize the model prediction results through cross-entropy loss function. By comparing logistic regression and generative learning, we know the difference between the two. We cannot directly say that logistic regression is the best. Generative learning usually assumes a probability distribution, which is equivalent to making a judgment in advance. We also learned the three steps of machine learning task guide: defining function, calculating loss, optimization, and how to solve the concept and judgment method of overfitting, local minimum and saddle point, as well as how to choose the suitable model. In machine learning, it is necessary to build a function for the prediction target, evaluate the quality of the model by calculating loss, and use optimization methods to find the process of parameters that minimize loss.

一.逻辑回归

1.原理

1.1 Function set

逻辑回归是一种分类算法,通过将输入的特征以及相应的权重进行线性加权求和,然后将结果通过sigmoid函数压缩到0到1之间,得到样本为正的概率。如图即为图像化的Logistic Regression。

image-20230702213131834

1.2 Goodness of a Function

假设由N个training data,给任意一组w、b参数,就可以计算N个Training Data的概率。我们需要计算最有可能产生Training Data的w和b,通过极大似然估计法,确定 w ∗ w^* w b ∗ b^* b.image-20230702213839892

image-20230702214431496

最后的公式其实是交叉熵损失函数,他和均方差的区别将在下文讲述

1.3 Find the best function

我们对-ln(w,b)求 w i w_i wi的偏导

image-20230702214618895

整理可得

image-20230702214818826

有了偏导后,梯度下降法将代码实现会非常简单

逻辑回归和线性回归区别

输出的区别. linear regression的输出是连续的,在有限空间可取任意值; logistic regression的输出期望是离散的,只有有限个数值.
预期目标(label)的区别. linear regression的预期是连续变量,如auto-encoder模型预测一张图像; logistir regression的预期是离散的类别.
最小化误差的方法区别. 采用均方误差的linear regression对于大的误差施加二次倍数的惩罚, 而logistic regression把较大的误差惩罚到一个渐进的常数.
先验的区别.liner regression期望拟合训练数据,通过feature的线性加权来预测结果; logistic regression是在训练一个最大似然分类器.
image-20230702214949314

如果在Logistic Regression用Square error平方和的方法定义一个Loss Function会怎么样?

将函数的输出值减去target的平均值的值求平方,用 Gradient Descent来算最小值。会出现取不同的值求微分的结果都是0,不管离目标远近,求微分都等于0。image-20230702215430066

图中中心平坦位置为目标位置,对于Cross entropy来说,距离目标值越远,微分值越大,更新速度越快。对于Square Error来说,距离目标值越远,微分值很小,更新速度非常慢。平方误差是一种在回归问题中使用的损失函数,它对异常值比较敏感,并且对于分类问题来说,它的反向传播可能会导致梯度消失或梯度爆炸。因此,如果在逻辑回归中使用平方误差作为损失函数,可能会导致性能下降。如:距离微分值很远的地方,微分值依然很小,更新很慢。

image-20230702215407206

1.4 Discriminative V.S. Generative

Logistic Regression的方法叫做Discriminative,用Gaussian来求概率的方法叫做Generative。它们的函数是一样的。用 Logistic Regression可以直接找出w、b。用Generative Model算出 μ \mu μ , Σ \Sigma Σ,代入下式然后算出w、b。 对比这两个方法,找出来的w、b是不同的。

image-20230702215717569

我们通常认为Discriminative Model会更加准确,事实上Discriminative Model求出来的结果并不一定会比Generative Model更准确。

例如如下案例:

假设有一组Training data,有两种class。每个data有两个feature,一共有13个data,如图所示

image-20230702220310292

用贝叶斯公式计算Testing data 来自class 1的概率:小于0.5,所以得出data 来自class 2。显然这是一个错误的结果,data 应该来自class 1。

image-20230702220418841

朴素贝叶斯认为两个红颜色的特征这个样本属于class C2,和人类直觉(我们判断第一个样本是属于class1)相反。因为朴素贝叶斯认为这两个特征时独立(independent)的。generative提前做了脑补这件事(即对于这个例子中样本属于Class C2的概率大)。脑补的到底好不,在训练样本数量少的情况下,脑补是十分有用的。

1.5 多分类

假设现在有三个class,每一个class都有自己的w、b,得到z1、z2、z3。使用的交叉熵损失函数,并且使用极大似然估计来推导多分类的损失函数。image-20230702220546448

计算Cross Entropy(交叉熵),属于class1,class2,class3的target如图所示。

image-20230702220716214

1.6 Limitation of Logistic Regression

一组data如图,用Logistic Regression来进行分类,class 1的概率大于0.5,class 2的概率小于0.5。

image-20230702220906317

逻辑回归本质上是一个线性分类器,使用一条直线分不开这四个点

image-20230702220932123

如果我们执意使用logistic regression,特征变换可以解决异或问题,但是如何找这个transformation又是一个问题。使用sigmiod函数进行特征变换。

image-20230702221002935

每一个Logistic Regression都可以与它前面的Logistic Regression和后面的Logistic Regression相连接,也就是说每个Logistic Regression既可以做input,也可以是output。我们把每一个Logistic Regression叫做Neuron(神经元),而这些Logistic Regression所连接形成的结构,叫做Neural Network(神经网络)。

image-20230702221107448

2.代码实现

第一步,导入库和数据

#导入库
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report 
from sklearn import preprocessing
scale = False
# 载入数据
data = np.genfromtxt("LR-testSet.csv", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1]

其中classification_report库可以用来评估模型,scale选择数据是否需要标准化

我们先画出初试数据的散点图

def plot():
    x0 = []
    x1 = []
    y0 = []
    y1 = []
    # 切分不同类别的数据
    for i in range(len(x_data)):
        if y_data[i]==0:
            x0.append(x_data[i,0])
            y0.append(x_data[i,1])
        else:
            x1.append(x_data[i,0])
            y1.append(x_data[i,1])

    # 画图
    scatter0 = plt.scatter(x0, y0, c='b', marker='o')
    scatter1 = plt.scatter(x1, y1, c='r', marker='x')
    #画图例
    plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best') 
    
plot()
plt.show()

image-20230702221603346

接下来开始处理数据

# 数据处理,添加偏置项
x_data = data[:,:-1]
y_data = data[:,-1,np.newaxis]
print(np.mat(x_data).shape)
print(np.mat(y_data).shape)
# 给样本添加偏置项
X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(X_data.shape)

然后开始写相关算法函数

def sigmoid(x):
    return 1.0/(1+np.exp(-x))

def cost(xMat, yMat, ws):
    left = np.multiply(yMat, np.log(sigmoid(xMat*ws)))
    right = np.multiply(1 - yMat, np.log(1 - sigmoid(xMat*ws)))
    return np.sum(left + right) / -(len(xMat))

def gradAscent(xArr, yArr):
    
    if scale == True:
        xArr = preprocessing.scale(xArr)
    xMat = np.mat(xArr)
    yMat = np.mat(yArr)
    
    lr = 0.001
    epochs = 10000
    costList = []
    # 计算数据行列数
    # 行代表数据个数,列代表权值个数
    m,n = np.shape(xMat)
    # 初始化权值
    ws = np.mat(np.ones((n,1)))
    
    for i in range(epochs+1):             
        # xMat和weights矩阵相乘
        h = sigmoid(xMat*ws)   
        # 计算误差
        ws_grad = xMat.T*(h - yMat)/m
        ws = ws - lr*ws_grad 
        
        if i % 50 == 0:
            costList.append(cost(xMat,yMat,ws))
    return ws,costList

sigmoid函数比较简单y=1/(1+ e − x e^{-x} ex),cost函数计算就是1.2中我们计算出的交叉熵损失函数,gradAscent中ws_grad=xMat.T*(h - yMat)/m这是我们1.3中求偏导的结果,costList算出每50次迭代的误差值,我们将会在最后绘制成图。

接下来训练模型和绘制决策边界图

# 训练模型,得到权值和cost值的变化
ws,costList = gradAscent(X_data, y_data)
if scale == False:
    # 画图决策边界
    plot()
    x_test = [[-4],[3]]
    y_test = (-ws[0] - x_test*ws[1])/ws[2]
    plt.plot(x_test, y_test, 'k')
    plt.show()

其中 y_test = (-ws[0] - x_test*ws[1])/ws[2],是由 w 0 w_0 w0+ w 1 w_1 w1x+y w 2 w_2 w2=0,y=-( w 0 w_0 w0-x w 1 w_1 w1)/ w 2 w_2 w2。决策边界图如下

image-20230702223041798

接下来绘制loss图

# 画图 loss值的变化
x = np.linspace(0,10000,201)
plt.plot(x, costList, c='r')
plt.title('Train')
plt.xlabel('Epochs')
plt.ylabel('Cost')
plt.show()

image-20230702222406575

最后我们做预测并且利用库函数计算准确率和召回率

# 预测
def predict(x_data, ws):
    if scale == True:
        x_data = preprocessing.scale(x_data)
    xMat = np.mat(x_data)
    ws = np.mat(ws)
    return [1 if x >= 0.5 else 0 for x in sigmoid(xMat*ws)]

predictions = predict(X_data, ws)

print(classification_report(y_data, predictions))

image-20230702223609543

二.机器学习任务攻略

机器学习一共有三个步骤

  1. function with unknown
  2. define loss from training data
  3. optimization

如果Kaggle上的结果不满意,首先要检查Training data的loss值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tEpYMOHb-1688310013561)(…/AppData/Roaming/Typora/typora-user-images/image-20230702224028965.png)]

1.Training data loss偏大

如果Training data的loss值很大,显然在训练资料上也不理想,可能是model bias的问题。即定义的model过于简单。解决方法:重新设计model,增加输入的feature,增加更多的neurons,使model更具有弹性。

image-20230702224640818

也也可能optimization不理想,例如使用梯度下降卡在局部最小值。

image-20230702224729469

如何确定是model bias的问题导致model弹性不够,还是optimization时Gradient Decent存在local minima的问题导致loss值偏大?

可以比较不同的模型来确定当前的model是否适合。例如用不同层训练network。

image-20230702224832058

2.Testing Data loss偏大

如果Training Data的loss值已经很小了,则可以检查Testing Data的loss值了。

如果Testing Data的loss值偏大就是出现了Overfitting的问题。记住是要Training 的值小,Testing 值大才是Overfitting问题。

overfitting

image-20230702225103063

在曲线上随机选择三个点作为Training Data,由于model的灵活性,它会通过这三个点,但是其它没有Training Data作为限制的点就会波动。再用这个model测试Testing Data,会导致训练上的loss小,但测试上的loss大。

image-20230702225144070

如何解决overfitting
  • 增加训练资料、Data augmentation(要具有合理性)
  • 给model一些限制,让model没有那么大的弹性(如给model限制为二次曲线,选择function时就有机会得到好结果)
如何选出适合的model?

把Training Set分为两部分,一部分为Training Set,一部分为Validation Set。在Training Set训练出来的model在Validation Set上取衡量他们的分数,根据Validation Set上的分数挑选结果,再将这个结果上传到Kaggle上,得到public的分数。因为挑分数是在Validation Set这个model上,public的分数就可以反应private的分数,这就避免了在public上分数很好,而在private上分数很差。
image-20230702225617341

N-fold Cross Validation

把训练资料分成N等份,例如分成3等份,拿其中的一份作为Validation Set,其它作为Training Set,重复三次。有3个model,将这3个model在Training Set都训练一次,在这三种Training Set的结果平均一下,对比结果。如图,model1最好,再将model1用在全部的Training Set上。

image-20230702225822314

三.总结

通过这周的学习,我学会了逻辑回归的原理以及用梯度下降法代码实现的方法,代码方面学会了sigmoid函数,cost交叉熵损失函数,gradAscent求偏导以及用classification_report库函数计算准确率和召回率。对机器学习任务的三个步骤:定义函数、计算 loss、优化有了更深的认识。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值