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

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

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

目录

概述

算法流程

核心代码

最后总结


概述

帕金森病是一种使人虚弱的慢性神经系统疾病。传统中医(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是一个通用的框架,可以为具有标签相关性的多标签问题提供鲁棒且更优的解决方案。

核心代码

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

python 复制代码
#########################伪代码###########################
# 导入必要的库
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和二元回归+深度学习。

python 复制代码
# 定义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)。

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

最后总结

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

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

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

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

相关推荐
NAGNIP7 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab8 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab8 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP12 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年12 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼12 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS12 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区13 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈13 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang14 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx