在机器学习中,经常遇到目标变量由多个类别组成的分类问题,这被称为多类分类。在scikit-learn库中,所有的估计器都原生支持多类分类,为最终用户提供了最合理的策略。此外,sklearn.multiclass模块实现了多种策略,这些策略可以用于实验或开发只支持二元分类的第三方估计器。
本例中,使用了UCI数据集中的酵母数据集,通过sklearn.datasets.fetch_openml函数从OpenML加载数据集。通过检查目标变量,可以确定正在处理的数据科学问题类型。目标变量是离散的,由10个类别组成,因此面临的是一个多类分类问题。
在接下来的实验中,使用决策树分类器和重复分层K折交叉验证,其中K折数为3,重复次数为5。比较了以下策略:决策树分类器可以直接处理多类分类,无需特殊调整。它通过将训练数据分解为更小的子集,并专注于每个子集中最常见的类别来工作。通过重复此过程,模型可以准确地将输入数据分类到多个不同的类别中。
from sklearn.datasets import fetch_openml
X, y = fetch_openml(data_id=181, as_frame=True, return_X_y=True)
print(y.value_counts().sort_index())
可以看到,决策树分类器的内置策略工作得很好。一对一和错误校正输出码策略甚至表现得更好。然而,一对一策略的表现不如其他策略。这些结果在文献中有所报道。然而,故事并不像看起来那么简单。
后来的研究表明,如果首先优化基分类器的超参数,多类策略将显示出相似的分数。在这里,尝试通过至少优化基决策树的深度来重现这样的结果。
from sklearn.model_selection import GridSearchCV
param_grid = {"max_depth": [3, 5, 8]}
tree_optimized = GridSearchCV(tree, param_grid=param_grid, cv=3)
ovo_tree = OneVsOneClassifier(tree_optimized)
ovr_tree = OneVsRestClassifier(tree_optimized)
ecoc = OutputCodeClassifier(tree_optimized, code_size=2)
一旦优化了超参数,所有多类策略的表现都相似,如文献中所讨论的。可以从这些结果中得到一些直觉。首先,一对一和错误校正输出码在未优化超参数时优于树的原因在于它们集成了更多的分类器。集成提高了泛化性能。这有点像为什么在没有优化超参数的情况下,装袋分类器通常比单个决策树表现得更好。