
作者 | 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
在AI渗透率超85%的2025年,企业生存之战就是数据之战,CDA认证已成为决定企业存续的生死线!据麦肯锡全球研究院数据显示,AI驱 ...
2025-07-2035岁焦虑像一把高悬的利刃,裁员潮、晋升无望、技能过时……当职场中年危机与数字化浪潮正面交锋,你是否发现: 简历投了10 ...
2025-07-20CDA 数据分析师报考条件详解与准备指南 在数据驱动决策的时代浪潮下,CDA 数据分析师认证愈发受到瞩目,成为众多有志投身数 ...
2025-07-18刚入职场或是在职场正面临岗位替代、技能更新、人机协作等焦虑的打工人,想要找到一条破解职场焦虑和升职瓶颈的系统化学习提升 ...
2025-07-182025被称为“AI元年”,而AI,与数据密不可分。网易公司创始人丁磊在《AI思维:从数据中创造价值的炼金术 ...
2025-07-18CDA 数据分析师:数据时代的价值挖掘者 在大数据席卷全球的今天,数据已成为企业核心竞争力的重要组成部分。从海量数据中提取有 ...
2025-07-18SPSS 赋值后数据不显示?原因排查与解决指南 在 SPSS( Statistical Package for the Social Sciences)数据分析过程中,变量 ...
2025-07-18在 DBeaver 中利用 MySQL 实现表数据同步操作指南 在数据库管理工作中,将一张表的数据同步到另一张表是常见需求,这有助于 ...
2025-07-18数据分析师的技能图谱:从数据到价值的桥梁 在数据驱动决策的时代,数据分析师如同 “数据翻译官”,将冰冷的数字转化为清晰的 ...
2025-07-17Pandas 写入指定行数据:数据精细化管理的核心技能 在数据处理的日常工作中,我们常常需要面对这样的场景:在庞大的数据集里精 ...
2025-07-17解码 CDA:数据时代的通行证 在数字化浪潮席卷全球的今天,当企业决策者盯着屏幕上跳动的数据曲线寻找增长密码,当科研人员在 ...
2025-07-17CDA 精益业务数据分析:数据驱动业务增长的实战方法论 在企业数字化转型的浪潮中,“数据分析” 已从 “加分项” 成为 “必修课 ...
2025-07-16MySQL 中 ADD KEY 与 ADD INDEX 详解:用法、差异与优化实践 在 MySQL 数据库表结构设计中,索引是提升查询性能的核心手段。无论 ...
2025-07-16解析 MySQL Update 语句中 “query end” 状态:含义、成因与优化指南 在 MySQL 数据库的日常运维与开发中,开发者和 DBA 常会 ...
2025-07-16如何考取数据分析师证书:以 CDA 为例 在数字化浪潮席卷各行各业的当下,数据分析师已然成为企业挖掘数据价值、驱动决策的 ...
2025-07-15CDA 精益业务数据分析:驱动企业高效决策的核心引擎 在数字经济时代,企业面临着前所未有的数据洪流,如何从海量数据中提取有 ...
2025-07-15MySQL 无外键关联表的 JOIN 实战:数据整合的灵活之道 在 MySQL 数据库的日常操作中,我们经常会遇到需要整合多张表数据的场景 ...
2025-07-15Python Pandas:数据科学的瑞士军刀 在数据驱动的时代,面对海量、复杂的数据,如何高效地进行处理、分析和挖掘成为关键。 ...
2025-07-15用 SQL 生成逆向回滚 SQL:数据操作的 “后悔药” 指南 在数据库操作中,误删数据、错改字段或误执行批量更新等问题时有发生。 ...
2025-07-14t检验与Wilcoxon检验的选择:何时用t.test,何时用wilcox.test? t 检验与 Wilcoxon 检验的选择:何时用 t.test,何时用 wilcox. ...
2025-07-14