k-折叠交叉验证:如何基于Stata中随机生成的整数变量过滤数据
以下几点似乎很明显,但它的行为并不像我预期的那样。我想在不使用SCC包的情况下进行k-fold交叉验证,我想我可以只过滤我的数据并在子集上运行我自己的回归 首先,我生成一个随机整数在1到5之间的变量(5倍交叉验证),然后循环每个折叠数。我想按折叠数过滤数据,但使用布尔过滤器无法过滤任何内容。为什么? 奖励:捕获所有测试MSE并对其求平均值的最佳方法是什么?在Python中,我只需要制作一个列表或numpy数组,然后取平均值k-折叠交叉验证:如何基于Stata中随机生成的整数变量过滤数据,stata,Stata,以下几点似乎很明显,但它的行为并不像我预期的那样。我想在不使用SCC包的情况下进行k-fold交叉验证,我想我可以只过滤我的数据并在子集上运行我自己的回归 首先,我生成一个随机整数在1到5之间的变量(5倍交叉验证),然后循环每个折叠数。我想按折叠数过滤数据,但使用布尔过滤器无法过滤任何内容。为什么? 奖励:捕获所有测试MSE并对其求平均值的最佳方法是什么?在Python中,我只需要制作一个列表或numpy数组,然后取平均值 gen randint = floor((6-1)*runiform()
gen randint = floor((6-1)*runiform()+1)
recast int randint
forval b = 1(1)5 {
xtreg c.DepVar /// // training set
c.IndVar1 ///
c.IndVar2 ///
if randint !=`b' ///
, fe vce(cluster uuid)
xtreg c.DepVar /// // test set, needs to be performed with model above, not a
c.IndVar1 /// // new model...
c.IndVar2 ///
if randint ==`b' ///
, fe vce(cluster uuid)
}
编辑:测试集需要在模型适合于培训集的情况下执行。我更改了代码中的注释以反映这一点
最终,过滤问题的解决方案是我使用引号中的标量来定义边界,我有:
替换randint=floor((`varscalar'-1)*runiform()+1)
而不仅仅是
替换randint=floor((varscalar-1)*runiform()+1)
何时何地使用Stata中的引号令我困惑。我不能只在循环中使用varscalar
,我必须使用`=varscalar'
,但出于某种原因,我可以使用varscalar-1
并获得预期的结果。有趣的是,我不能使用
替换randint=floor(`varscalar')*runiform()+1)
我想我应该用
替换randint=floor(`=varscalar')*runiform()+1)
那么为什么可以使用带负号但不带等号的版本呢
下面的答案仍然非常有用,我从中学到了很多。事实上,这里发生的两件事并不一定直接相关。1) 如何使用随机生成的整数值和2)k倍交叉验证程序过滤数据 对于第一个问题,我将在下面留下一个示例,它可以帮助您使用Stata和一些可以轻松转移到其他问题的工具(例如矩阵生成和存储度量的操作)解决问题。然而,我不会将您的代码草图或我的示例称为“k-fold交叉验证”,主要是因为它们在测试和训练数据中都符合模型。然而,严格来说,情况应该是,模型应该在训练数据中进行训练,并使用这些参数评估模型在测试数据中的性能 有关该程序的更多参考,包括几个可视化 话虽如此,这里有些东西可能会有所帮助
clear all
set seed 4
set obs 100
*Simulate model
gen x1 = rnormal()
gen x2 = rnormal()
gen y = 1 + 0.5 * x1 + 1.5 *x2 + rnormal()
gen byte randint = runiformint(1, 5)
tab randint
/*
randint | Freq. Percent Cum.
------------+-----------------------------------
1 | 17 17.00 17.00
2 | 18 18.00 35.00
3 | 21 21.00 56.00
4 | 19 19.00 75.00
5 | 25 25.00 100.00
------------+-----------------------------------
Total | 100 100.00
*/
// create a matrix to store results
matrix res = J(5,4,.)
matrix colnames res = "R2_fold" "MSE_fold" "R2_hold" "MSE_hold"
matrix rownames res ="1" "2" "3" "4" "5"
// show formated empty matrix
matrix li res
/*
res[5,4]
R2_fold MSE_fold R2_hold MSE_hold
1 . . . .
2 . . . .
3 . . . .
4 . . . .
5 . . . .
*/
// loop over different samples
forvalues b = 1/5 {
// run the model using fold == `b'
qui reg y x1 x2 if randint ==`b'
// save R squared training
matrix res[`b', 1] = e(r2)
// save rmse training
matrix res[`b', 2] = e(rmse)
// run the model using fold != `b'
qui reg y x1 x2 if randint !=`b'
// save R squared training (?)
matrix res[`b', 3] = e(r2)
// save rmse testing (?)
matrix res[`b', 4] = e(rmse)
}
// Show matrix with stored metrics
mat li res
/*
res[5,4]
R2_fold MSE_fold R2_hold MSE_hold
1 .50949187 1.2877728 .74155365 1.0070531
2 .89942838 .71776458 .66401888 1.089422
3 .75542004 1.0870525 .68884359 1.0517139
4 .68140328 1.1103964 .71990589 1.0329239
5 .68816084 1.0017175 .71229925 1.0596865
*/
// some matrix algebra workout to obtain the mean of the metrics
mat U = J(rowsof(res),1,1)
mat sum = U'*res
/* create vector of column (variable) means */
mat mean_res = sum/rowsof(res)
// show the average of the metrics acros the holds
mat li mean_res
/*
mean_res[1,4]
R2_fold MSE_fold R2_hold MSE_hold
c1 .70678088 1.0409408 .70532425 1.0481599
*/
就风格而言,我只想说‘gen byte randint=runiformint(1,5)’,但这不是问题所在。@PencilBox,我认为您上次编辑的内容足够长,可以在单独的问题中发布,因为它也偏离了您原来的问题。此外,更好地理解这些宏的行为可能是有益的。您在代码的测试集部分是对的,这完全是错误的,根本不是k-fold。