多标签文本分类任务中如何用全部标签训练统一模型实现预测
问题判断
你的判断完全正确:当前代码通过循环逐标签拟合模型,属于手动实现的「单标签二分类叠加」策略,每个标签对应独立的逻辑回归模型,不会学习不同标签之间的关联特征,也无法利用标签组合的共现信息。
失败原因说明
你之前使用MultiLabelBinarizer/LabelBinarizer失败,是因为你的标签已经是0/1编码的哑变量格式,不需要再做二值化转换,直接把4个标签列拼接为二维数组作为多标签任务的标注输入即可。
解决方案
要训练兼顾标签组合特征的统一模型,推荐使用scikit-learn提供的ClassifierChain(分类器链):它会按顺序训练标签,前序标签的预测结果会作为后续标签训练的输入特征,能够捕捉标签之间的共现依赖关系,比独立训练标签的效果更好。
完整修改后代码
import numpy as np from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline # 导入多标签分类所需工具 from sklearn.multioutput import ClassifierChain from sklearn.metrics import hamming_loss, accuracy_score # 导入数据 df = import_data("product_data") # 仅保留相关列 df = df.loc[:,['text','TV','Internet','Mobil','Fastnet']] # 统计每条文本对应的标签数量 sum_column = df["TV"] + df["Internet"] + df["Mobil"] + df["Fastnet"] df["label_sum"] = sum_column # 移除无标签的文本数据 df.drop(df[df['label_sum'] == 0].index, inplace = True) # 定义标签列 categories = ['TV','Internet','Mobil','Fastnet'] # 拆分数据集 train, test = train_test_split(df, random_state=42, test_size=0.2, shuffle=True) X_train = train.text X_test = test.text # 构造多标签二维标注数组 y_train = train[categories].values y_test = test[categories].values # 模型管道:用分类器Chain包装逻辑回归,自动学习标签关联 LogReg_pipeline = Pipeline([ ('tfidf', TfidfVectorizer(analyzer = 'word', max_df=0.20)), ('clf', ClassifierChain( LogisticRegression(solver='lbfgs', class_weight = 'balanced', n_jobs=-1), order=categories # 可自定义标签学习顺序,默认按输入顺序 )), ]) # 直接拟合多标签标注,无需循环 LogReg_pipeline.fit(X_train, y_train) prediction = LogReg_pipeline.predict(X_test) # 多标签评估 print('全局子集准确率(所有标签都预测正确才算对):{}'.format(accuracy_score(y_test, prediction))) print('汉明损失(单个标签预测错误的平均比例,越低越好):{}'.format(hamming_loss(y_test, prediction)))
可选方案
如果你不需要标签关联学习,只是想简化代码不用写循环,可以把ClassifierChain替换为MultiOutputClassifier,效果和你当前逐标签训练的结果一致,只是代码更简洁。
内容的提问来源于stack exchange,提问作者hideonbush
相关产品推荐
相关产品推荐

