当前位置: 首页 > news >正文

《sklearn机器学习——多标签排序指标》

在多标签的机器学习中,每个样本可以有很多与之相关联的真实标签。目标是提供高的评分和较好的真实值排名。

覆盖误差

coverage_error函数计算必须包含在最中预测的标签的平均数量,以预测所有真实的标签。如果想知道高分数标签的个数,需要可以预测不缺少任何真实标签的平均值。因此,该指标的最佳值是真实标签的平均值。

注意:这里实现的得分比在Tsoumakas et al., 2010文献中提供的计算方式大1.这个延伸是为了解决一些例子中不包含真实标签的退化现象。
在形式上,提供真实标签y∈{0,1}nsamples×nlabelsy \in \{0, 1\}^{n_{samples} \times n_{labels}}y{0,1}nsamples×nlabels的二分类指标矩阵,以及与每一个标签相联合的得分f^∈Rnsamples×nlabels\hat{f} \in R^{n_{samples} \times n_{labels}}f^Rnsamples×nlabels,覆盖误差定义如下:

coverage(y,f^)=1nsamples∑i=0nsamples−1maxj:yij=1rankij\begin{aligned} coverage(y, \hat{f}) = \frac{1}{n_{samples}} \sum_{i=0}^{n_{samples}-1} max_{j:y_{ij}=1} rank_{ij} \end{aligned}coverage(y,f^)=nsamples1i=0nsamples1maxj:yij=1rankij

其中,rankij=∣k:f^ik≥f^ij∣rank_{ij} = |k: \hat{f}_{ik} \geq \hat{f}_{ij}|rankij=k:f^ikf^ij。给定等级定义,通过给出将被分配给所有绑定值的最大等级,yscoresy_scoresyscores中的关系被破坏。

这是使用该函数的小例子:

>>> import numpy as np
>>> from sklearn.metrics import coverage_error
>>> y_true = np.array([[1, 0, 0], [0, 0, 1]])
>>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]])
>>> coverage_error(y_true, y_score)
2.5 

标签排名平均精确度

label_ranking_average_precision_score函数执行标签排名平均精确度(label ranking average precision LRAP)。这个指标与average_precision_score函数相联系,但是基于标签排名的概念而不是精确度和召回率。

主要参数

  • y_true:真实标签的二进制矩阵,形状为(n_samples, n_labels),其中1表示相关标签,0表示不相关 1 。
  • y_score:预测得分矩阵,形状与 y_true 相同,数值越高表示标签排名越靠前 。
  • sample_weight (可选):样本权重数组,用于加权计算最终得分 。
  • return(返回值)
    返回标签排名平均精度(LRAP),范围在(0,1]之间,1表示完美排序。该指标通过计算每个样本的真实标签在预测排名中的平均精度,综合反映模型对多标签的排序能力。

标签排名平均精确度(LRAP)平均所有样本,并是回答如下问题的答案:对于每一个真实标签,多大的较高排名标签的比例是真实的标签?如果可以与每一个样本相关的排名,这个指标测量值会较高。得到的评分均会大于0,最佳值是1。如果每个样本有一个确定的相关标签,标签排名平均精确度等价于mean reciprocal rank
形式上地,给定一个真实标签的二分类指标矩阵y∈{0,1}nsamples×nlabelsy \in \{0, 1\}^{n_{samples} \times n_{labels}}y{0,1}nsamples×nlabels,且与每个标签相联系的评分f^∈Rnsamples×nlabels\hat{f} \in R^{n_{samples} \times n_{labels}}f^Rnsamples×nlabels,平均精确度的定义如下:

LRAP(y,f^)=1nsamples∑i=0nsamples−11∣∣yi∣∣0∑j:yij=1∣Lij∣rankij\begin{aligned} LRAP(y, \hat{f}) = \frac{1}{n_{samples}} \sum_{i=0}^{n_{samples}-1} \frac{1}{||y_i||_0} \sum_{j:y_{ij}=1} \frac{|L_{ij}|}{rank_{ij}} \end{aligned}LRAP(y,f^)=nsamples1i=0nsamples1∣∣yi01j:yij=1rankijLij

其中Lij={k:yik=1,f^ik≥f^ij}L_{ij} = \{k: y_{ik} = 1, \hat{f}_{ik} \geq \hat{f}_{ij}\}Lij={k:yik=1,f^ikf^ij}rankij=∣{k:f^ik≥f^ij}∣rank_{ij} = |\{k: \hat{f}_{ik} \geq \hat{f}_{ij}\}|rankij={k:f^ikf^ij}∣⋅∣|\cdot|计算集合的基数(例如,集合中元素的数量),∣∣⋅∣∣0||\cdot||_0∣∣0l0l_0l0“范式”(它计算向量中非零元素个数)。

如下是使用该函数的小例子:

>>> import numpy as np
>>> from sklearn.metrics import label_ranking_average_precision_score
>>> y_true = np.array([[1, 0, 0], [0, 0, 1]])
>>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]])
>>> label_ranking_average_precision_score(y_true, y_score)
0.416... 

排序损失

label_ranking_loss函数用于计算排序损失,它计算样本中标签匹配排序不正确的个数均值。例如,真实标签的得分比错误标签的得分低,赋予排序的错误和正确标签匹配个数倒数作为权重。最低的排序损失值为0。

label_ranking_loss函数

参数

  • y_true: 一个二进制矩阵,尺寸为 (n_samples, n_labels),代表真实的标签情况。每个元素是0或1,表示样本中是否存在对应的标签。
  • y_score: 预测得分矩阵,尺寸同样为 (n_samples, n_labels)。这些分数反映了模型对样本属于对应标签的信心程度。

返回值

  • loss: 一个浮点数,表示平均的标签排序损失。这个值越低,说明模型在区分正负标签方面表现越好。

函数内部计算数学形式:

给定一个真实标签y∈{0,1}nsamples×nlabelsy \in \{0, 1\}^{n_{samples} \times n_{labels}}y{0,1}nsamples×nlabels的二分类指标矩阵,以及与每一个标签相联系的评分f^∈Rnsamples×nlabels\hat{f} \in R^{n_{samples} \times n_{labels}}f^Rnsamples×nlabels,排序损失函数的定义如下:

ranking_loss(y,f^)=1nsamples∑i=0nsamples−11∣∣yi∣∣0(nlabels−∣∣yi∣∣0)∣{(k,l):f^ik≤f^il,yik=1,yil=0}∣\begin{aligned} ranking\_loss(y, \hat{f}) = \frac{1}{n_{samples}} \sum_{i=0}^{n_{samples}-1} \frac{1}{||y_i||_0 (n_{labels} - ||y_i||_0)} |\{(k, l): \hat{f}_{ik} \leq \hat{f}_{il}, y_{ik} = 1, y_{il} = 0\}| \end{aligned}ranking_loss(y,f^)=nsamples1i=0nsamples1∣∣yi0(nlabels∣∣yi0)1{(k,l):f^ikf^il,yik=1,yil=0}

其中,∣⋅∣|\cdot|计算集合的基数(例如,集合中各元素的个数)以及∣∣⋅∣∣0||\cdot||_0∣∣0l0l_0l0"范式"(它计算向量中非零元素的个数)。

如下是使用该函数的小例子:

>>> import numpy as np
>>> from sklearn.metrics import label_ranking_loss
>>> y_true = np.array([[1, 0, 0], [0, 0, 1]])
>>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]])
>>> label_ranking_loss(y_true, y_score)
0.75...
>>> # With the following prediction, we have perfect and minimal loss
>>> y_score = np.array([[1.0, 0.1, 0.2], [0.1, 0.2, 0.9]])
>>> label_ranking_loss(y_true, y_score)
0.0 

Normalized Discounted Cumulative Gain(NDGG)

Discounted Cumulative Gain(DCG)和Normalized Discounted Cumulative Gain(NDCG)均是排序指数;它们对预测序列和真实得分进行比较,例如一个查询答案的相关性。

概述

nDCG是一种评价排序结果好坏的度量标准,尤其适用于搜索引擎或推荐系统等场景。它通过计算Discounted Cumulative Gain(DCG)并将其规范化到[0, 1]区间来实现这一点,其中1表示最佳可能的排序。

参数

  • y_true: 一个数组或列表,包含每个项目的实际相关性得分。这些值直接反映了项目的真实重要性或用户对其的兴趣程度。
  • y_score: 一个数组或列表,长度与y_true相同,包含模型预测的得分。这些分数反映模型认为各个项目对用户的潜在价值。
  • k (可选): 整数,表示仅考虑前k个结果进行评估。如果未指定,则默认使用所有提供的结果。

计算

  1. DCG: 通过累加从第一位开始的实际相关性得分,并根据其位置给予不同的权重来计算。位置越靠后,得分折扣越多。
  2. IDCG (Ideal DCG): 在相同的前k项下,假设结果是按最佳方式排序时所能达到的最大DCG值。
  3. nDCG: 将DCG除以IDCG得到的值。这将原始的DCG标准化到[0, 1]范围内,1表示最好的排序效果。

返回值

  • nDCG@k: 一个浮点数,代表在考虑前k个结果的情况下的规范化折损累积增益。该值越接近1,表明排序效果越好。

“Discounted cumulative gain(DCG)是一个对排序质量的测量。在信息检索中,该指标经常被用来搜索引擎算法或者相关应用的效率。在搜索引擎结果集中,使用文档的分级相关性比例,DCG基于它在结果列表中的位置,测量文档有用性,或者增益。增益在结果表中是由上到下的累积,根据每一个结果的增益,不考虑较低的排名。”

DCG在预测序列中,给正确标签排序(例如查询答案的相关性),然后乘以对数衰减,最后汇总求和。在最先的K个结果后,求和会被截断,因此称它为DCG@K。KDCG,或者NDCG@K是DCG除以最佳预测对应的DCG,从而该值是介于0和1之间的。通常,NDCG优先于DCG。

与排序损失作比较,NDCG能够考虑相关性评分,而不是真实值排序。所以,所过真实值仅由一个序列构成,使用排序损失会更好;如果真实值是由实际有用性评分构成(例如,0表示不相关,1表示相关,2表示非常相关),可以选用NDCG。

NDGG内部计算的数学形式:

对于某样本,给定每一个标签y∈RMy \in R^MyRM的连续真实值向量,其中MMM是返回值的个数,预测值是y^\hat{y}y^,它是排序函数的索引fff,DCG评分是:

∑r=1min(K,M)yf(x)log⁡(1+r)\begin{aligned} \sum_{r=1}^{min(K, M)} \frac{y f(x)}{\log(1 + r)} \end{aligned}r=1min(K,M)log(1+r)yf(x)

并且,NDCG评分是DCG评分除以从yyy中得到的DCG评分。
以下是他的一个简单示例:

import math
import numpy as npdef dcg_at_k(relevance_scores, k):"""计算前 k 个结果的折损累积增益 (DCG@k)Args:relevance_scores: 相关性得分列表,按排序位置排列 (例如: [3, 2, 3, 0, 1])k: 计算到第 k 个位置Returns:DCG@k 值"""# 确保只计算前 k 个scores = relevance_scores[:k]# DCG 公式: sum( rel_i / log2(i+1) ),其中 i 从 1 开始# 注意: Python 索引从 0 开始,所以位置 i 对应索引 i-1dcg = 0.0for i, rel in enumerate(scores):# i+1 是实际位置 (1-indexed)# log2(i+1) 是折损因子,位置 1 的折损是 log2(2)=1,位置 2 是 log2(3)≈1.58,依此类推dcg += rel / math.log2(i + 2)  # i+2 因为 i 从 0 开始,位置是 i+1return dcgdef ndcg_at_k(relevance_scores, k):"""计算前 k 个结果的归一化折损累积增益 (NDCG@k)Args:relevance_scores: 相关性得分列表,按排序位置排列k: 计算到第 k 个位置Returns:NDCG@k 值 (范围在 0 到 1 之间)"""# 计算当前排序的 DCGactual_dcg = dcg_at_k(relevance_scores, k)# 计算理想排序 (IDCG): 将相关性得分从高到低排序ideal_scores = sorted(relevance_scores, reverse=True)ideal_dcg = dcg_at_k(ideal_scores, k)# 避免除以零if ideal_dcg == 0:return 0.0# NDCG = DCG / IDCGreturn actual_dcg / ideal_dcg# --- 示例 ---
if __name__ == "__main__":# 假设我们有一个搜索查询,返回了 5 个文档# 我们对每个文档的相关性进行打分 (例如: 3=非常相关, 2=相关, 1=轻微相关, 0=不相关)# 情况 1: 排序效果很好 (高相关性结果排在前面)good_order = [3, 2, 3, 0, 1]  # 实际排序的相关性得分# 情况 2: 排序效果很差 (高相关性结果排在后面)bad_order = [0, 1, 3, 2, 3]  # 实际排序的相关性得分k = 5  # 我们关心前 5 个结果的整体排序质量# 计算好排序的 NDCGndcg_good = ndcg_at_k(good_order, k)print(f"好排序 {good_order} 的 NDCG@{k}: {ndcg_good:.4f}")# 计算差排序的 NDCGndcg_bad = ndcg_at_k(bad_order, k)print(f"差排序 {bad_order} 的 NDCG@{k}: {ndcg_bad:.4f}")# 让我们再看一个只看前 3 个结果的例子 (NDCG@3)k3 = 3ndcg_good_3 = ndcg_at_k(good_order, k3)ndcg_bad_3 = ndcg_at_k(bad_order, k3)print(f"\n只看前 {k3} 个结果:")print(f"好排序 {good_order[:k3]} 的 NDCG@{k3}: {ndcg_good_3:.4f}")print(f"差排序 {bad_order[:k3]} 的 NDCG@{k3}: {ndcg_bad_3:.4f}")# 验证: 理想排序的 NDCG 应该是 1.0ideal_order = sorted(good_order, reverse=True) # [3, 3, 2, 1, 0]ndcg_ideal = ndcg_at_k(ideal_order, k)print(f"\n理想排序 {ideal_order} 的 NDCG@{k}: {ndcg_ideal:.4f} (应该接近 1.0)")

输出为:

好排序 [3, 2, 3, 0, 1] 的 NDCG@5: 0.9073
差排序 [0, 1, 3, 2, 3] 的 NDCG@5: 0.6827只看前 3 个结果:
好排序 [3, 2, 3] 的 NDCG@3: 1.0000
差排序 [0, 1, 3] 的 NDCG@3: 0.5714理想排序 [3, 3, 2, 1, 0] 的 NDCG@5: 1.0000 (应该接近 1.0)

文章转载自:

http://JbeArwop.Ldspj.cn
http://lZk5GIl3.Ldspj.cn
http://sjjUwT36.Ldspj.cn
http://ZHF6OHxB.Ldspj.cn
http://v4ReRguS.Ldspj.cn
http://HztqrG4k.Ldspj.cn
http://6cXnn7i2.Ldspj.cn
http://QA9RwLHp.Ldspj.cn
http://yeUWErYJ.Ldspj.cn
http://WH5Pwhqv.Ldspj.cn
http://vrvqLySj.Ldspj.cn
http://ReX5ow6R.Ldspj.cn
http://9fJ7htDh.Ldspj.cn
http://s5ptb5J8.Ldspj.cn
http://4g6XDBKi.Ldspj.cn
http://q4oIwMBE.Ldspj.cn
http://1cBAxfEq.Ldspj.cn
http://uy62RWXs.Ldspj.cn
http://FObq9tQK.Ldspj.cn
http://VdSCd1lf.Ldspj.cn
http://ZQfkaJuB.Ldspj.cn
http://lhhVypgO.Ldspj.cn
http://GtQn5pEL.Ldspj.cn
http://ebU7ogzt.Ldspj.cn
http://GZMOaKI6.Ldspj.cn
http://ZNMw9t9k.Ldspj.cn
http://ePlZFR7T.Ldspj.cn
http://0nEV2BOW.Ldspj.cn
http://s8D5NAPH.Ldspj.cn
http://88yEfSwc.Ldspj.cn
http://www.dtcms.com/a/369157.html

相关文章:

  • 智能风险评估与欺诈检测系统
  • 深度学习:归一化技术
  • 遇到“指责型人格”别硬碰硬!3个反拿捏技巧,让他从挑刺变闭嘴
  • numpy实现torch和multi-head
  • 基于TurboID的邻近标记质谱(PL-MS)实验指南③:完整实验流程
  • Day26 函数1
  • Hutool AI模块已经上线
  • 从头开始学习AI:第四章 - 逻辑回归与分类问题
  • 优利德绝缘电阻测试仪:从原理、操作到安全应用的完全指南
  • GCC工具链使用学习笔记
  • 【前端教程】JavaScript 实现图片鼠标悬停切换效果与==和=的区别
  • 8. Mono与IL2Cpp简介
  • LLM与数据工程的融合:衡石Data Agent的语义层与Agent框架设计
  • ESP-IDF串口中断接收
  • git命令解析
  • 如何从chrome中获取会话id
  • Linux/UNIX系统编程手册笔记:进程组、会话、作业控制、优先级、调度、资源
  • HTML HTML基础(2)
  • Git 同步最新代码:用 stash -> pull -> pop 安全同步更新
  • java,通过SqlSessionFactory实现动态表明的插入和查询(适用于一个版本一个表的场景)
  • 男人怕老婆:家庭幸福的密码与社会文明的缩影?
  • 基于单片机的六足机器人控制系统设计
  • watchEffect 与 watch的区别
  • 怎么获取Nano Banana的APK Key?
  • proxmox8升级到proxmox9
  • Karmada v1.15 版本发布
  • AI在目前会议直播系统中应用
  • 【C++】 priority_queue 容器模拟实现解析
  • rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(二十六)windows平台运行时隐藏控制台
  • leetcode 6 Z字形变化