在机器学习领域,当目标变量由两个以上的类别组成时,面临的问题被称为多类分类。本文将探讨不同的多类分类策略,并使用scikit-learn库中的相关工具进行实验和比较。
本例中,使用的是UCI数据集中的酵母数据集。通过scikit-learn库的fetch_openml
函数,可以从OpenML平台加载数据集。数据集中的目标变量是离散的,包含10个类别,因此面临的是一个典型的多类分类问题。
在本实验中,使用决策树分类器和重复分层K折交叉验证方法,比较了以下几种策略:
通过交叉验证和统计性能比较这些策略,并绘制了不同策略的准确率分布图。
以下是使用Python和scikit-learn库实现上述策略比较的代码示例。
from sklearn.datasets import fetch_openml
from sklearn.model_selection import RepeatedStratifiedKFold, cross_validate
from sklearn.multiclass import OneVsOneClassifier, OneVsRestClassifier, OutputCodeClassifier
from sklearn.tree import DecisionTreeClassifier
import pandas as pd
from matplotlib import pyplot as plt
# 加载数据集
X, y = fetch_openml(data_id=181, as_frame=True, return_X_y=True)
# 定义交叉验证策略
cv = RepeatedStratifiedKFold(n_splits=3, n_repeats=5, random_state=0)
# 初始化分类器
tree = DecisionTreeClassifier(random_state=0)
ovo_tree = OneVsOneClassifier(tree)
ovr_tree = OneVsRestClassifier(tree)
ecoc = OutputCodeClassifier(tree, code_size=2)
# 交叉验证
cv_results_tree = cross_validate(tree, X, y, cv=cv, n_jobs=2)
cv_results_ovo = cross_validate(ovo_tree, X, y, cv=cv, n_jobs=2)
cv_results_ovr = cross_validate(ovr_tree, X, y, cv=cv, n_jobs=2)
cv_results_ecoc = cross_validate(ecoc, X, y, cv=cv, n_jobs=2)
# 绘制准确率分布图
scores = pd.DataFrame({
"DecisionTreeClassifier": cv_results_tree["test_score"],
"OneVsOneClassifier": cv_results_ovo["test_score"],
"OneVsRestClassifier": cv_results_ovr["test_score"],
"OutputCodeClassifier": cv_results_ecoc["test_score"],
})
ax = scores.plot.kde(legend=True)
ax.set_xlabel("准确率")
ax.set_xlim([0, 0.7])
ax.set_title("不同多类策略的准确率分布")
plt.show()
通过实验,发现在未优化超参数的情况下,一对一和输出码策略的性能优于决策树。然而,当优化了决策树的超参数后,所有策略的性能都趋于相似。这表明在开发预测模型时,优化超参数是非常重要的。
此外,scikit-learn库中的估计器已经针对多类分类问题实现了特定的策略,因此对于这些估计器来说,不需要使用不同的策略。这些策略主要适用于只支持二分类的第三方估计器。
本文中提到的参考资料包括: