多标签分类涉及预测零个或多个类标签。
与类标签互斥的常规分类任务不同,多标签分类需要专门的机器学习算法来支持预测多个互不排斥的类或“标签”。
深度学习神经网络是原生支持多标签分类问题的算法示例。可以使用 Keras 深度学习库轻松定义和评估多标签分类任务的神经网络模型。
在本教程中,您将学习如何为多标签分类开发深度学习模型。
完成本教程后,您将了解:
- 多标签分类是一项预测建模任务,涉及预测零个或多个互不排斥的类标签。
- 神经网络模型可以配置为支持多标签分类任务。
- 如何评估用于多标签分类的神经网络以及如何为新数据进行预测。
让我们开始吧。

深度学习的多标签分类
照片作者 Trevor Marron,部分权利保留。 Trevor Marron。
教程概述
本教程分为三个部分;它们是:
- 多标签分类
- 用于多标签的神经网络
- 用于多标签分类的神经网络
多标签分类
分类是涉及给定某些输入输出类标签的预测建模问题。
它不同于涉及预测数值的回归任务。
通常,分类任务涉及预测单个标签。或者,它可能涉及预测两个或多个类标签的概率。在这些情况下,类是互斥的,这意味着分类任务假设输入仅属于一个类。
有些分类任务需要预测多个类标签。这意味着类标签或类成员资格不是互斥的。这些任务被称为**多标签分类**,简称多标签分类。
在多标签分类中,每个输入样本需要零个或多个标签作为输出,并且输出是同时需要的。假设输出标签是输入的函数。
我们可以使用 scikit-learn 库中的 make_multilabel_classification() 函数来创建合成多标签分类数据集。
我们的数据集将有 1,000 个样本,包含 10 个输入特征。该数据集将为每个样本提供三个类标签输出,每个类将有一个或两个值(0 或 1,例如存在或不存在)。
创建和汇总合成多标签分类数据集的完整示例列在下面。
1 2 3 4 5 6 7 8 9 |
# 多标签分类任务示例 from sklearn.datasets import make_multilabel_classification # 定义数据集 X, y = make_multilabel_classification(n_samples=1000, n_features=10, n_classes=3, n_labels=2, random_state=1) # 总结数据集形状 print(X.shape, y.shape) # 汇总前几个示例 for i in range(10): print(X[i], y[i]) |
运行该示例将创建数据集并汇总输入和输出元素的形状。
如预期所示,有 1,000 个样本,每个样本有 10 个输入特征和三个输出特征。
汇总了输入和输出的前 10 行,我们可以看到此数据集的所有输入都是数字,并且输出类标签对于三个类标签中的每一个都具有 0 或 1 的值。
1 2 3 4 5 6 7 8 9 10 11 12 |
(1000, 10) (1000, 3) [ 3. 3. 6. 7. 8. 2. 11. 11. 1. 3.] [1 1 0] [7. 6. 4. 4. 6. 8. 3. 4. 6. 4.] [0 0 0] [ 5. 5. 13. 7. 6. 3. 6. 11. 4. 2.] [1 1 0] [1. 1. 5. 5. 7. 3. 4. 6. 4. 4.] [1 1 1] [ 4. 2. 3. 13. 7. 2. 4. 12. 1. 7.] [0 1 0] [ 4. 3. 3. 2. 5. 2. 3. 7. 2. 10.] [0 0 0] [ 3. 3. 3. 11. 6. 3. 4. 14. 1. 3.] [0 1 0] [ 2. 1. 7. 8. 4. 5. 10. 4. 6. 6.] [1 1 1] [ 5. 1. 9. 5. 3. 4. 11. 8. 1. 8.] [1 1 1] [ 2. 11. 7. 6. 2. 2. 9. 11. 9. 3.] [1 1 1] |
接下来,让我们看看如何为多标签分类任务开发神经网络模型。
用于多标签的神经网络
一些机器学习算法原生支持多标签分类。
神经网络模型可以配置为支持多标签分类,并且根据分类任务的具体情况可以表现良好。
通过将问题中的目标标签数指定为输出层中的节点数,神经网络可以直接支持多标签分类。例如,一个有三个输出标签(类)的任务将需要一个输出层中具有三个节点的神经网络。
输出层中的每个节点都必须使用 sigmoid 激活。这将预测标签的类成员资格概率,一个介于 0 和 1 之间的值。最后,模型必须使用 二元交叉熵损失函数进行拟合。
总之,要为多标签分类配置神经网络模型,具体细节是:
- 输出层中的节点数与标签数匹配。
- 输出层中每个节点使用 Sigmoid 激活。
- 二元交叉熵损失函数。
我们可以使用 Keras 深度学习库来演示这一点。
我们将为上一节定义的多标签分类任务定义一个多层感知机(MLP)模型。
每个样本有 10 个输入和三个输出;因此,网络需要一个输入层,该输入层在第一个隐藏层通过“input_dim”参数指定 10 个输入,并在输出层中有三个节点。
我们将使用流行的 ReLU 激活函数作为隐藏层。隐藏层有 20 个节点,这些节点是通过反复试验确定的。我们将使用二元交叉熵损失和随机梯度下降的 Adam 版本来拟合模型。
用于多标签分类的网络定义列在下面。
1 2 3 4 5 |
# 定义模型 model = Sequential() model.add(Dense(20, input_dim=n_inputs, kernel_initializer='he_uniform', activation='relu')) model.add(Dense(n_outputs, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam') |
您可能希望为自己的多标签分类任务调整此模型,因此我们可以创建一个函数来定义并返回模型,其中输入和输出变量的数量作为参数提供。
1 2 3 4 5 6 7 |
# 获取模型 def get_model(n_inputs, n_outputs): model = Sequential() model.add(Dense(20, input_dim=n_inputs, kernel_initializer='he_uniform', activation='relu')) model.add(Dense(n_outputs, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam') return model |
现在我们已经熟悉了如何为多标签分类定义 MLP,让我们探讨一下如何评估此模型。
用于多标签分类的神经网络
如果数据集很小,最好反复在同一数据集上评估神经网络模型,并报告多次运行的平均性能。
这是因为学习算法的随机性。
此外,当对新数据进行预测时,使用 k 折交叉验证而不是数据集的训练/测试拆分来获得无偏的模型性能估计是一个好习惯。同样,前提是数据量不是太大,以至于该过程可以在合理的时间内完成。
考虑到这一点,我们将使用重复的 k 折交叉验证(10 折,3 次重复)来评估多输出回归任务的 MLP 模型。
MLP 模型默认会预测每个类标签的概率。这意味着它将为每个样本预测三个概率。这些可以通过将值四舍五入到 0 或 1 来转换为清晰的类标签。然后,我们可以计算清晰类标签的分类准确率。
1 2 3 4 5 6 7 |
... # 在测试集上进行预测 yhat = model.predict(X_test) # 将概率四舍五入到类标签 yhat = yhat.round() # 计算准确率 acc = accuracy_score(y_test, yhat) |
收集分数,可以通过报告所有重复和交叉验证折叠的平均值和标准差来汇总。
下面的 evaluate_model() 函数接收数据集,评估模型,并返回评估分数的列表,在本例中是准确率分数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 使用重复k折交叉验证评估模型 def evaluate_model(X, y): results = list() n_inputs, n_outputs = X.shape[1], y.shape[1] # 定义评估过程 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 枚举折叠 for train_ix, test_ix in cv.split(X): # 准备数据 X_train, X_test = X[train_ix], X[test_ix] y_train, y_test = y[train_ix], y[test_ix] # 定义模型 model = get_model(n_inputs, n_outputs) # 拟合模型 model.fit(X_train, y_train, verbose=0, epochs=100) # 在测试集上进行预测 yhat = model.predict(X_test) # 将概率四舍五入到类标签 yhat = yhat.round() # 计算准确率 acc = accuracy_score(y_test, yhat) # 存储结果 print('>%.3f' % acc) results.append(acc) return results |
我们可以加载数据集并评估模型,然后报告平均性能。
将这些结合起来,完整的示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# 用于多标签分类的 MLP from numpy import mean from numpy import std from sklearn.datasets import make_multilabel_classification from sklearn.model_selection import RepeatedKFold from keras.models import Sequential from keras.layers import Dense from sklearn.metrics import accuracy_score # 获取数据集 定义 获取_数据集(): X, y = make_multilabel_classification(n_samples=1000, n_features=10, n_classes=3, n_labels=2, random_state=1) 返回 X, y # 获取模型 def get_model(n_inputs, n_outputs): model = Sequential() model.add(Dense(20, input_dim=n_inputs, kernel_initializer='he_uniform', activation='relu')) model.add(Dense(n_outputs, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam') return model # 使用重复k折交叉验证评估模型 def evaluate_model(X, y): results = list() n_inputs, n_outputs = X.shape[1], y.shape[1] # 定义评估过程 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 枚举折叠 for train_ix, test_ix in cv.split(X): # 准备数据 X_train, X_test = X[train_ix], X[test_ix] y_train, y_test = y[train_ix], y[test_ix] # 定义模型 model = get_model(n_inputs, n_outputs) # 拟合模型 model.fit(X_train, y_train, verbose=0, epochs=100) # 在测试集上进行预测 yhat = model.predict(X_test) # 将概率四舍五入到类标签 yhat = yhat.round() # 计算准确率 acc = accuracy_score(y_test, yhat) # 存储结果 print('>%.3f' % acc) results.append(acc) return results # 加载数据集 X, y = get_dataset() # 评估模型 results = evaluate_model(X, y) # 总结性能 print('Accuracy: %.3f (%.3f)' % (mean(results), std(results))) |
运行该示例将报告每个折叠和每个重复的分类准确率,以了解评估进度。
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行几次示例并比较平均结果。
最后,报告了平均和标准差准确率。在这种情况下,模型实现了约 81.2% 的准确率。
您可以使用此代码作为模板,在您自己的多标签分类任务上评估 MLP 模型。模型中的节点数和层数可以轻松调整并根据您数据集的复杂性进行定制。
1 2 3 4 5 6 7 |
... >0.780 >0.820 >0.790 >0.810 >0.840 准确率:0.812 (0.032) |
选择模型配置后,我们可以使用它来拟合整个数据集上的最终模型,并为新数据进行预测。
下面的示例通过首先在整个多标签分类数据集上拟合 MLP 模型,然后调用保存模型的 predict() 函数来预测新数据行来演示这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# 使用 MLP 对多标签分类进行预测 from numpy import asarray from sklearn.datasets import make_multilabel_classification from keras.models import Sequential from keras.layers import Dense # 获取数据集 定义 获取_数据集(): X, y = make_multilabel_classification(n_samples=1000, n_features=10, n_classes=3, n_labels=2, random_state=1) 返回 X, y # 获取模型 def get_model(n_inputs, n_outputs): model = Sequential() model.add(Dense(20, input_dim=n_inputs, kernel_initializer='he_uniform', activation='relu')) model.add(Dense(n_outputs, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam') return model # 加载数据集 X, y = get_dataset() n_inputs, n_outputs = X.shape[1], y.shape[1] # 获取模型 model = get_model(n_inputs, n_outputs) # 在所有数据上拟合模型 model.fit(X, y, verbose=0, epochs=100) # 为新数据进行预测 row = [3, 3, 6, 7, 8, 2, 11, 11, 1, 3] newX = asarray([row]) yhat = model.predict(newX) print('Predicted: %s' % yhat[0]) |
运行该示例将拟合模型并为新行进行预测。如预期所示,预测包含多标签分类任务所需的三个输出变量:每个类标签的概率。
1 |
预测:[0.9998627 0.9849341 0.00208042] |
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
- 多标签分类,维基百科.
- sklearn.datasets.make_multilabel_classification API.
- Keras 主页.
- sklearn.model_selection.RepeatedStratifiedKFold API.
总结
在本教程中,您学习了如何为多标签分类开发深度学习模型。
具体来说,你学到了:
- 多标签分类是一项预测建模任务,涉及预测零个或多个互不排斥的类标签。
- 神经网络模型可以配置为支持多标签分类任务。
- 如何评估用于多标签分类的神经网络以及如何为新数据进行预测。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
嗨,Jason,
如何处理一个或多个标签严重不平衡的情况?
我们可能有高准确率,但 F1 分数对那些标签会很低。
使用基于标签的宏平均或微平均 F 分数,而不是准确率或汉明损失进行评估。进行每标签性能分析是一个好主意,这在多标签文献中并不常见。
好建议。
这篇文章很棒
谢谢!
Jason 先生,您是一位慈善家
上帝保佑您
感谢 nasiri 的支持和反馈!我们非常感激,并祝您在机器学习之旅中一切顺利!
即使是 f1-score 可能也无法显示模型的实际状态。所以,我认为最好也使用精确率和召回率。
我最近正在做一个关于“SafeCity: 故事分类”(一个多标签问题)的项目,我使用以下指标来评估我的模型。
1. 准确率(精确匹配):它不是一个很好的模型评判指标,但被用于一篇研究论文。
2. macro f1-score,以及使用 Classification report 的每标签 f1-score。
3. macro recall,以及使用 Classification report 的每标签 recall。
4. macro precision(你也可以使用 'micro',但有一个问题,你可以去谷歌搜索一下)
5. Hamming loss
6. Hamming accuracy(不是官方指标,代码为自写,没有 sklearn/tf 支持)
7. 每标签 AUC
最后,我使用以上所有七个指标来评判我的模型,但我更喜欢每标签的精确率和召回率。
最后一点,我评估我的模型在训练数据上的表现,以查看是否存在过拟合。
我希望这能帮助你评判你的多标签分类模型。
谢谢!
你有你的代码链接吗?
也许你可以尝试类别加权,例如成本敏感学习。
https://machinelearning.org.cn/cost-sensitive-neural-network-for-imbalanced-classification/
Pytorch 具有这种位置权重,应该会有帮助。我目前也面临着同样的问题。
你好,
这真是一篇信息量非常大的文章,感谢分享这篇有用的帖子。
不客气。很高兴听到你这么说!
您真是个宝藏!很棒的文章!
谢谢。
对于我们会使用 train/test/validate 的大型数据集,我们仍然会使用平均准确率来评估吗?
不,你会直接从你的测试集中估算。
嗨,Jason,
解释得很好。
谢谢你
不客气。
Jason, 我很欣赏你的教程。
谢谢!
在 Anaconda 上安装时遇到一些问题,我的解决方案是 Autokeras 网站上的说明。要安装该软件包,请使用如下的 pip 安装:
pip3 install git+https://github.com/keras-team/keras-tuner.git@1.0.2rc1
pip3 install autokeras
感谢 Jason 的这篇文档,我周末会以学生折扣购买这本书。
很棒的建议,感谢分享!
嗨,Jason,
Random Forest 或 XGBoost 是否可以用于类似的多标签分类问题?这种方法有多可行?您是否计划在不久的将来发表此类文章?
我不太确定,抱歉。也许可以尝试一下看看。
你好 Saad,我认为如果你能转化问题(使用二元相关法),你就可以使用分类链来进行多标签分类(可以以 RF/DT、KNN、朴素贝叶斯等为基础分类器)。
分类器的选择取决于你想如何利用(捕捉)多个标签之间的相关性。
这绝对是一个很棒的教程。
隐藏层有 20 个节点。选择节点数量是否有任何特定逻辑,取决于输入维度(在本例中为 10)?
谢谢!
没有,这是通过试错确定的。
有一些模糊的理解。
如果你有大量数据,那么你可以创建一个复杂的模型,即许多隐藏层和大量神经元,但这并非强制。但模型应该复杂到足以从大量数据中学习,否则你会欠拟合。
如果你数据量少,则创建浅层网络。否则,你的模型会过拟合训练数据,意味着它会记住所有权重而不是从你的训练数据中学习。
希望这会有所帮助。
嗨,Jason,
在 MultiLabel 中,如果预测结果是
array([[0.4774732 , 0.04919493, 0.47333184]], dtype=float32)
并且数据有 3 个类别,例如 ‘0’、‘1’、‘2’
我们如何知道哪个类别的概率属于哪个类别?
谢谢你
另外,如何获取 keras 函数式模型的 model.classes_?对于多标签,我们会对 y 值进行 to_categorical,例如
y_train = tensorflow.keras.utils.to_categorical(y_train, num_classes= 3)
y_valid = tensorflow.keras.utils.to_categorical(y_valid, num_classes= 3)
y_train 的列名是否会按预测顺序返回类别?
你可以调用 model.predict_classes(),更多信息在这里。
https://machinelearning.org.cn/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/
索引 0 始终是类别 0,索引 1 始终是类别 1,依此类推。
你可以使用 argmax 作为快捷方式。
https://machinelearning.org.cn/argmax-in-machine-learning/
谢谢 Jason
这是否也意味着
array([[0.4774732 , 0.04919493, 0.47333184]], dtype=float32)
索引 0 属于类别 0,索引 1 属于类别 1,依此类推?
是的。
因为 model.predict_classes(),argmax 会返回最大概率的类别?
是的。
predict_classes() 会为您执行 argmax。
尊敬的Jason博士,
预测的 yhat[0].round() 返回
* 上面的例子是在预测多变量输出吗?
谢谢你,
悉尼的Anthony
多标签输出。我猜你可以称之为多变量,但我不会使用这个词。
尊敬的Jason博士,
谢谢你,
悉尼的Anthony
尊敬的Jason博士,
考虑到存在仅包含 0 或 1 的多标签输出,是否有输出属于整数集合的多标签回归模型?
我说的整数集合是指像 0、1、2、3、4 这样的数字?而不是 0、1、1.39、2.141、3.142、4.23?我的意思是多标签整数输出类别。
谢谢你,
悉尼的Anthony
如果你需要模型预测整数,你可以通过四舍五入/缩放模型的输出来满足你的需求。
尊敬的Jason博士,
谢谢你的回复。
您能否详细说明我可以生成什么样的多变量 Y 模型?
谢谢你,
悉尼的Anthony
用于回归的 MLP 可以输出 0-1 之间的实数值,这些值可以按所需范围缩放并四舍五入。
训练数据中的目标值必须以相同的方式准备。
尊敬的Jason博士,
在 #define model 中
* 我们知道 '20' 表示第一个隐藏层中有 20 个神经元。
* 有没有一个经验法则来确定隐藏层中有多少个神经元?
谢谢你,
悉尼的Anthony
好问题,没有,请看这里。
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
尊敬的Jason博士,
感谢回复,将我引导至关于添加层和节点的 FAQ。
我有一个 FAQ 中未解决的进一步问题。
即使添加层和节点,评估分数或准确率分数是否会变得更差?
换句话说,在添加更多层和/或节点时,评估或准确率分数是否会达到峰值,然后随着添加更多层和/或节点而下降?
谢谢你,
悉尼的Anthony
是的,添加层和节点在某个时候导致性能下降是很常见的,特别是如果你不调整学习算法的超参数。
Jason博士,您好,
解释得非常好,谢谢。
请问,我有一个多标签分类数据集,有很多标签,标签数量为 1385。
当我在我的数据集上使用这个模型时
训练数据的准确率为 15,而
测试数据的准确率为零。
我该如何处理这个拥有如此多标签的多标签数据集?
非常感谢。
谢谢。
好问题,这可能给你一些想法。
https://machinelearning.org.cn/faq/single-faq/how-do-i-handle-a-large-number-of-categories
嗨,Jason,
解释得很好!
只想了解如何实现以下目标——
我的数据如下所示:
订单号 Item ID Item Type Box Size
X A APP C1
B APP C2
C FTW C3
D FTW
Y B HAZ C1
C FTW C2
E APP C3
基本上,我有可以包含多个产品的订单。一个订单中的产品可以根据某些参数分组到一个或多个箱子中。我的算法应该能够根据历史数据预测哪些产品可以放入什么尺寸的箱子。有没有办法实现这一点?
这可能会给你一些想法(将站点替换为产品)。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
Jason,
以一个二元分类问题为例,即图像中是否有人。这里输出显然是互斥的。那么为什么我们还要为此类问题使用 sigmoid 函数呢?
对于二元分类问题,sigmoid 和 softmax 不是一样的吗?
Sigmoid 用于二元分类。
Softmax 用于多类别分类。
这里我们进行的是“多标签”分类,这就像多个二元分类问题。所以我们使用 sigmoid。
我在这里陈述的问题是,它的输出是互斥的,也就是说,图像中可能有人,也可能没有人。那么为什么在这个二元问题中我应该使用 sigmoid 而不是 softmax?
抱歉,我不明白你的问题。你能否重新表述或详细说明?
分类标签是互斥的。
在多标签分类中,它们不是互斥的。
看这里
https://machinelearning.org.cn/types-of-classification-in-machine-learning/
我想问的是,像图像中是否有人的二元分类问题,其输出是互斥的。一个图像要么有新人,要么没有新人。为什么我们要在这里使用 sigmoid?Sigmoid 的总和不为一。因此,概率(图像中有新人)+ 概率(图像中没有新人)不等于 1。也许应该为二元分类问题使用 softmax?
你的问题可能是一个互斥分类问题。
我们在上面使用 sigmoid 是因为它是一种不同的分类问题,在这种问题中,标签**不**互斥。
这样更清楚了吗?
那么对于标签互斥的二元分类问题,我们应该使用 softmax 而不是 sigmoid 吗?
不,互斥的二元分类有一个单一的输出,应该使用 sigmoid。
Softmax 只用于两个以上的互斥类别。
谢谢 Jason
不客气。
非常好的教程。谢谢。我运行了它并进行了一些修改实验,尝试了加权 F1,效果比准确率好(特征和类别翻倍 — 我希望增加到 x10 类别)。关于类别并非完全独立,有什么建议吗?
干得好!
或许值得回顾一下文献,看看大量标签是如何支持的。
如果它们不是独立的,那么也许可以使用多遍/分层的方法。
嗨,Jason,
在 MultiLabel 中,如果预测结果是
array([[0.4774732 , 0.04919493, 0.47333184]], dtype=float32)
并且数据有 3 个类别,例如 'credit'、'debit'、'loan'。
我们如何知道哪个类别的概率属于哪个类别?
谢谢你
多标签类别不是互斥的——也就是说,我们可以将多个标签应用于给定的示例。
截止点是 0.5。你可以调用 model.predict_classes() 来获取标签而不是概率,或者调用 round()。
Jason 你好,在这篇教程中,是否可以使用时间序列作为数据集来对未来时间步进行分类?我的意思是,是否有其他需要考虑的因素?
是的,请参阅这里的时间序列分类的 HAR 示例。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
亲爱的 Jason,
感谢这篇教程。您能否提供一些建议,如何处理训练样本的局部/缺失标签?
带有缺失标签/目标的样本不能用于训练。
你好,你能帮我解决我的研究问题吗?我正在对研究论文 (RP) 的文本内容进行多标签分类,而 RP 内容非常大,并且有很多 RP 可能所属的类别,你能为多标签大规模文本内容分类问题推荐一个模型吗?
我认为深度学习语言模型将在该应用中发挥重要作用。
你好 Jason,感谢这篇教程。
那么,多标签多类别分类呢?也就是说,当每个类别有多个标签选项时?如何处理这样的任务?
好问题,我希望将来能写一篇关于这个主题的文章。
你已经写了吗?
你好 Joseph… 以下资源涵盖了深度学习回归和分类。
https://machinelearning.org.cn/deep-learning-with-python/
博士您好,
很棒的文章,解释得很详细……你能告诉我你用了什么版本的 keras、tensorflow 和 python 来写这段代码吗?
谢谢。
它适用于最新版本的 Keras 和 TensorFlow,但我预计它适用于所有版本(如果不是全部的话)。
我该如何准备多标签分类的数据?
好问题。
创建一个长度为标签/类别数量的目标向量,然后如果一个样本存在该标签,则标记为 1,否则标记为 0。
举个例子!
感谢您的建议。
你好 Jason,很棒的文章,很高兴看到你回答每个人的问题。
我正在做我的学期项目“指纹预测”。我拥有 366 个单独的类别和约 3000 个图像数据集。我想构建一个模型,该模型将接收两个输入指纹图像,并预测它们“在多大程度上相同”。
如果我用这366个类别多分类数据集来训练我的模型,它将无法检测或比较数据集之外的任何新指纹,对吗?
你有什么建议吗?
听起来你想要一个两幅图像之间的距离度量。
另一种方法是将其视为二元分类——例如,这两幅图像是同一枚指纹的可能性有多大。
也许可以尝试一下,看看什么效果好?
也许可以查阅文献,看看有什么常用的方法?
也许可以查看相似的领域(如人脸识别),看看是否可以使用类似的方法?
非常感谢!我会看看的!
不客气。
感谢 Jason 的这篇文章。
我对学习使用其他多标签分类算法感兴趣,例如基于决策树的模型,用于对结构化表格数据进行预测(例如,表格医疗保健数据,主要包含用于预测多种慢性病风险的分类或定量值)。我一直在你的博客上搜索类似的例子。你能推荐一些好的学习资源吗?感谢你的帮助!
抱歉,我没有如此具体的例子。也许你可以尝试直接将决策树应用于你的问题?
你好,
我想为给定的评论获取多个标签。在这种情况下,我的输入数据是文本数据。所以在你的模型中,你使用了数值数据作为输入数据。那么我可以使用这种模型来将评论分类成多个标签吗?
是的,也许可以为你的输入数据进行调整。
嗨 Jason,我正在做一个AI营养师的项目,我需要根据年龄、BMI、性别和疾病来预测一系列食物。
我有超过6个因变量,应该应用哪种算法?多输出分类还是多标签分类?
并且请推荐一些我可以获得帮助的来源。谢谢!
我建议测试一系列不同的算法,以发现什么对你的数据集有效或最好。
嗨,Jason,
感谢您的辛勤工作!这个网站是我最依赖的,可以清楚地理解机器学习概念。
我有一个问题——我有大约200万行数据,有10K个标签,以ID的形式出现,例如1534、67322、592874等。基于文本变量,我需要预测这些数字。你会建议回归(向量化后)还是分类来解决这个问题?
我尝试了使用Keras的MLP进行分类,但在应用`to_categorical()`对高基数标签(在标签编码值上)时遇到了问题——
“MemoryError: Unable to allocate 247. GiB for an array with shape (257483, 257483) and data type int32”
任何提示都将不胜感激(我是在谷歌搜索了很长时间后才联系你的)。
谢谢。
也许你可以对问题的几种不同表述进行原型设计,并找出最适合你的项目目标或利益相关者需求的方法。
关于大型数据集
https://machinelearning.org.cn/faq/single-faq/how-to-i-work-with-a-very-large-dataset
嗨,Jason,
如果每个类别的真实标签不是二元的(多标签多分类),那么 sigmoid 就不是合适的选项。你有什么建议来处理这个问题吗?
哎哟。
也许可以将多类标签进行独热编码,例如,将所有类标签进行反规范化。
亲爱的Jason
谢谢回复。我不太明白你的回答。我将gt-labels转换为类别,以便获得独热编码。此时,我将得到一个3D的标签数组(例如,(5000, 4, 3),其中行是实例,列是类标签,第三个维度代表类别标签(3)。问题是,当我尝试训练模型时,出现了 logits 和标签形状不匹配的问题((None, 4) vs (None, 4, 3))。我应该单独训练每个类标签,这样会忽略类标签之间的相关性,还是有其他解决方案?
谢谢你
你可能需要做一些实验,我以前没试过。
也许你可以为每个类标签使用不同的输出模型?
阅读愉快!
我正在做一个非常类似的问题,我有20个类别(10种形状,10种颜色),每个样本都有一个真实标签,并且已知其所属的形状和颜色——所以是[1,0,1..等]。sigmoid和binary_crossentropy方法效果很好——我为各个子类别生成一个混淆矩阵(仅形状的cm和仅颜色的cm),这让我对每个类别的分类有了更好的了解——但有一件事我在文献中找不到,那就是训练后如何处理这个数据集的指标——即FPR、TPR、灵敏度等。
将混淆矩阵像上面那样拆分,然后分别计算每个类别的FPR、TPR、召回率等(对于仅形状和仅颜色),这是否有效?鉴于标签现在是二元的,我不认为这种方法本身无效——我的想法是,有两个主要子类别,所以我想了解它在每个类别上的表现——例如,整体的FPR等方法可能会掩盖它在颜色识别方面比形状识别做得好多少……但我不知道是否有任何统计学上的“法则”反对这样做?
谢谢!
这些指标只有在你可以将类别分成“阳性”和“阴性”病例时才有意义(例如,癌症和无癌症等)。如果不是这样,那么这些指标就没有意义。
好的,谢谢——那么年龄和器官是否符合条件呢?所以如果我有5个器官,我也知道年龄,我能看到基于器官单独和然后年龄单独的效果如何吗?这是否也符合你使用的类比?——也就是说,在器官内,它将是——阳性器官相对于所有其他器官……年龄也是如此……?
谢谢!
也许可以试试。
深度学习是每个工作中最重要的一词。任何人都可以通过深度学习来发展业务。无论如何,感谢分享这样的谷歌文章。
谢谢。
谢谢 Jason,这是一个很棒的教程!我现在正在使用 Keras 来实现一个多标签分类模型。数据标签是8位,例如 [0,1,0,0,1,0,1,1]。这意味着标签总共有 2^8=256 种组合。现在我只收集了数据中部分标签(约20个)用于模型训练。虽然模型在已见数据上表现良好(95%),但对于具有未见标签(训练中未出现)的数据表现很差(30%)。我想知道如何提高模型的性能?还是我必须用尽可能多的不同标签的数据来训练这个模型?我认为这会引起数据收集工作量的组合爆炸。
也许这些建议中的一些会对您有所帮助
https://machinelearning.org.cn/improve-deep-learning-performance/
谢谢!我会去看看的。
嗨 Jason
很棒的教程!
我没有在 SKLEARN API 的“make_multilabel_classification()”的参数中清楚地区分,如果你设置了 n_classes = 3……而且我猜同时可以有1、2或3个标签……n_labels= 2 的参数是什么意思?
因为当你解释(如存在=1或不存在=0,所以总共=2)时,它总是有效的,并且必须是 n_labels= 2 吗?
谢谢
草草地说,我认为如果所有标签都转换为二进制,那么整个多标签分类问题将变得更易于建模。
谢谢。
不客气!
你好,Jason。
为什么你对多标签问题使用 BinaryCrossEntropy?我们不应该使用 CategoricalCrossEntropy 吗?
抱歉,我只是误解了整个情况……非常酷的文章 Jason。
没关系,这是个好问题。
这是个好问题,因为我们要进行一系列二元预测,而不是单一的多项概率分布。
谢谢 Jason 的澄清。
不客气。
嗨,Jason
# 获取模型
model = get_model(n_inputs, n_outputs)
# 在所有数据上拟合模型
model.fit(X, y, verbose=0, epochs=100)
# 为新数据进行预测
row = [3, 3, 6, 7, 8, 2, 11, 11, 1, 3]
在进行模型评估后,你如何选择最好的模型用于上面的“model.fit”?我不知道交叉验证是如何选择正确的模型并用于“fit”的。
好问题。一般来说,你会评估一系列模型和模型配置,选择一个最能解决你问题的模型,然后用数据拟合最终模型,用于未来进行预测。
也许这会有帮助。
https://machinelearning.org.cn/make-predictions-scikit-learn/
嗨 Jason,感谢您的帖子。我想征求您对一种问题的意见。
我的目标是将实例分类到标签中,其中标签遵循一个分布(分布总和为1),而不是二元的0或1。在这种情况下,我不确定是使用具有 sigmoid 的二元交叉熵损失,还是使用具有 softmax 的分类交叉熵损失。另外,在这种情况下,MLP 作为一个神经网络架构可以使用吗?请指导。
我认为你想预测类概率而不是类标签。
如果你有两个类别,你应该在输出层使用具有 sigmoid 激活函数的二元交叉熵损失;否则,你应该在输出层使用具有 softmax 激活函数的分类交叉熵损失。
谢谢 Jason 的回复。我的输出是跨不同标签的百分比分布。对于输入数据的每个实例,我都有一个跨标签的百分比分布。我想预测它。我有两个问题:
1. 我尝试在你的代码中将分类交叉熵损失与输出层中的 softmax 激活函数进行替换,但它给出的跨不同标签的概率与实际百分比相差甚远。我是否遗漏了什么?
2. 我想为我的输入分类特征执行实体嵌入,但是,大多数文献都谈论嵌入,其中它们使用目标变量作为单个输出而不是多标签输出。你是否有进行多标签分类的实体嵌入的参考/实现?
如果你的预测概率与实际值相差甚远,你可以看看你的模型是否错误。例如,你是否使用了正确的指标来训练模型?这里的一个问题是你的设计与普通情况有很大的不同。MSE 可能不起作用,但分布的最大误差可能是一个更好的指标。
希望这有帮助。
当然,谢谢 Jason。我会试试的。关于我的第二个问题,你有什么看法吗?
是什么阻止你使用多级输出的嵌入?
非常好的教程,Jason,做得很好。
谢谢。
感谢您的精彩解释,
但是有 R 语言的代码吗?我不熟悉 Python。
不完全是,但你可能会发现这篇帖子很有用:https://machinelearning.org.cn/non-linear-classification-in-r/
嗨,Jason,
感谢您的帖子,它简单易懂。
我正在做一个涉及多标签、多类(超过2个)输出的项目。我们通常在分类问题中应用 SMOTE 来平衡测试和训练数据的输出。
在多标签分类问题中,我们如何处理不平衡数据?
你认为这篇帖子回答了你的问题吗?https://machinelearning.org.cn/multi-class-imbalanced-classification/
早上好,Jason,
非常感谢您编写这个简单有效的教程。我正在尝试将这个想法应用于每像素语义分割。我有 n 个样本,编码为 RGB 图像 (512,512,3),真实标签编码为两个通道 (512,512,2),第一个通道提供更通用的分割(3个类别),第二个通道提供更具体的类别(7个类别)。因此,总共有10个类别,并且第一个通道中的某个类别包含第二个通道中的几个其他类别。
我已成功训练了一个使用简单(512,512,1)真实标签的 U-Net,但在将其扩展到多标签时遇到了困难。我相信创建这个两步分类应该能提高模型的性能。
任何想法/指导都非常受欢迎。
谢谢,
Hector
我不确定我是否明白。但对于两个通道,第一个通道有3个类别,第二个通道有7个类别,你的模型中总共应该有 3×7=21 个类别。
你好,亲爱的 Jason 博士。感谢这篇文章。
我有一些问题。
我有 11445 个样本和 4 列作为标签。
如果我理解了你的注释
我有 n_samples=11445,n_features=904(未经预处理),n_classes=4,(我没有任何重复或零行)。
一个标签列是二元的(True/False),但其他三列有3种状态(1、2、3 => 例如:“3-other, 2-other, 2-samba, 3-other, 1-sql...”)。
我的问题
我使用这篇文章的方法来处理我的数据集以构建神经网络模型是否合适?
2- 如果你说“是”,我应该为 n_label 使用什么数字?
3- 我的两个标签列是分类类型的,在对我的数据集进行缩放时,我使用了 z_score,并对这两列进行了序数编码,因为它们的数值差异太大。
而独热编码对它们不起作用。
这样对吗?
附言
文章参考中没有将数据集拆分为训练-测试。
如果你回答我,我将非常感激。因为没有人能好好指导我,我感到很困惑????♀️
1. 你需要检查一下,但我认为它可能有效。
2. 你有 4 列,一列是二元的,三列在 [1,2,3] 中,所以总标签将是 2x3x3x3=54。
3. 在我看来,这似乎不正确。为什么独热编码对分类类型不好?
你好,
感谢您提供的信息丰富的文章。
需要您就此提供建议,如果有三个类别可用,并且类内的概率应为
[x,y,z]
[.98 .97,.96]
我们不需要总和为1的概率,我们需要单独的概率,如果某个对象属于三个不同的类别。
在这种情况下,你不是在 N 个类别中进行分类。但你是在进行 N 个二元分类(即,它是否属于一个类,对于 N 个不同的类)。
在这种情况下,你需要两样东西:(1) 最后一层的输出是 N 个 sigmoid 激活函数,因此每个函数的输出都在 0 到 1 之间(就像概率一样),并且 (2) 你不在输出层使用 softmax,因为你不想将值归一化为总和为 1 的概率。
请建议如何使用深度学习技术对 QoS 参数进行分类。
你尝试过什么吗?如果你有一个具体的例子,会更容易评论。
你好,
首先,这些教程太棒了,感谢您花时间和精力撰写如此详细的课程和代码。
其次,这可能是一个愚蠢的问题,但有一个简单的答案,但我正在尝试基于“用于多标签分类的神经网络”代码,并以 CSV 作为输入。我尝试了各种方法,例如在代码外部预处理 CSV,将类/目标变量提取为 y 等,但仍然收到各种错误。
你是否有包含使用 read CSV 而不是代码开头看到的“make_multilabel_classification”的代码示例?非常感谢。
是的,很多。例如,在这里:https://machinelearning.org.cn/neural-network-for-cancer-survival-dataset/
搜索 `read_csv()` 函数,你应该能看到如何做到。
我有一个疑问,
为什么我们在 cv.split() 循环(在 evaluate() 函数中)内初始化模型?
它应该在 cv.split() 循环之外对吧?
由于我们一遍又一遍地初始化它,所以使用交叉验证方法没有意义。
不,代码是正确的。CV 是为了评估模型配置。因此,你应该从头开始初始化它,并使用一个折叠来训练它。通过对 K 个这样的折叠取平均值,你可以获得这个特定模型配置的平均分数。
嗨,Jason,
感谢这篇好文章。
为了解释“将概率四舍五入为类别标签”,您可以添加一个指向 https://machinelearning.org.cn/threshold-moving-for-imbalanced-classification/ 中“将概率转换为类别标签”部分的引用链接。
感谢您的建议!
亲爱的 Jason,
感谢您这篇精彩的文章。
我的项目是一个由四个区域组成的电力系统,它们的状态涉及 [稳定、警报、紧急]。我想知道是否可以使用4个输出神经元,每个神经元的值为 (-1 或 0 或 1),并在最后一层使用 tanh 而不是 sigmoid?如果我没记错,在这种情况下您建议使用什么损失函数?
tanh 似乎更合适,或者您可以将其视为一个多类别分类问题,其中稳定、警报、紧急状态都被 one-hot 编码。
Mahmoud,您好……感谢您的提问!通常,尝试各种激活函数是有益的。以下资源将为您选择各种激活函数提供一些指导。
https://machinelearning.org.cn/choose-an-activation-function-for-deep-learning/
此致,
对于多类别问题,有些问题中的每个样本都属于其中一个类别,而有些问题中的样本属于 0 或 1 类。这种情况实际上就有一个“以上皆非”的标签,这本身就是一种类别。
如果我们能避免,“以上皆非”标签与其它样本相比,我们应该争取多少?例如,在 NER 中,我们无法避免,“O”标签将创建一个不平衡的数据集。但在其他情况下,我们可能会。
因此,问题归结为,我们为“有趣”的标签训练多少,以及我们提供多少反例?
Greg,您好……我的建议是根据网络从未见过的数据的性能进行调整……即通过验证,如果您有可用的数据。
嗨,Jason,
如何修改此模型以进行多标签图像分类?
输入层将是 224,因为图像的尺寸将是 224×224。
由于是图像,将无法获得特征数量。
您能帮助 Json 吗?
此致,
Haris。
你好 Jason,
感谢您的精彩文章!我正在尝试构建一个深度学习模型来进行多标签 TS 分类,但我遇到了这个问题:我的训练数据集只包含单个标签的样本。但是,我希望我的模型能够在测试数据中预测多标签。
例如,我的训练数据是这样的
[ 3. 3. 6. 7. 8. 2. 11. 11. 1. 3.] [1 0 0]
[7. 6. 4. 4. 6. 8. 3. 4. 6. 4.] [0 0 0]
[ 5. 5. 13. 7. 6. 3. 6. 11. 4. 2.] [0 1 0]
[1. 1. 5. 5. 7. 3. 4. 6. 4. 4.] [1 1 1]
[ 4. 2. 3. 13. 7. 2. 4. 12. 1. 7.] [0 0 1]
但我的测试数据最终会是这样的
[ 3. 3. 6. 7. 8. 2. 11. 11. 1. 3.] [1 1 0]
[7. 6. 4. 4. 6. 8. 3. 4. 6. 4.] [0 0 0]
[ 5. 5. 13. 7. 6. 3. 6. 11. 4. 2.] [1 1 0]
[1. 1. 5. 5. 7. 3. 4. 6. 4. 4.] [1 1 1]
[ 4. 2. 3. 13. 7. 2. 4. 12. 1. 7.] [0 1 0]
如何训练我的模型才能用单标签训练数据成功预测多标签输出?
Victory,您好……您在运行模型时得到了什么结果?
你好,James,
抱歉回复晚了。我的结果在多标签测试中非常不一致。模型在单标签测试案例(如 [1 0 0])上表现良好。但是,当涉及到多标签测试案例时,模型通常只能找到一个正确的标签。在仅存在多标签示例的数据集中,准确率约为 30%。
抱歉我弄错了,我的训练数据形状是这样的
[ 3. 3. 6. 7. 8. 2. 11. 11. 1. 3.] [1 0 0]
[7. 6. 4. 4. 6. 8. 3. 4. 6. 4.] [0 1 0]
[ 5. 5. 13. 7. 6. 3. 6. 11. 4. 2.] [0 0 1]
您好,首先非常感谢您的教程,它对我尝试的另一个 AI 项目非常有帮助,而不仅仅是这个项目,其他的教程也非常简单易懂,并且以一种有序、清晰的方式展示了一切。
但在我的项目中,我对这些限制感到困惑。
我有一个 csv 文件,有 9 列,4 列是传感器数据,1 列是传感器 ID,其余 4 列是传感器数据异常。我需要使用 CNN 来创建一个模型。
对于异常列,它们只有 1 和 0(是否存在异常)。在传感器 ID 列中,存在从 1 到 15 的 ID 号,即。
为了清晰起见,这是我的 csv 文件的一部分
temperature humidity light voltage moteid temperature_anomaly voltage_anomaly light_anomaly humidity_anomaly
122.153 -3.91901 11.04 2.03397 1 1 0 0 1
122.153 -3.91901 10.12 2.048 15 1 0 0 1
122.153 -3.91901 10.12 2.048 1 0 0 1
121.997 -1.41947 9.2 2.01329 1 9 0 0 1
121.977 -0.457683 9.2 2.01329 2 1 0 0 1
121.918 4.77448 9.2 2.01329 1 10 0 0 1
122.153 8.67328 9.2 2.00649 1 14 0 0 1
我必须创建一个 CNN 模型,同时对异常概率和 moteid 概率进行分类,这意味着哪种异常可以与哪个 moteid(传感器 ID)一起出现。我尝试了很多方法,但总是在模型输入和输出方面感到困惑,并且删除 moteid 或其他 4 个异常列总是让我只能进行 mote ID 分类或异常分类,有没有可能同时分类两者?
我希望看到这样的结果
来自 moteid 12(异常概率:0.98)
以及它们的传感器异常
voltage_anomaly: 0.75
light_anomaly: 0.3
temp_anomaly: 0.55,
humidty_anomaly: 0.01
任何建议都会让我很高兴,我真的很困惑。
谢谢!
Talina,您好……请将您的问题限制在一个问题上,以便我们能更好地帮助您。