LogisticRegression模型绘制学习曲线train_sizes取值范围报错求解
报错产生原因
- 核心原因是sklearn的
learning_curve函数在指定cv=5的5折交叉验证规则下,每轮验证可用于训练的最大样本量为总样本量的(cv-1)/cv:你传入的总样本量是125578,计算可得最大可用训练样本数为125578 * 4/5 = 100462,刚好和报错提示的上限一致,不存在数据丢失问题,你观察到的差值是2.5万左右,属于位数误读。 - 你当前代码中
np.linspace(0, dataframe.shape[0])生成的训练集大小序列范围是[0, 125578],一方面包含了非法的0值(训练集不能为0样本),另一方面最大值超过了交叉验证下的可用上限,因此触发ValueError。
修复方案
推荐优先使用比例模式指定train_sizes,不需要手动计算绝对值,可自动适配交叉验证的样本上限,代码修改逻辑如下:
- 把
train_sizes的取值改为0~1之间的浮点数序列,代表占可用最大训练集的比例,取值范围避开0,从最小可用比例(比如0.1)开始即可。 - 不需要额外根据数据集行数调整参数,适配性更强。
修正后的完整代码:
import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import learning_curve def get_learning_curves(model, X, y): # 直接使用比例模式指定训练集大小,默认生成50个采样点 train_sizes = np.linspace(0.1, 1.0, 50) # 获取交叉验证下的训练、测试得分,显式指定scoring为r2和你后续指标对应 train_sizes, train_scores, test_scores = learning_curve( estimator=model, X=X, y=y, train_sizes=train_sizes, cv=5, scoring='r2') # 计算交叉验证得分均值 train_scores_mean = np.mean(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) # 绘图逻辑不变 plt.plot(train_sizes, train_scores_mean, label = 'Training score') plt.plot(train_sizes, test_scores_mean, label = 'Test score') plt.ylabel('r2 score', fontsize = 14) plt.xlabel('Training set size', fontsize = 14) plt.title('Learning curves', fontsize = 18, y = 1.03) plt.legend() return plt.show()
调用代码调整为:
get_learning_curves(LogisticRegression(), X_pre, y_pre)
如果坚持要使用绝对值模式指定训练集大小,可将训练集上限调整为int(dataframe.shape[0] * 0.8),同时取值下限调整为大于0的数值即可。
内容的提问来源于stack exchange,提问作者Arthur Langlois
相关产品推荐
相关产品推荐

