我正在尝试使用自助法来获取我的模型平均MSE估计。我正在遵循这个指南来进行操作,供参考:https://machinelearningmastery.com/a-gentle-introduction-to-the-bootstrap-method/ 这是我的代码:
models_mse = [None]*100for i in range(100): boot = resample(X, replace = True, n_samples = math.floor(len(X) / 2),random_state = 1) y_new = [y for y in X if y not in boot] X_train, X_test, y_train, y_test = train_test_split(boot, y_new, test_size=0.1, random_state=42) reg = LogisticRegression() reg.fit(X_train, y_train) MSE = mean_squared_error(y_test, reg.predict(X_test)) models_mse.append(MSE)
这会产生以下错误:
ValueError: Found input variables with inconsistent numbers of samples: [497, 0]
这意味着y_new
是空的。根据我对自助法的理解,我们将我们的样本视为“总体”,并在这个伪总体上进行有放回的重抽样,以生成更多的样本来估计伪总体的参数,在我的例子中就是MSE。这里,我有一些使用onehot编码的数据X
,它看起来像这样:
array([[1., 0., 0., ..., 0., 0., 1.], [1., 0., 1., ..., 1., 0., 0.], [1., 0., 1., ..., 0., 0., 1.], ..., [0., 1., 0., ..., 0., 0., 1.], [0., 1., 0., ..., 1., 0., 0.], [0., 1., 0., ..., 1., 0., 0.]])
并且它是一个numpy数组:
>>>type(X)numpy.ndarray
我的问题如下:为什么当我观察到boot
和X
之间存在差异时,y_new
是空的?此外,我已经随意决定使用原始样本的一半样本数。在自助法中选择样本数是否有更系统的方法?最后,我当前的设置是否适合我试图解决的问题?
谢谢。
编辑:在经过用户评论的修改后,我的新代码是:
models_mse = [None]*100for i in range(100): boot = resample(X_train, replace = True, n_samples = X_train.shape[0],random_state = 1) reg = LogisticRegression() reg.fit(boot, y_train) MSE = mean_squared_error(y_test, reg.predict(X_test)) models_mse.append(MSE)
这不会抛出任何错误。然而,每个模型的MSE完全相同,这很奇怪,因为boot
不应该是每次迭代都不同的吗?
回答:
在你的代码中,y_new
是从X
中选择的:
y_new = [y for y in X if y not in boot]
你可能想要从X
中选择。不过这仍然不会工作,因为你不能对numpy数组进行in
操作。另外,正如这篇文章所说,resample
API不会给你提供用于测试集的袋外观察。然而,我们从API中想要的功能实现起来相当简单。另外,你可能不希望在每次抽样时使用相同的种子(随机状态)。
models_mse=[]for _ in range(100): train_idx = np.random.randint(0,len(X),size=(len(X),)) test_idx = np.array([i for i in range(len(X)) if i not in train_idx]) X_train, Y_train, X_test, Y_test = X[train_idx], Y[train_idx], X[test_idx],Y[test_idx] model = LogisticRegression() model.fit(X_train, Y_train) Y_pred = model.predict(X_test) mse = MSE(Y_test, Y_pred) # 替换为适当的API/函数 models_mse.append(mse)print("Bootstrapped MSE={}".format(sum(models_mse)/100))
我使用了与原始数据集X
相同的大小作为训练集,这是我通常的做法。你可以根据需要进行更改。