Python机器学习:如何自动选择最高cv_results均值的分类器
问题排查与修正方案
我来帮你搞定这个问题!你现在的代码里,选择最优分类器的逻辑出了个小纰漏,咱们一步步拆解:
问题根源
你把每个模型的完整交叉验证得分数组存在了results列表里,直接调用max(results)的时候,Python是在逐个比较数组的元素值(按顺序比第一个元素,再第二个,以此类推),而不是你需要的「比较得分均值」。这就是为什么本该选中均值最高的SVM,结果却选了NB的原因——它只是某个fold的得分刚好在数组比较中占了优势而已。
修正后的代码
我们需要把每个模型的名称、得分均值、标准差绑定在一起存储,然后通过均值来筛选最优模型:
import sklearn.model_selection as model_selection from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.naive_bayes import GaussianNB from sklearn.svm import SVC # 假设你已经定义了 X_tr, Y_tr, seed, scoring 这些变量 models = [] models.append(('LR', LogisticRegression())) models.append(('KNN', KNeighborsClassifier())) models.append(('NB', GaussianNB())) models.append(('SVM', SVC())) results = [] names = [] storeresults = [] # 存储每个模型的(名称,均值,标准差) for name, model in models: # 建议加上shuffle=True,避免数据顺序影响交叉验证结果 kfold = model_selection.KFold(n_splits=10, random_state=seed, shuffle=True) cv_results = model_selection.cross_val_score(model, X_tr, Y_tr, cv=kfold, scoring=scoring) mean_score = cv_results.mean() std_score = cv_results.std() results.append(cv_results) names.append(name) storeresults.append( (name, mean_score, std_score) ) # 用f-string格式化输出更清晰 print(f"{name}: {mean_score:.6f} ({std_score:.6f})") # 通过lambda指定按均值排序,找到得分最高的模型 best_model = max(storeresults, key=lambda x: x[1]) print(f'The best classifier is {best_model[0]} with mean score {best_model[1]:.6f} (std: {best_model[2]:.6f})')
关键改进点
- 存储完整模型信息:用
storeresults把每个模型的名称、均值、标准差打包存储,方便后续筛选。 - 指定max的比较键:通过
key=lambda x: x[1]告诉Python,要按照元组里的第二个元素(也就是得分均值)来找最大值,而不是默认的数组比较逻辑。 - 优化交叉验证:给KFold加上
shuffle=True,如果你的数据集是按类别排序的,这能让交叉验证结果更可靠。
预期输出
运行修正后的代码,你会得到正确的结果:
LR: 0.552291 (0.021477) KNN: 0.884636 (0.016431) NB: 0.609434 (0.026586) SVM: 0.897305 (0.015317) The best classifier is SVM with mean score 0.897305 (std: 0.015317)
内容的提问来源于stack exchange,提问作者Nazmin Nasya
相关产品推荐
相关产品推荐

