京公网安备 11010802034615号
经营许可证编号:京B2-20210330
作者 | KHYATI MAHENDRU
编译 | CDA数据分析师
损失函数实际上是我们经常使用的这些技术的核心,本文介绍了多种损失函数,他们的工作位置以及如何在Python中进行编码。
首先想象一下一个场景–你已经在给定的数据集上训练了一个机器学习模型,并且已经准备将其放在客户面前。但是,这个时候你应该如何确定该模型会给出最优的结果呢?是否有一种度量标准或技术可以帮助你快速评估数据集中的模型?
当然有了—简单的说,这就是损失函数在机器学习中发挥作用的地方。
损失函数是我们喜欢使用的机器学习算法的核心。但是可以看到大多数初学者和爱好者对如何使用损失函数们以及在哪里使用损失函数感到非常困惑。
损失函数并不是那么的难以理解,并且如果掌握了它将无限地增强你对机器学习算法的理解。那么,损失函数是什么,我们应该如何把握损失函数的意义呢?
在本文中,我们将讨论机器学习中使用的7种常见的损失函数,并说明每个函数中在什么地方使用。 我们将在本文中介绍很多内容,所以让我们现在开始吧!
假设你现在在山顶上,这个时候需要往下走。你应该怎么决定你往哪个方向走?
假如是我的话,我会这么做:
我刚刚只是凭借我的直接来判断我的决定的么?当然不是,这些决定正是损失函数所提供的。
损失函数将决策映射到相关的成本上。
决策认为上坡会浪费我们的精力和时间。决定认为向下对我们来说更有利。因此,它具有负成本。
在有监督的机器学习算法中,我们希望在学习过程中将每个训练样本的误差最小化。这可以通过一些优化策略(例如梯度下降)来完成。这个误差就来自损失函数。
损失函数和成本函数有什么区别?
首先需要在这里强调一下,尽管成本函数和损失函数是同义词,可以互换使用,但是它们是不同的。
损失函数仅用于单个训练样本。有时也称为错误函数。另一方面,成本函数是整个训练数据集的平均损失。优化策略的目标是最小化成本函数。
此时,你应该非常熟悉线性回归了。它涉及对因变量 Y和几个自变量 X_i 之间的线性关系建模。因此,我们实际上在这些变量上在空间上拟合了一条空间线。
我们将使用给定的数据点来找到系数a0,a1,...,an。
我们将使用著名的波士顿住房数据集来理解这一概念。为了简单起见,我们将只使用一个特征- 每个住宅的平均房间数(X),来预测因变量,以1000美元为单位的房屋的中位数价值(Y)。
我们将使用“ 梯度下降”作为一个优化策略来找到回归线。我不会详细介绍有关“梯度下降”的复杂细节,但是这里有一个关于权重更新规则的提示”:
在这里,theta_j是要更新的权重,alpha是学习率,J是成本函数。成本函数由theta参数化。我们的目标是找到产生最小总成本的theta值。
我已经定义了以下每个损失函数要遵循的步骤:
1.平方误差损失
每个训练样本的平方误差损失(也称为L2损失)是实际值与预测值之差的平方:
相应的成本函数是这些平方误差(MSE)的均值
我觉得在你参考下面的这些代码之前,先自己尝试找到梯度下降的梯度。
def update_weights_MSE(m, b, X, Y, learning_rate): m_deriv = 0 b_deriv = 0 N = len(X) for i in range(N): # Calculate partial derivatives # -2x(y - (mx + b)) m_deriv += -2*X[i] * (Y[i] - (m*X[i] + b)) # -2(y - (mx + b)) b_deriv += -2*(Y[i] - (m*X[i] + b)) # We subtract because the derivatives point in direction of steepest ascent m -= (m_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m, b
我在波士顿数据上使用了这段代码,以获取500次迭代中不同的学习率值:
接下来你可以尝试以0.1的学习率再次运行该代码500次迭代。
让我们再多谈一下MSE损失函数。它是一个二次函数
其中a> 0),还记得它的是什么样子么?
二次函数仅具有全局最小值。由于没有局部最小值,因此我们永远不会陷入局部最小值的困境。因此,它始终可以确保“梯度下降”收敛(如果它完全收敛)到全局最小值。
MSE损失函数通过对错误进行平方来惩罚模型,以免产生大的错误。平方大会使它更大,对吗?但是在这里有一个警告。此属性使MSE成本函数对异常值的鲁棒性(Robust)降低。因此,如果我们的数据容易出现异常值,则不应使用此方法。
2.绝对误差损失
每个训练样本的绝对误差是预测值与实际值之间的距离,而与符号无关。绝对误差也称为L1损失:
正如我之前提到的,代价是这些绝对误差(MAE)的均值。
与MSE相比,MAE成本对于异常值更为稳健。但是,在处理数学方程中的绝对或模运算并不容易。我相信你们中的很多人都会同意这一点!我们可以认为这是MAE的一个缺点。
这是带有MAE成本的update_weight函数的代码:
def update_weights_MAE(m, b, X, Y, learning_rate): m_deriv = 0 b_deriv = 0 N = len(X) for i in range(N): # Calculate partial derivatives # -x(y - (mx + b)) / |mx + b| m_deriv += - X[i] * (Y[i] - (m*X[i] + b)) / abs(Y[i] - (m*X[i] + b)) # -(y - (mx + b)) / |mx + b| b_deriv += -(Y[i] - (m*X[i] + b)) / abs(Y[i] - (m*X[i] + b)) # We subtract because the derivatives point in direction of steepest ascent m -= (m_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m, b
在以不同的学习率运行代码500次的迭代后,我们得到以下图表:
3.Huber Loss
Huber损失综合了MSE和MAE的最佳性能。对于较小的误差,它是平方的;对于其他误差,它是线性的(对于梯度,也是类似)。由其delta参数进行标识:
上方是针对较小的误差是平方的,下方是针对其他误差为线性的。
def update_weights_Huber(m, b, X, Y, delta, learning_rate): m_deriv = 0 b_deriv = 0 N = len(X) for i in range(N): # derivative of quadratic for small values and of linear for large values if abs(Y[i] - m*X[i] - b) <= delta: m_deriv += -X[i] * (Y[i] - (m*X[i] + b)) b_deriv += - (Y[i] - (m*X[i] + b)) else: m_deriv += delta * X[i] * ((m*X[i] + b) - Y[i]) / abs((m*X[i] + b) - Y[i]) b_deriv += delta * ((m*X[i] + b) - Y[i]) / abs((m*X[i] + b) - Y[i]) # We subtract because the derivatives point in direction of steepest ascent m -= (m_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m, b
对于delta参数的不同值,我们以 0.0001的学习率获得了500次权重更新的迭代,获得了如下图表:[
与MSE相比,Huber损失对异常值的鲁棒性更高。它被使用与稳健回归,M-估计和叠加模型。在分类中也使用了Huber Loss的一种变体。
从看到这个名字就应该不言自明了。二分类是指将一个对象分配给两个类别中的一个。这种分类基于应用于输入特征向量的规则。例如,根据电子邮件的主题,将电子邮件分为垃圾邮件或非垃圾邮件,这是一种二进制分类。
我将在乳腺癌数据集上说明这些二分类损失函数。
我们希望根据平均半径,面积,周长等特征将肿瘤分类为“恶性”或“良性”。为简化起见,我们将仅使用两个输入特征(X1和X2),即“最差面积”和“平均对称”进行分类。目标值Y可以为0(恶性)或1(良性)。
这是我们数据的散点图:
1.二元交叉熵损失
让我们首先了解“熵”一词。 通常,我们使用熵来表示混乱或不确定性。对于具有概率分布p(X)的随机变量X进行测量:
负号是用于使总量为正的。
概率分布的熵值越大,表示分布的不确定性越大。同样,较小的值表示更确定的分布。
这使得二元交叉熵适合作为损失函数– 使其值最小化。我们将二进制交叉熵损失用于分类模型,该模型输出一个概率p。
元素属于1类(或正类)的概率= p 然后,元素属于0类(或负类)的概率= 1-p
然后,输出标签y(可以取值0和1)和预测概率p的交叉熵损失定义为:
这也称为对数丢失。要计算概率p,我们可以使用Sigmoid函数。在此,z是我们输入特性的函数:
Sigmoid函数的范围是[0,1],使其适合于计算概率。
尝试自己输入一下代码,然再后查看下面的update_weight函数的代码。
def update_weights_BCE(m1, m2, b, X1, X2, Y, learning_rate): m1_deriv = 0 m2_deriv = 0 b_deriv = 0 N = len(X1) for i in range(N): s = 1 / (1 / (1 + math.exp(-m1*X1[i] - m2*X2[i] - b))) # Calculate partial derivatives m1_deriv += -X1[i] * (s - Y[i]) m2_deriv += -X2[i] * (s - Y[i]) b_deriv += -(s - Y[i]) # We subtract because the derivatives point in direction of steepest ascent m1 -= (m1_deriv / float(N)) * learning_rate m2 -= (m2_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m1, m2, b
关于使用权重更新规则进行1000次迭代(具有不同的alpha值),我得到以下图表:
2.铰链损失(Hinge Loss)
铰链损失主要用于支持标签为-1和1的支持向量机(SVM)分类器。因此,请确保将数据集中“Malignant”类的标签从0更改为-1。
铰链损失不仅会惩罚错误的预测,还会惩罚不确定的正确预测。
输入输出对(x,y)的铰链损失为:
def update_weights_Hinge(m1, m2, b, X1, X2, Y, learning_rate): m1_deriv = 0 m2_deriv = 0 b_deriv = 0 N = len(X1) for i in range(N): # Calculate partial derivatives if Y[i]*(m1*X1[i] + m2*X2[i] + b) <= 1: m1_deriv += -X1[i] * Y[i] m2_deriv += -X2[i] * Y[i] b_deriv += -Y[i] # else derivatives are zero # We subtract because the derivatives point in direction of steepest ascent m1 -= (m1_deriv / float(N)) * learning_rate m2 -= (m2_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m1, m2, b
在使用三个不同的alpha值对2000次迭代运行update函数之后,我们获得了以下图:
铰链损失简化了SVM的数学运算,同时使损失最大化(与对数损失相比)。当我们要做出实时决策而并不是高度关注准确性时,就可以使用它。
现在电子邮件不只是被归类为垃圾邮件或非垃圾邮件(现在已经不是90年代了!)。它们可以被分为其他各种类别-工作,家庭,社交,晋升等。在现在邮件分类是一个多类别分类用例。
我们将使用鸢尾花数据集来了解其余两个损失函数。我们将使用2个特征X1(萼片长度)和特征X2(花瓣宽度)来预测鸢尾花(Setosa,Versicolor或Virginica)的类别(Y)
我们的任务是使用神经网络模型和Keras中内置的Adam优化器来实现分类。这是因为随着参数数量的增加,数学以及代码将变得难以理解。
这是我们数据的散点图:
1.多分类交叉熵损失
多分类交叉熵损失是二分类交叉熵损失的概括。输入向量Xi和相应的单编码目标向量Yi的损耗为:
我们使用softmax函数来找到概率p_ij:
“ Softmax是通过在输出层之前的神经网络层实现的。Softmax层必须具有与输出层相同数量的节点。”
最后,我们的输出是给定输入具有最大概率的类别。
我们使用一个输入层和一个输出层来进行构建模型,并以不同的学习率对其进行编译。在model.compile()语句中将损失参数指定为“ categorical_crossentropy”:
# importing requirements from keras.layers import Dense from keras.models import Sequential from keras.optimizers import adam # alpha = 0.001 as given in the lr parameter in adam() optimizer # build the model model_alpha1 = Sequential() model_alpha1.add(Dense(50, input_dim=2, activation='relu')) model_alpha1.add(Dense(3, activation='softmax')) # compile the model opt_alpha1 = adam(lr=0.001) model_alpha1.compile(loss='categorical_crossentropy', optimizer=opt_alpha1, metrics=['accuracy']) # fit the model # dummy_Y is the one-hot encoded # history_alpha1 is used to score the validation and accuracy scores for plotting history_alpha1 = model_alpha1.fit(dataX, dummy_Y, validation_data=(dataX, dummy_Y), epochs=200, verbose=0)
这是经过200个时期训练后的成本和准确率图:
2. KL散度(KL-Divergence)
KL散度是度量一个概率分布与另一个分布之间的差异的指标。KL散度为零表示分布相同。
请注意,散度函数不是对称的。
这就是为什么KL散度不能用作距离度量的原因。
我将介绍使用KL-散度作为损失函数而不涉及其数学的基本方法。我们想要得到目标变量关于输入特征的真实概率分布P的近似值,给出一个近似分布q。由于kl散度不是对称的,我们可以用两种方法来实现:
第一种方法用于监督学习中,第二种方法用于强化学习中。KL-散度在功能上类似于多分类交叉熵,并且也称为P相对于Q的相对熵:
我们像以前对多类交叉熵损失所做的那样,在compile()函数中将'kullbackleiblerdivergence'指定为损失参数的值。
# importing requirements from keras.layers import Dense from keras.models import Sequential from keras.optimizers import adam # alpha = 0.001 as given in the lr parameter in adam() optimizer # build the model model_alpha1 = Sequential() model_alpha1.add(Dense(50, input_dim=2, activation='relu')) model_alpha1.add(Dense(3, activation='softmax')) # compile the model opt_alpha1 = adam(lr=0.001) model_alpha1.compile(loss='kullback_leibler_divergence', optimizer=opt_alpha1, metrics=['accuracy']) # fit the model # dummy_Y is the one-hot encoded # history_alpha1 is used to score the validation and accuracy scores for plotting history_alpha1 = model_alpha1.fit(dataX, dummy_Y, validation_data=(dataX, dummy_Y), epochs=200, verbose=0)
与多类分类相比,KL-散度更常用于近似复杂函数。我们在使用深度自动生成模型(如变分自动编码器(VAE))时经常遇到KL-散度。
哇!到这里为止我们已经讲了很多了。一直看到最后的你,给你自己一点鼓励吧。这篇文章中是我们通常在机器学习中使用的损失函数的详细列表。
在这里呢建议你在继续进行机器学习的过程中,多读几遍。因为这不是一次努力就可以全部理解的。需要一些阅读时间和经验才能了解这些损失函数的工作方式和位置。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
一、问题:为什么 ID 会"断号" 很多刚接触 MySQL 的同学都会有一个困惑:表里的主键 ID 是自增的,删了中间几行数据之后,ID 变 ...
2026-10-22一、问题场景:为什么会重复 JOIN 同一个子查询 在写复杂 SQL 时,经常遇到这种需求:同一张表或同一个聚合子查询,要和主表关联 ...
2026-10-22人力资源专员是HR体系的执行入口。招聘信息发布、简历初筛、面试安排、考勤汇总、入离职手续、劳动合同与档案管理,大多由这个岗 ...
2026-10-22人力资源经理问“必学技巧”,真正要解决的不是知识清单不够长,而是时间有限、业务催得紧,学完却用不上。更有效的路径是:先用 ...
2026-10-22内容营销岗位的核心任务,不是“把文案写得更漂亮”,而是围绕目标受众,用持续的内容供给影响认知、推动转化并沉淀复购。它至少 ...
2026-10-22理财经理培训课程很多,难的是判断“先学什么、后学什么、学完能做什么”。与其按课程名称罗列,不如先看岗位任务:客户分层与维 ...
2026-10-22理财经理的知识结构,可以先用一句话概括:合规与产品知识决定“不出错”,客户经营与资产配置决定“够不够专业”,市场研判与数 ...
2026-10-22经济学背景做数据分析,优势不在工具,而在问题意识:供需如何相互作用、成本与收益如何权衡、变量之间是相关还是因果。真正的缺 ...
2026-10-22需要,但要把“需要”理解准确。经济学本身就在处理数据:GDP、物价、就业、企业营收、问卷调研,都是经济分析的原料。真正的区 ...
2026-10-22经济学分析能力不是单一技能,它至少由三层构成:把现实问题转成可检验假设的理论框架能力、用数据与统计方法验证假设的工具能力 ...
2026-10-22金融分析师的知识提升,先补的不是更多模型,而是让结论可复核的底层能力。按任务顺序,大致是四层:财务与业务理解、指标口径管 ...
2026-10-22金融分析师的“通用技能”,指换到不同机构、不同行业组仍用得上的底层能力,而非某家公司内部系统的操作经验。按任务拆,日常要 ...
2026-10-22先给结论:数据分析证书不是金融分析师的准入条件,招聘方也不会因为一张证书就直接判断你能做分析。要不要考,取决于你当前任务 ...
2026-10-22金融分析师的核心技能,不是“会看K线”或“会讲宏观”,而是能把一家公司、一个行业或一类资产,转化为可核查的数据判断与书面 ...
2026-10-22产品经理的知识提升,不是把需求文档、原型、SQL、数据分析、项目管理都学一遍,而是先对准目标岗位的真实任务,找出自己最缺的 ...
2026-10-22产品专员提升工作知识,最有效的方式不是先囤课程,而是围绕日常交付的四件事来补:需求调研与优先级判断、原型与PRD表达、竞品 ...
2026-10-22产品运营专员提升个人能力,常见误区是先把Excel、SQL、Python列成一张学习清单,然后从第一个工具开始学。更有效的做法是先回答 ...
2026-10-22产品运营的能力提升,最怕从“课程目录”出发:今天学增长模型,明天背SQL语法,学完却说不清自己负责的功能为什么激活率低。更 ...
2026-10-22产品经理的技能和影响力不是两条分开的赛道。技能决定你能不能把问题分析清楚、把方案设计对;影响力决定你的判断能否被团队接受 ...
2026-10-22产品经理要学的数据分析能力,不是“会写SQL”或“会用BI工具”这么简单。更准确地说,是围绕需求评估、功能迭代、指标监控、实 ...
2026-10-22