如何在Scikit-learn多类SVM中获取各OVA估计器的结果与分类分数
当然可以!在Scikit-learn里用One-vs-All(OVA)策略的多类SVM时,咱们完全能拿到每个二分类器的分类分数和结果,下面一步步给你拆解怎么做:
1. 先明确OVA策略的多类SVM实现
要注意:Scikit-learn里的SVC默认用的是**One-vs-One(OVO)**策略,如果你想明确用OVA,推荐用OneVsRestClassifier来包装基础的SVM分类器,这样不仅能保证是OVA逻辑,还能直接访问每个内部的二分类器。
比如初始化并训练模型:
from sklearn.svm import SVC from sklearn.multiclass import OneVsRestClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 加载示例数据,拆分训练/测试集 X, y = load_iris(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 用OneVsRestClassifier包装SVC,开启probability来获取概率得分 ovr_svm = OneVsRestClassifier( SVC(kernel='linear', probability=True, random_state=42) ) ovr_svm.fit(X_train, y_train)
2. 获取所有OVA分类器的分类分数
训练完成后,你有两种方式获取每个样本在各个OVA分类器上的得分:
predict_proba():返回每个样本属于每个类别的概率(归一化到0-1之间),每一列对应一个OVA分类器(比如第i列就是“类别i vs 其他所有类别”的分类器给出的概率)decision_function():返回每个样本在每个类别上的决策值(未归一化,反映分类器的置信度)
示例代码:
# 获取概率得分,shape为(n_samples, n_classes) ova_prob_scores = ovr_svm.predict_proba(X_test) # 或者获取决策值 # ova_decision_scores = ovr_svm.decision_function(X_test) # 比如查看第一个测试样本在所有OVA分类器上的得分 print("第一个测试样本的OVA分类器得分:") for cls, score in zip(ovr_svm.classes_, ova_prob_scores[0]): print(f"类别 {cls}: {score:.4f}")
3. 获取每个样本排名前10的OVA分类器结果
如果要对每个样本的所有OVA得分排序,取前10的类别和对应得分,可以用Numpy来快速处理:
import numpy as np # 对每个样本的得分降序排序,取前10的类别索引 top10_indices = np.argsort(ova_prob_scores, axis=1)[:, -10:] # 反转顺序,让得分从高到低排列 top10_indices = np.flip(top10_indices, axis=1) # 获取对应的类别标签和得分 top10_classes = ovr_svm.classes_[top10_indices] top10_scores = np.take_along_axis(ova_prob_scores, top10_indices, axis=1) # 查看第一个样本的前10结果 print("\n第一个样本的前10OVA分类器结果:") for cls, score in zip(top10_classes[0], top10_scores[0]): print(f"类别 {cls}: {score:.4f}")
如果你的数据集类别总数少于10,这段代码会自动返回所有类别的结果,不用额外调整。
4. 直接访问每个OVA估计器的实例和单独结果
用OneVsRestClassifier的好处是,你可以直接通过estimators_属性拿到所有内部的二分类器实例,然后单独调用它们的方法:
# 获取所有OVA分类器的列表,每个元素对应一个"类别i vs 其他"的二分类器 ova_classifiers = ovr_svm.estimators_ # 比如访问第一个分类器(对应类别0 vs 其他) class0_clf = ova_classifiers[0] # 单独用这个分类器预测测试集的概率得分([:,1]是类别0的概率) class0_scores = class0_clf.predict_proba(X_test)[:, 1] # 甚至可以单独生成这个二分类器的混淆矩阵 from sklearn.metrics import confusion_matrix y_test_binary = (y_test == 0).astype(int) y_pred_binary = class0_clf.predict(X_test) class0_cm = confusion_matrix(y_test_binary, y_pred_binary) print("\n类别0的OVA分类器混淆矩阵:") print(class0_cm)
关于混淆矩阵的补充
混淆矩阵主要用来展示分类器的对错分布,它不能直接给出每个OVA分类器的得分,但你可以像上面那样,针对每个OVA二分类器单独生成混淆矩阵,来查看这个分类器的分类表现。如果需要得分,还是predict_proba或decision_function更直接。
内容的提问来源于stack exchange,提问作者theSOMguy




