You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于TensorFlow/Keras实现文本多标签分类?

实现带原因标签的文本分类模型修改方案

1. 修改数据加载逻辑

原加载函数仅处理单标签,现在需要拆分主标签(Approve/Disapprove)和原因标签。根据数据格式,行拆分后长度为2时对应Approve(无原因),长度为3时对应Disapprove+具体原因:

def load_data(file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        lines = f.readlines()
    posts, main_labels, reason_labels = [], [], []
    for line in lines:
        parts = line.strip().split('³')
        post = parts[0]
        posts.append(post)
        if len(parts) == 2:
            # 对应Approve场景
            main_labels.append(parts[1])
            reason_labels.append("Approved")  # 用特殊值标记无原因
        else:
            # 对应Disapprove+原因场景
            main_labels.append(parts[2])
            reason_labels.append(parts[1])
    return posts, main_labels, reason_labels

# 加载数据
train_posts, train_main_labels, train_reason_labels = load_data('mixed_train_data.csv')
test_posts, test_main_labels, test_reason_labels = load_data('mixed_test_data.csv')

2. 构建双标签映射字典

分别为主标签和原因标签创建索引映射,原因标签需包含所有可能的类别(包括Approve对应的"Approved"):

# 主标签映射(保持原逻辑)
main_label_to_index = { 
    'Approve': 0,
    'Disapprove': 1
}

# 收集所有原因标签并创建映射
all_reasons = list(set(train_reason_labels + test_reason_labels))
reason_label_to_index = {reason: idx for idx, reason in enumerate(all_reasons)}

3. 预处理标签数据

将标签转换为模型可接受的索引数组:

import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 文本分词与填充(保持原逻辑)
tokenizer = Tokenizer()
tokenizer.fit_on_texts(train_posts)
max_sequence_length = 7500

# 训练数据
sequences = tokenizer.texts_to_sequences(train_posts)
X_train = pad_sequences(sequences, maxlen=max_sequence_length)
y_train_main = np.array([main_label_to_index[label] for label in train_main_labels])
y_train_reason = np.array([reason_label_to_index[label] for label in train_reason_labels])

# 测试数据
test_sequences = tokenizer.texts_to_sequences(test_posts)
X_test = pad_sequences(test_sequences, maxlen=max_sequence_length)
y_test_main = np.array([main_label_to_index[label] for label in test_main_labels])
y_test_reason = np.array([reason_label_to_index[label] for label in test_reason_labels])

4. 重构模型为多输出结构

使用Keras Functional API构建共享特征提取层的双输出模型:一个分支预测主标签,另一个分支预测原因标签:

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Embedding, Flatten, Dense

# 输入层
input_layer = Input(shape=(max_sequence_length,))
# 共享特征提取层
embedding = Embedding(input_dim=len(tokenizer.word_index)+1, output_dim=50)(input_layer)  # +1是因为Tokenizer从1开始索引
flatten = Flatten()(embedding)
dense_shared = Dense(128, activation='relu')(flatten)

# 主标签输出分支
main_output = Dense(len(main_label_to_index), activation='softmax', name='main_output')(dense_shared)
# 原因标签输出分支
reason_output = Dense(len(reason_label_to_index), activation='softmax', name='reason_output')(dense_shared)

# 构建模型
model = Model(inputs=input_layer, outputs=[main_output, reason_output])

5. 编译与训练模型

针对双输出设置损失函数和评估指标,训练时传入两组标签数据:

from tensorflow.keras.optimizers import Adam

# 编译模型
learning_rate = 0.001
model.compile(
    optimizer=Adam(learning_rate=learning_rate),
    loss={
        'main_output': 'sparse_categorical_crossentropy',
        'reason_output': 'sparse_categorical_crossentropy'
    },
    metrics={
        'main_output': 'accuracy',
        'reason_output': 'accuracy'
    }
)

# 训练模型(假设你已定义checkpoint_callback)
model.fit(
    X_train,
    {'main_output': y_train_main, 'reason_output': y_train_reason},
    epochs=100,
    batch_size=32,
    validation_data=(X_test, {'main_output': y_test_main, 'reason_output': y_test_reason}),
    callbacks=[checkpoint_callback]
)

预测示例

预测时可同时得到主标签和原因标签,再转换回原始文本:

# 反向映射字典
index_to_main_label = {v: k for k, v in main_label_to_index.items()}
index_to_reason_label = {v: k for k, v in reason_label_to_index.items()}

# 预测单条文本
sample_post = ["你真蠢"]
sample_seq = tokenizer.texts_to_sequences(sample_post)
sample_pad = pad_sequences(sample_seq, maxlen=max_sequence_length)
main_pred, reason_pred = model.predict(sample_pad)

# 获取预测结果
pred_main_label = index_to_main_label[np.argmax(main_pred)]
pred_reason_label = index_to_reason_label[np.argmax(reason_pred)]
print(f"预测结果:{pred_main_label} + {pred_reason_label}")

内容的提问来源于stack exchange,提问作者Menrion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:40