【传知代码】基于标签相关性的多标签学习(论文复现)

news2024/11/15 4:24:54

在当今信息爆炸的时代,数据中包含的标签信息对于理解和分析复杂问题至关重要。在诸如文本分类、图像识别和推荐系统等应用中,如何有效地利用标签相关性提升多标签学习的效果成为了研究的热点之一。基于标签相关性的多标签学习方法,通过挖掘不同标签之间的潜在关联,旨在提高模型对多标签数据的准确性和泛化能力。

本文所涉及所有资源均在传知代码平台可获取

目录

概述

算法流程

核心代码

最后总结


概述

        帕金森病是一种使人虚弱的慢性神经系统疾病。传统中医(TCM)是一种诊断帕金森病的新方法,而用于诊断帕金森病的中医数据集是一个多标签数据集。考虑到帕金森病数据集中的症状(标签)之间总是存在相关性,可以通过利用标签相关性来促进多标签学习过程。目前的多标签分类方法主要尝试从标签对或标签链中挖掘相关性。该文章提出了一种简单且高效的多标签分类框架,称为潜在狄利克雷分布多标签(LDAML),该框架旨在通过使用类别标签的主题模型来学习全局相关性。简而言之,研究人员试图通过主题模型在标签集上获得抽象的“主题”,从而能够挖掘标签之间的全局相关性。大量实验清楚地验证了所提出的方法是一个通用且有效的框架,能够提高大多数多标签算法的性能。基于该框架,研究人员在中医帕金森病数据集上取得了令人满意的实验结果,这可以为该领域的发展提供参考和帮助。

        多标签学习(Multi-Label Learning)是一种机器学习方法,用于处理具有多个标签的数据样本。与传统的单标签学习不同,每个数据点在多标签学习中可以同时属于一个或多个类别,而不仅仅是一个确定的标签。其目标是经过算法训练后输出一个分类模型,即学习一组从特征空间到标记空间的实值函数映射。假设使用X=RdX=Rd表示一个d维的输入空间,Y={y1,y2,y3,...,yq}Y={y1​,y2​,y3​,...,yq​}表示可能输出的q个类别,多标签任务即在训练集合D={(x1,Y1),(x2,Y2),...,(xm,Ym)}D={(x1​,Y1​),(x2​,Y2​),...,(xm​,Ym​)}上学习一个X到Y的函数,该函数可以衡量x和y的相关性,对于未见过的实例x预测其对应的标签y。

今天介绍的论文是多标签学习经典算法——LDAML,论文链接:https://ieeexplore.ieee.org/abstract/document/8217717 ,如下图所示:

论文提出了一种通用且高效的多标签分类框架——Latent Dirichlet Allocation Multi-Label (LDAML)。该框架通过利用标签间的关联性进行多标签分类。该框架可以应用于大多数当前的多标签分类方法,使其性能得到提升。通过使用LDAML框架,可以显著提升简单方法(如Binary Relevance, BR)的性能,甚至超过某些最新的方法,同时保持较低的时间成本。提出的改进LDAML在某些特殊数据集(如帕金森数据集)上取得了最佳性能。特别是在帕金森数据集上,改进的LDAML框架实现了最优性能,达到了本文的最终目标。该方法能够在未来为医生提供指导和帮助。

算法流程

        与通过查找标签子集或标签链来利用相关性的传统方法不同,LDAML通过发现标签的抽象“主题”来利用相关性。假设为d维特征向量的输入空间,表示q类标号的输出空间。给定多标签训练集,其中为d维特征向量,为对应的标签集。我们可以将每个实例看作一个文档,每个标签看作文档中的一个单词。直观地说,一定有一些抽象的“主题”,期望特定的标签或多或少地出现在实例中,特别是在包含大量相关标签的多标签数据集中。LDAML算法的主要流程分为两步:(1)从训练集中挖掘标签主题;(2)计算主题的离散分布。

从训练集中挖掘标签主题: 首先,我们将LDA引入到训练集d中,每个实例xi表示文档,每个标签表示第i个实例中的第j个标签。然后利用LDA模型生成过程计算实例-主题 θ 的概率分布矩阵,其中 表示第i个实例注入第j主题的概率。
主题的离散分布: 计算实例-主题分布矩阵后,得到每个实例属于每个主题的概率值。为了确定实例确切属于哪个主题,我们需要用离散值0/1来代替概率值。在这里我们使用的离散化方法如下所示:

在这里我们的训练集数据与测试集数据分布相似,因此我们可以假设测试数据集的主题概率分布与训练数据集相同。首先我们对训练集提取出具有标记相关性的k个主题(利用算法1),然后我们使用多标签分类模型MTMT​对训练集的特征-主题进行拟合,然后利用训练好的MT模型对未知标记集合的测试集特征数据生成含有标记相关性的k个主题(这里需要注意的是,MTMT​可以随便选取一个有效的多标签分类模型,文章的重点是利用标签相关性来提高各种多标签学习模型的效率)。

文章在四份数据集上用多种多标签学习分类模型分别加上LDAML算法与其原始模型的分类效果进行对比,实验结果如图所示:

以上实验结果表明,LDAML能够在性能和时间成本之间取得良好的平衡。目前的大多数方法都可以应用于LDAML。我们可以采用目前最先进的方法作为LDAML在原始基础上取得突破的基本方法(base model)。另一方面,唯一额外的时间代价是计算主题概率分布矩阵的小词空间。因此,LDAML的时间成本接近于其基础方法的时间成本。通过采用BR或CC等较弱的方法作为基本方法,可以在较低的时间成本下提高接近实际状态的性能。这些结果表明,LDAML是一个通用的框架,可以为具有标签相关性的多标签问题提供鲁棒且更优的解决方案。 

核心代码

由于改论文代码目前尚未开源,因此在本文中我将给出由本人根据论文算法流程一比一复制的复现代码,代码源文件我将放在附件中,其核心逻辑如下:

#########################伪代码###########################
# 导入必要的库
Import libraries

# 定义函数
Function discretize(theta):
    # 初始化二进制矩阵 YT
    Initialize YT as a zero matrix with the same shape as theta
    For each row i in theta:
        Find the maximum value in row i
        For each column j in row i:
            If the difference between the max value and theta[i][j] is less than 1/K:
                Set YT[i][j] to 1
            Else:
                Set YT[i][j] to 0
    Return YT

Function convert_to_one_hot(data):
    # 获取唯一值和类别数
    Find unique values in data
    Initialize one_hot_encoded as a zero matrix
    For each value in data:
        Find the index of the value in unique values
        Set the corresponding position in one_hot_encoded to 1
    Return one_hot_encoded

Function lda(labels, n):
    # 进行潜在狄利克雷分配(LDA)
    Initialize LDA model with n components
    Fit and transform labels using LDA model
    Discretize the transformed data
    Return the discretized data

Function metric_cal(test, pred):
    # 计算并打印评估指标
    Calculate accuracy, precision, recall, F1 score, and AUC
    Print the calculated metrics

# 主程序
If __name__ == "__main__":
    # 加载数据
    Load data from Excel file
    # 定义标签列和特征
    Define label_cols and features
    Convert features and labels to NumPy arrays
    # 设置主题数
    Set n to 6
    # 对标签进行LDA
    Call lda function to get Y_T
    # 将特征与离散化的标签组合
    Concatenate features and Y_T to get XYT
    # 划分训练集和测试集
    Split XYT and labels into X_train, X_test, y_train, y_test
    # 初始化多标签分类器
    Initialize MT_classifier as RankSVM
    # 从训练集和测试集中提取主题
    Extract yt_train and yt_test from X_train and X_test
    Remove last n columns from X_train and X_test
    # 训练多标签分类器
    Fit MT_classifier using X_train and yt_train
    # 预测测试集的主题
    Predict yt_proba and yt_pred using MT_classifier on X_test
    Convert yt_pred to integer
    # 使用预测的主题扩展训练集和测试集
    Concatenate X_train with yt_train to get X_train_aug
    Concatenate X_test with yt_pred to get X_test_aug
    # 初始化并训练二进制相关性分类器
    Initialize base_classifier as MLPClassifier
    Initialize clf as BinaryRelevance with base_classifier
    Fit clf using X_train_aug and y_train
    # 预测测试集的标签
    Predict y_pred and y_score using clf on X_test_aug
    # 计算评估指标
    Calculate hamming loss, ranking loss, coverage error, and average precision
    Print calculated metrics
    # 对每个标签计算并打印评估指标
    For each label i:
        Extract test and pred for label i
        Call metric_cal function to calculate and print metrics
        Print separator
    Print final separator

在主文件main.py中我复现了LDAML算法的整个流程,并实现了从输入数据到输出评价指标的全过程,在这里默认采用的多标签学习分类起MTMT​和MM是RankSVM和二元回归+深度学习。 

# 定义LIFTClassifier类,继承自BaseEstimator和ClassifierMixin
class LIFTClassifier(BaseEstimator, ClassifierMixin):
    # 初始化函数,接受一个基本分类器作为参数
    def __init__(self, base_classifier=DecisionTreeClassifier()):
        设置base_classifier为传入的参数
        初始化classifiers字典

    # 训练模型函数
    def fit(self, X, y):
        获取标签数量
        遍历每个标签
            对每个标签训练一个分类器
            将训练好的分类器存入classifiers字典
        返回self

    # 预测函数
    def predict(self, X):
        获取标签数量
        初始化预测结果矩阵
        遍历每个标签
            使用对应的分类器进行预测
            将预测结果存入预测结果矩阵
        返回预测结果矩阵

    # 预测概率函数
    def predict_proba(self, X):
        获取标签数量
        初始化概率预测结果矩阵
        遍历每个标签
            使用对应的分类器进行概率预测
            将预测概率结果存入概率预测结果矩阵
        返回概率预测结果矩阵

# 定义MLkNN类
class MLkNN:
    # 初始化函数,接受一个k值作为参数
    def __init__(self, k=3):
        设置k值
        初始化k近邻模型

    # 训练模型函数
    def fit(self, X, y):
        保存训练数据X和y
        使用X训练k近邻模型

    # 预测函数
    def predict(self, X):
        获取样本数量
        初始化预测结果矩阵

        遍历每个样本
            获取样本的k+1个最近邻
            排除样本自身
            计算邻居标签的和
            根据标签和判断最终预测结果
        返回预测结果矩阵

    # 预测概率函数
    def predict_proba(self, X):
        获取样本数量
        初始化概率预测结果矩阵

        遍历每个样本
            获取样本的k+1个最近邻
            排除样本自身
            计算每个标签的概率
        返回概率预测结果矩阵

# 定义RankSVM类,继承自BaseEstimator和ClassifierMixin
class RankSVM(BaseEstimator, ClassifierMixin):
    # 初始化函数,接受参数C, kernel, gamma
    def __init__(self, C=1.0, kernel='rbf', gamma='scale'):
        设置C, kernel, gamma值
        初始化模型列表
        初始化多标签二值化器

    # 训练模型函数
    def fit(self, X, y):
        使用多标签二值化器转换y
        获取标签数量

        遍历每个标签
            将当前标签转换为二值格式
            使用SVM训练二值化后的标签
            将训练好的SVM模型加入模型列表

    # 预测函数
    def predict(self, X):
        初始化预测结果矩阵

        遍历每个SVM模型
            使用模型进行预测
            将预测结果存入预测结果矩阵
        返回预测结果矩阵

    # 预测概率函数
    def predict_proba(self, X):
        初始化概率预测结果矩阵

        遍历每个SVM模型
            使用模型进行概率预测
            将预测概率结果存入概率预测结果矩阵
        返回概率预测结果矩阵

# 定义MultiLabelDecisionTree类
class MultiLabelDecisionTree:
    # 初始化函数,接受参数max_depth, random_state
    def __init__(self, max_depth=None, random_state=None):
        设置max_depth, random_state值
        初始化标签幂集转换器
        初始化决策树分类器

    # 训练模型函数
    def fit(self, X, y):
        使用标签幂集转换器转换y
        使用转换后的y训练决策树分类器

    # 预测概率函数
    def predict_proba(self, X):
        使用决策树分类器进行概率预测
        将预测概率结果转换为原始标签格式
        返回概率预测结果

    # 预测函数
    def predict(self, X):
        使用决策树分类器进行预测
        将预测结果转换为原始标签格式
        返回预测结果

# 定义MLP神经网络类,继承自nn.Module
class MLP(nn.Module):
    # 初始化函数,接受输入大小、隐藏层大小和输出大小作为参数
    def __init__(self, input_size, hidden_size, output_size):
        调用父类的初始化函数
        初始化全连接层1
        初始化ReLU激活函数
        初始化全连接层2
        初始化Sigmoid激活函数

    # 前向传播函数
    def forward(self, x):
        通过全连接层1
        通过ReLU激活函数
        通过全连接层2
        通过Sigmoid激活函数
        返回输出

# 定义BPMLL类,继承自BaseEstimator和ClassifierMixin
class BPMLL(BaseEstimator, ClassifierMixin):
    # 初始化函数,接受参数input_size, hidden_size, output_size, epochs, lr
    def __init__(self, input_size, hidden_size, output_size, epochs=10, lr=0.0001):
        设置输入大小、隐藏层大小、输出大小、训练轮数、学习率
        初始化MLP模型
        初始化优化器
        初始化损失函数

    # 训练模型函数
    def fit(self, X_train, X_val, y_train, y_val):
        将训练数据和验证数据转换为张量
        创建训练数据集和数据加载器

        遍历每个训练轮次
            设置模型为训练模式
            遍历训练数据加载器
                清零梯度
                前向传播
                计算损失
                反向传播
                更新参数

            设置模型为评估模式
            计算验证损失并打印

    # 预测概率函数
    def predict_proba(self, X):
        设置模型为评估模式
        禁用梯度计算
        进行前向传播
        返回预测概率结果

    # 预测函数
    def predict(self, X, threshold=0.5):
        获取预测概率结果
        根据阈值判断最终预测结果
        返回预测结果

# 定义RandomKLabelsetsClassifier类,继承自BaseEstimator和ClassifierMixin
class RandomKLabelsetsClassifier(BaseEstimator, ClassifierMixin):
    # 初始化函数,接受参数base_classifier, labelset_size, model_count
    def __init__(self, base_classifier=None, labelset_size=3, model_count=10):
        设置基本分类器、标签集大小、模型数量
        初始化RakelD模型

    # 训练模型函数
    def fit(self, X, y):
        使用RakelD模型训练数据
        返回self

    # 预测函数
    def predict(self, X):
        使用RakelD模型进行预测
        返回预测结果

    # 预测概率函数
    def predict_proba(self, X):
        使用RakelD模型进行概率预测
        返回概率预测结果

调用LDAML算法的方法放在main.py文件中,首先我们需要将文件路径修改成自己所要使用的数据集路径。这里我使用的文件路径为’./测试数据.xlsx’,供大家一键运行熟悉项目。然后大家需要将自己的标签列名称提取变量label_cols中,用于对数据集划分特征集合与标签集合。 

构建想要的多标签学习分类算法,这里我给大家复现了多种经典的多标签分类器,如LIFT、MlkNN和RankSVM等,并帮大家配置好了参数,大家可以将想要使用的算法对应行的注释删掉即可(MTMT​和MM都是一样)。

设置好这些外在参数后,我们就可以运行代码,主文件将自动调用第三方库和multi_label_learn.py文件中的函数来进行训练和测试。下面是我选取的几种测试指标,分别会输出模型对整体的多标签分类性能指标(Hamming loss、Ranking loss、Coverage error和Average precision)和对单一标签的分类指标(Accuracy、Precision、Recall、F1 Score和AUC)。 

下面是在测试数据集上模型的表现:

最后总结

        多标签学习作为处理现实世界复杂数据的重要方法,其有效性在很大程度上依赖于如何处理标签之间的相关性。本文探讨了基于标签相关性的多标签学习的关键技术和方法。我们首先介绍了不同的标签相关性建模方法,包括基于图结构的方法、注意力机制和迁移学习等。

通过实例和案例分析,我们展示了这些方法如何提高模型对多标签数据的分类精度和泛化能力。特别是在面对标签稀疏性和噪声数据时,这些方法显示出了明显的优势和适应能力。未来的研究方向可能包括更加复杂的标签关联建模、跨领域的标签迁移学习以及与深度学习技术的进一步集成,以应对日益复杂和多样化的数据挑战。

基于标签相关性的多标签学习不仅在学术研究中具有深远意义,也在实际应用中展现了巨大潜力。我们希望本文能够为读者提供一个全面的视角,激发更多关于多标签学习和标签关联性研究的探索与创新。

详细复现过程的项目源码、数据和预训练好的模型可从该文章下方附件获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971784.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

存储届的奥运竞技 | 400层3D NAND最快2025到来~

随着内存巨头之间的高带宽内存 (HBM) 竞争日益激烈,NAND 存储器领域的竞争也在升温。据韩国媒体《etnews》报道,SK 海力士正在研发 400 层 NAND 闪存技术,计划在 2025 年底前准备好这项技术以实现量产。 报道称,SK 海力士目前正在…

AcWing并查集

建议先看这个 Bilibili------------------>图论——并查集(详细版) 其实M 1 2就是把1的祖先改成了2,然后M 3 4就是把3的祖先改成了4,然后查询这两数1,2的祖先是不是同一个,3,4的祖先是不是同一个,1,3的祖先是不是同…

【期货】收盘点评。昨天说的,p2409棕榈油在今天或者周一会走出行情

收盘点评 昨天说的,p2409棕榈油在今天或者周一会走出行情。事实就是如此。震荡了几天了,波幅不大的来回震荡,其实主力是不想震荡的,但是不震荡自己的货和行情走不出来。所以我昨天就说,应该就是这一两天会走出一波小行…

⑤【从0制作自己的ros导航小车:上、下位机通信篇】上、下位机串口DMA通信

从0制作自己的ros导航小车 前言一、准备工作二、下位机端(STM32)三、上位机端(旭日x3派)四、测试 系列文章: ①【从0制作自己的ros导航小车:介绍及准备】 ②【从0制作自己的ros导航小车:下位机篇…

一站式解决方案:打造无缝连接的跨渠道客户服务体验

在当今这个数字化时代,客户与企业之间的互动已不再局限于单一渠道。从社交媒体、在线聊天、电子邮件到电话热线,甚至是实体店面,客户期望能够随时随地、无缝切换地获得一致且高效的服务体验。因此,构建一站式解决方案,…

商城系统审计代码审计

1 开源组件通用性漏洞审计 1.1 fastjson漏洞审计与验证 1.1.1 相关知识 Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java对 象之间相互转换。 Fastjson反序列化漏洞简单来说是出现在将JSON数据反序列化过程中出现的漏洞。 攻击者可以传入一个恶…

算法小白的进阶之路(力扣6~8)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

对象属性值对比(支持复杂对象)

文章目录 前言一、如何对比二、开始编码三、使用结果示例总结 前言 需求如下: 对比两个bean中的内容,返回其中属性的值不一致的完整信息,包括: 属性 新值 旧值 一、如何对比 例如我有一个这的类型: public class Tel {private String name;private String tel; …

学习笔记第十七天

1.链表 1.1链表尾插 void push_back(struct Node *pHead,int n)//尾插 {if(isEmpty(pHead)){push_front(pHead,n);}else{struct Node *p pHead->next; while(p->next !NULL){p p->next;}struct Node *pNew malloc(sizeof(struct Node));p->nextpNew;pNew->n…

C++ bind复杂回调逻辑分析

回调函数基本知识回顾 回调函数是什么 函数指针或者函数对象作为参数传递给另一个函数的机制,当某个事件发生的时候,系统会自动的调用这些函数进行处理事件驱动模型中作用,回调函数则被用于处理I/O事件,通常用来读写异常等事件 bi…

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——2Yolo使用之ONNX模型准备

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——2Yolo使用之ONNX模型准备 ​ 大家好,因为板端BPU环境,可以加速目标检测的速度,所以今天在此先给大家带来如何准备一个模型,下一期会给大家带来如何在板端部…

如何做一个惊艳领导和客户的原型?

在产品开发过程中,原型设计是验证设计想法、提升用户体验的重要环节。Axure作为一款业界领先的原型设计工具,凭借其强大的交互设计和丰富的功能,赢得了全球设计师和开发者的信赖。而Axure的高效交互元件库,则如同一本字典或说明书…

将YOLOv8模型从PyTorch的.pt格式转换为OpenVINO支持的IR格式

OpenVINO是Open Visual Inference & Neural Network Optimization工具包的缩写,是一个用于优化和部署AI推理模型的综合工具包。OpenVINO支持CPU、GPU和NPU设备。 OpenVINO的优势: (1).性能:OpenVINO利用英特尔CPU、集成和独立GPU以及FPGA的强大功能提…

原生IP节点是什么意思?和socks5节点有什么区别?

在了解这两种代理节点前,我们首先要了解:节点是什么? 首先,在电信网络当中,一个节点是一个连接点。表示一个再分发点又或者是一个通信端点。节点的定义依赖于所提及的网络和协议层。一个物理网络节点是一个连接到网络…

深度强化学习:穿越智能迷雾,探索AI新纪元

近年来,深度强化学习成为关注的热点。在自动驾驶、棋牌游戏、分子重排和机器人等领域,计算机程序能够通过强化学习,理解以前被视为超级困难的问题,取得了令人瞩目的成果。在围棋比赛中,AlphaGo接连战胜樊麾、李世石和柯…

使用 SpringBoot + 虚拟线程将服务性能提升几百倍

虚拟线程简介 虚拟线程是 Java 平台的一项创新特性。虚拟线程是一种轻量级的线程实现,它在操作系统层面并不对应真实的内核线程,而是由 JVM 进行管理和调度。这使得可以在不消耗大量系统资源的情况下创建大量的线程,从而能够更高效地处理并发任务。 虚拟线程与普通线程的区…

【数学建模】——【A题 信用风险识别问题】全面解析

目录 1.题目 2.解答分析 问题1:指标筛选 1.1 问题背景 1.2 数据预处理 1.3 特征选择方法 1.4 多重共线性检测 1.5 实现步骤 问题2:信用评分模型 2.1 问题背景 2.2 数据分割 2.3 处理不平衡数据 2.4 模型选择与理由 问题3:模型对…

『 Linux 』线程池与 POSIX 线程的封装编码实现

文章目录 线程池概念线程池的编码实现线程池的测试参考代码 线程的封装使用测试封装后的线程参考代码 线程池概念 池化技术是一种资源管理方法,通过预先创建和管理一组资源以便在需要使用时快速分配这些资源; 线程池是池化技术的一种典型应用; 资源分配 在线程池中预先创建一定…

【python015】常见成熟AI-图像识别场景算法清单(已更新)

1.欢迎点赞、关注、批评、指正,互三走起来,小手动起来! 【python015】常见成熟AI-图像识别场景算法清单及代码【python015】常见成熟AI-图像识别场景算法清单及代码【python015】常见成熟AI-图像识别场景算法清单及代码文章目录 1.背景介绍2.`Python`版数据爬取、解析代码2.…

鸿蒙应用框架开发【画中画效果实现】 UI框架

画中画效果实现 介绍 本示例通过kit.ArkUI、kit.MediaKit等接口,实现了视频播放、手动和自动拉起画中画、画中画窗口控制视频播放和暂停等功能。 效果预览 使用说明 在主界面,可以点击对应视频按钮进入视频播放页面;视频播放页面点击开启…