#stata
#stata
Вопрос:
Следующее кажется очевидным, но оно ведет себя не так, как я ожидал. Я хочу выполнить k-кратную перекрестную проверку без использования пакетов SCC и подумал, что могу просто отфильтровать свои данные и выполнить собственные регрессии для подмножеств.
Сначала я генерирую переменную со случайным целым числом от 1 до 5 (5-кратная перекрестная проверка), затем я перебираю каждое число сгибов. Я хочу отфильтровать данные по числу сгибов, но использование логического фильтра ничего не фильтрует. Почему?
Бонус: каков наилучший способ захватить все тестовые MSE и усреднить их? В Python я бы просто составил список или числовой массив и взял среднее значение.
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)
}
РЕДАКТИРОВАТЬ: тестовый набор должен выполняться с моделью, подходящей для обучающего набора. Я изменил свой комментарий в коде, чтобы отразить это.
В конечном итоге решение проблемы фильтрации заключалось в том, что я использовал скаляр в кавычках для определения границ, и у меня было:
replace randint = floor((`varscalar'-1)*runiform() 1)
вместо того, чтобы просто
replace randint = floor((varscalar-1)*runiform() 1)
Когда и где использовать кавычки в Stata меня смущает. Я не могу просто использовать varscalar
в цикле, я должен использовать `=varscalar'
, но я могу по какой-то причине использовать varscalar - 1
и получить ожидаемый результат. Интересно, что я не могу использовать
replace randint = floor((`varscalar')*runiform() 1)
Я полагаю, я должен просто использовать
replace randint = floor((`=varscalar')*runiform() 1)
Итак, почему можно использовать версию с минус единицей и без знака равенства??
Приведенный ниже ответ по-прежнему чрезвычайно полезен, и я многому научился из него.
Комментарии:
1. С точки зрения стиля я бы просто сказал: `gen byte randint = runiformint(1, 5)», но проблема не в этом.
2. @PencilBox, я думаю, что ваша последняя правка достаточно длинная, чтобы ее можно было опубликовать в отдельном вопросе, потому что она также довольно далека от вашего первоначального вопроса. Кроме того, это и это может быть полезно для лучшего понимания поведения таких макросов.
Ответ №1:
На самом деле, здесь происходят две разные вещи, которые не обязательно напрямую связаны. 1) Как фильтровать данные по случайно сгенерированному целочисленному значению и 2) k-кратная процедура перекрестной проверки.
Для первого я оставлю ниже пример, который может помочь вам разобраться с использованием Stata с некоторыми инструментами, которые можно легко перенести на другие задачи (такие как генерация матрицы и манипулирование для хранения метрик). Однако я бы не назвал ни ваш набросок кода, ни мой пример «k-кратной перекрестной проверкой», главным образом потому, что они соответствуют модели, как в тестировании, так и в обучающих данных. Тем не менее, должно быть так, что, строго говоря, модель должна быть обучена на обучающих данных и, используя эти параметры, оценивать производительность модели при тестировании данных.
Для получения дополнительных ссылок на процедуру Scikit-learn проделал блестящую работу, объяснив ее с включением нескольких визуализаций.
Тем не менее, вот кое-что, что может быть полезно.
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
*/
Комментарии:
1. Вы правы в моей тестовой части кода, которая полностью ошибочна и вообще не k-кратна.