TheThing
3.08.2012 - 20:07
Согласно моим расчетам лишь фактор С (тяжесть состояния больного) статистически значимо ассоциирован с риском смерти (повышенный риск). Первый столбец цифр - групповые вероятности факторов А+Б+С, второй столбец - вероятности А+Б, третий столбец - А+С, четвертый - Б+С.
0,34015 0,40888 0,34989 0,39730
0,49263 0,50523 0,38566 0,55469
0,42836 0,26548 0,39794 0,62781
0,59121 0,36225 0,60615 0,70132
0,25785 0,31131 0,25945 0,36786
0,43051 0,43519 0,44927 0,47932
0,57229 0,30174 0,58240 0,72457
0,25236 0,38984 0,23751 0,31511
0,48796 0,40442 0,50717 0,56495
0,28626 0,39493 0,29287 0,34319
0,49658 0,37706 0,51123 0,59569
0,37246 0,31495 0,38091 0,50680
0,12237 0,25227 0,11330 0,21316
0,12748 0,31118 0,10785 0,19567
0,53328 0,46286 0,54719 0,57564
0,52075 0,45196 0,49164 0,58775
0,49832 0,42483 0,47445 0,58010
0,36305 0,40782 0,37485 0,42414
0,45776 0,43172 0,47040 0,51505
0,36475 0,42263 0,34469 0,43039
0,57694 0,45255 0,59446 0,62775
0,76129 0,46953 0,75743 0,81078
0,14571 0,39503 0,14859 0,16921
0,13010 0,47251 0,11741 0,13051
0,18435 0,41960 0,15968 0,21998
0,11134 0,39310 0,10980 0,12896
0,86965 0,82693 0,66838 0,83274
0,72274 0,61052 0,74657 0,68379
0,88778 0,82411 0,75763 0,84437
0,86492
0,79245 0,63566 0,81702 0,75099
0,74476
0,35380 0,73615 0,40006 0,19948
0,83108 0,69577 0,83671 0,77659
0,73978 0,64728 0,77173 0,67595
0,67489 0,61222 0,70833 0,62232
0,79319 0,67501 0,82141 0,72640
0,69415 0,70943 0,72958 0,57129
0,70840 0,70052 0,74604 0,59504
0,73655 0,79736 0,77758 0,54065
0,58925 0,63310 0,62808 0,50647
0,55043 0,71285 0,58524 0,40279
0,69639 0,67085 0,71908 0,61115
0,88188 0,67862 0,89790 0,84678
0,46330 0,67591 0,50338 0,33916
0,49648 0,53330 0,52366 0,48054
0,74687 0,58398 0,77340 0,72615
0,47468 0,57482 0,49834 0,42908
0,54642 0,51868 0,56019 0,55171
0,34062 0,60430 0,36285 0,27085
0,73011 0,55340 0,75691 0,72478
0,76456 0,50137 0,78571 0,78991
0,60758 0,46409 0,63096 0,64996
0,66616 0,59398 0,69391 0,62750
0,76595 0,57299 0,74402 0,77482
0,53226 0,56143 0,52938 0,51339
0,65210 0,57569 0,68407 0,62190
0,55687 0,54630 0,58823 0,53632
0,82779 0,56820 0,84837 0,82598
0,63646 0,52353 0,63253 0,65455
0,25158 0,48530 0,26149 0,24793
0,76566 0,53693 0,78297 0,77582
0,66544 0,55563 0,69248 0,65225
0,35473 0,50851 0,36883 0,34657
0,47536 0,54117 0,50240 0,45183
0,68043 0,58309 0,71167 0,64929
0,32747 0,47152 0,34773 0,33673
0,12440 0,56551 0,13399 0,09099
0,74684 0,58395 0,77340 0,72612
0,47667 0,58016 0,50408 0,42592
0,32795 0,59106 0,35756 0,26315
0,56675 0,64000 0,45425 0,54231
Коэффициент конкордации около 65%, что в принципе совпадает с классификационной способностью модели, полученной с помощью случайного леса (100 - OOB error = 100 - 31,43 = 68,57%).
Цитата(DrgLena @ 3.08.2012 - 23:56)

А если не лес строить, а одно дерево, то при одном ветвлении, на двух конечных узлах при условии С<=16,64 классификация произойдет с точностью 65,7%
Переменная С разделяет пациентов реальной выборки, а вот В не разделяет и вообще не имеет различий в группах выживших и нет ни по каким парным критериям. И не удивительно, такие разбросы данных (скорее всего ошибки ввода) например, у умерших больных есть значение 237 и 0,14. Вряд ли В может называться маркером. Но в сгенерированных выборках значения могут повторяться или вообще не попасть.
ПО приведенным исходным данным точки разделения, и соответственно чувствительность и специфичность с моими расчетами не сходятся, но площадь ROC сходится, это очень странно. Автор должен верифицировать данные, иначе никакие многомерные методы на таких данных применять нельзя.
1 по мимо того что B надо логарифмировать, имеются корреляции между предикторами
Код
> cor(cbind(data.na[,c(2,4)], log(data.na[,3]))) A C log(data.na[, 3])
A 1.0000000 0.2813438 0.1289035
C 0.2813438 1.0000000 0.2625643
log(data.na[, 3]) 0.1289035 0.2625643 1.0000000
> cor.test(data.na[,4], data.na[,2])
Pearson's product-moment correlation
data: data.na[, 4] and data.na[, 2]
t = 2.4177, df = 68, p-value = 0.01831
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.04965218 0.48430137
sample estimates:
cor
0.2813438
> cor.test(data.na[,4], log(data.na[,3]))
Pearson's product-moment correlation
data: data.na[, 4] and log(data.na[, 3])
t = 2.2439, df = 68, p-value = 0.0281
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.02940446 0.46862610
sample estimates:
cor
0.2625643
> cor.test(data.na[,2], log(data.na[,3]))
Pearson's product-moment correlation
data: data.na[, 2] and log(data.na[, 3])
t = 1.0719, df = 68, p-value = 0.2876
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.1093837 0.3531800
sample estimates:
cor
0.1289035
Группа выделена и имеет отличный состав
Код
> table(factor(cmdscale(dist(rf1$proximity), k=2)[,2]>0.2), factor(data.na$выжил.умер))
0 1
FALSE 24 21
TRUE 9 16
во 2й группе исходы 9 к 16, в первой 24 к 21
вклад в разделение групп оказывает не один единственный предиктор, (B и С вместе)
Кружки первая группа, треугольники вторая. (На сечении С|log(B) вообще летальные исходы сгруппировались в центре и вверху. Может отработать эту нелинейность не может при разделении групп рандомфорест. Нужен какой нибудь svm или явная трансформация данных.)
Код
> pairs(cbind(data.na[,c(2,4)],
log(data.na[,3])),
pch=c(1,2)[factor(cmdscale(dist(rf1$proximity), k=2)[,2]>0.2)],
col=c("red","green")[factor(data.na$выжил.умер)])
второй вариант наоборот цветом группы, значками исходы.
линеаризирующее преобразование (!после отрезания всех явно тяжелых!):
1) берем точку среднее log(B) -- среднее C (или лучше среднее по шкалам mds) для летальных исходов
2) строим вектора с началом в этой точке и концом в точках наблюдений
3) новое пространство --- угол вектора vs его длинна
в таком пространстве должны работать линейные методы
Код
> data.leit<- data.na[data.na$C<25,]
> nrow(data.leit)
[1] 62
> model1 <- svm( выжил.умер ~ A+log(B)+C, data = data.leit, type= "C-classification")
> table(model1$decision.values<=0,data.leit$выжил.умер)
0 1
FALSE 19 5
TRUE 6 32
вот по группе без явно безнадежных (критерий C>25) svm вырезает выживших до 32.
вот так решение графически выглядит
Код
> plot(cmdscale(dist(cbind(data.leit[,c(2,4)],
log(data.leit[,3]))),
k=2),
col=c("red","green")[factor(data.leit$выжил.умер)],
pch=c(1,2)[factor(model1$decision.values<=0)])
Трансформация
Код
> tapply(data.leit[,3], data.leit$выжил.умер, mean)
0 1
12.67121 20.19569
> tapply(data.leit[,4], data.leit$выжил.умер, mean)
0 1
13.48000 11.40541
> tapply(log(data.leit[,3]), data.leit$выжил.умер, mean)
0 1
1.775605 1.189165
> ((data.leit$C-12.67121)^2+(log(data.leit$B)-1.775605)^2)^0.5
[1] 5.3311377 5.1087745 2.1709325 6.0049577 6.3416986 2.5971127
[7] 7.6488885 9.4283268 2.9613371 7.3290071 2.0874944 2.6590571
[13] 0.7077666 1.7968509 1.6400452 4.3481172 1.3288040 5.5428207
[19] 2.6856595 9.7595860 3.7072333 4.6724333 4.3954970 7.6958694
[25] 7.8144577 5.1120372 3.4003874 6.7942236 0.7232215 2.2810260
[31] 0.6200533 3.0480755 5.3432953 1.8203928 12.6712147 7.3712229
[37] 2.4614863 6.8202322 4.3332743 0.6811193 10.3318129 7.2930514
[43] 9.8974529 4.0868944 2.6899526 6.9645308 2.7174036 3.7413277
[49] 2.2007804 12.0539703 3.0041289 11.3308822 8.6715569 3.7608580
[55] 7.3350855 3.3930430 4.4240841 7.5608856 6.8246717 4.3312637
[61] 10.4496927 6.0334436
> l<-((data.leit$C-12.67121)^2+(log(data.leit$B)-1.775605)^2)^0.5
> atan2(data.leit$C-12.67121, log(data.leit$B)-1.775605)
[1] 1.60047511 1.01092706 -0.87854661 -1.90576287 1.63461177 2.02937132
[7] -2.08195084 1.42536019 -2.91294791 1.57849395 -2.21332718 2.61831456
[13] -1.24799125 0.18401803 0.20184394 1.66511774 1.56620199 1.29199482
[19] -1.67457571 -1.43611893 0.08880546 -1.54791341 -0.65318030 -1.65087067
[25] -1.37902877 -1.98913076 -2.23799124 -1.76137710 -1.95235967 -2.31937471
[31] 2.58268440 2.69050581 1.49709553 -1.16313148 -1.57165444 1.67814707
[37] 1.90064623 -1.78022440 1.52529843 0.50375801 1.54660568 -1.98674087
[43] -1.78502201 -2.02573395 -1.68891279 -1.27953913 1.02940171 -2.34643526
[49] 2.99163425 -1.82347545 -1.09554895 1.55157912 -1.56185158 -1.78957673
[55] 1.52936211 1.76571555 -2.16280092 1.81921224 -1.78326322 1.60459531
[61] 1.72306160 1.08266063
> a<-atan2(data.leit$C-12.67121, log(data.leit$B)-1.775605)
> plot(a,
l,
col=c("red","green")[factor(data.leit$выжил.умер)],
pch=c(1,2)[factor(model1$decision.values<=0)])
и в пространстве трансформированных шкал mds
Код
> data.mds<-cmdscale(dist(cbind(data.leit[,c(2,4)],log(data.leit[,3]))))
> tapply(data.mds[,1], data.leit$выжил.умер, mean)
0 1
-1.2605935 0.8517523
> tapply(data.mds[,2], data.leit$выжил.умер, mean)
0 1
-0.2579902 0.1743177
> l.mds<-((data.mds[,1]+1.2605935)^2+(data.mds[,2]+0.2579902)^2)^0.5
> a.mds<-atan2(data.leit$C-12.67121, log(data.leit$B)-1.775605)
> plot(a.mds,
l.mds,
col=c("red","green")[factor(data.leit$выжил.умер)],
pch=c(1,2)[factor(model1$decision.values<=0)])
похожую трансформацию, судя по внешнему сходству, рандом_форест и пытался сделать.
PS забыл отнормировать данные прежде чем считать длину вектора и угол

Код
> data.mds.scale<-scale(data.mds, center=c(-1.2605935, -0.2579902))
> l.mds.scale<-((data.mds.scale[,1])^2+(data.mds.scale[,2])^2)^0.5
> a.mds.scale<-atan2(data.mds.scale[,1], data.mds.scale[,2])
> plot(a.mds.scale,l.mds.scale, col=c("red","green")[factor(data.leit$выжил.умер)], , pch=c(1,2)[factor(model1$decision.values<=0)])
на картинке я зону svm приблизительно обвел, горизонтальная ось замкнута (это радианы угла вектора)
поскольку все читать утомительно я резюмирую:
решатель состоящий из правила -- все кто тяжелее 25 считать безнадежными и svm-решателя для остальных случаев дает
11 ошибок на 70 ~ 0.16
TheThing
5.08.2012 - 15:37
Решил сделать рэндом форест, а также построить простое CART, чтобы понять почему результаты расходятся с логистической регрессией и с результатами p2004r. Как выяснилось, все со всем сходится
Сначала рендом форест с 3 исходными предикторами:
randomForest(formula = Group ~ .,
data = crs$dataset[, c(crs$input, crs$target)],
ntree = 500, mtry = 1, importance = TRUE, replace = FALSE, na.action = na.roughfix)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 1
OOB estimate of error rate: 27.78%
Confusion matrix:
alive dead class.error
alive 30 9 0.2307692
dead 11 22 0.3333333
Analysis of the Area Under the Curve (AUC)
==========================================
Call:
roc.default(response = crs$rf$y, predictor = crs$rf$votes)
Data: crs$rf$votes in 39 controls (crs$rf$y alive) > 33 cases (crs$rf$y dead).
Area under the curve: 0.7584
95% CI: 0.6462-0.8706 (DeLong)
Variable Importance
===================
alive dead MeanDecreaseAccuracy
C 2.87 3.59 2.67
B 1.90 3.03 2.14
A 1.89 1.65 1.59
Ошибка OOB составляет 27,78%, что в принципе говорит, что модель неплохая (AUC = 75%)/ На первом месте по важности предикторов выступает фактор С, затем В и лишь в конце болтается А.
Решил убрать фактор А из модели и посмотреть насколько изменится классификационная способность. Вот что получилось:
OOB estimate of error rate: 31.94%
Confusion matrix:
alive dead class.error
alive 28 11 0.2820513
dead 12 21 0.3636364
Analysis of the Area Under the Curve (AUC)
==========================================
Call:
roc.default(response = crs$rf$y, predictor = crs$rf$votes)
Data: crs$rf$votes in 39 controls (crs$rf$y alive) > 33 cases (crs$rf$y dead).
Area under the curve: 0.7599
95% CI: 0.6499-0.8699 (DeLong)
Variable Importance
===================
alive dead MeanDecreaseAccuracy
C 3.51 4.77 3.26
B 1.69 3.40 2.24
Видим, что OOB увеличилась на пару процентов, а AUC остался прежним, фактор С опять на 1 месте по важности. Поэтому я бы предиктор А вообще-бы не включал в модель, а рассматривал его как ненужный "шум".
Затем построил простое CART и получил результат, который полностью совпал с методом опорных векторов (svm) в подсчетах p2004r, логистической регрессией и random forest.
Хорошо то, что хорошо заканчивается
Нажмите для просмотра прикрепленного файла
p2004r
17.08.2012 - 15:28
Цитата(Диана @ 17.08.2012 - 09:02)

КФР-контролируемый фактор риска, НФР-неконтролируемый ФР, ЗАДАЧА- выявить наиболее вероятные факторы риска для прогнозирования развития кардиальных осложнений в послеоперационном периоде
много пропущенных данных... будет интересно

у меня после импорта данных (там иногда попадаются точки в ячейках, нельзя ли сохранить таблицу с простым заголовком в старом эксель формате? а то я не уверен в корректности импорта) получились вот такие переменные:
Код
> names(read.csv2("mp3gl.csv"))
[1] "ФИО.шифр" "пол"
[3] "возраст" "ИМТ..кг.м2"
[5] "ИМТ" "S.тела.по.Дюб"
[7] "к.во.дней.до.опер" "к.во.дней.после.опер"
[9] "время.уст..я.д.за.анев" "кардио.жалобы"
[11] "длит.кардиожалоб" "хирург.жалобы"
[13] "группы.по.лечению" "п.о.кард.осложн"
[15] "Кард.осл.я" "летальность"
[17] "стресс.ЭхоКГ" "к.во.зон.гипо.и.акинезии"
[19] "X" "X.1"
[21] "ГБ" "X.2"
[23] "ГБ.ГЛЖ" "ИБС..стенокардия"
[25] "постинф.кардиоскл" "НК..фк"
[27] "ДЛП" "размер.АБА"
[29] "синдромность" "прех.ишем.послеопер"
[31] "СД" "доступ"
[33] "курение" "диаст..Дисфункция00"
[35] "САД1" "ДАД1"
[37] "ЧСС1" "САД5"
[39] "ДАД5" "ЧСС5"
[41] "САД.д.о" "ДАД.д.о"
[43] "ЧСС.д.о" "САД.п.о"
[45] "ДАД.п.о" "ЧСС.п.о"
[47] "бета.блокеры" "ББдоза"
[49] "ББкол.во.суток.назн" "антаг.кальция"
[51] "АКдоза.суточная" "АКкол.во.сут.назн"
[53] "антиагреганты" "инг.АПФ"
[55] "ИАПФсут.доза" "ИАПФкол.во.сут.назн"
[57] "нитраты" "дигоксин"
[59] "диуретики" "кордарон"
[61] "гепарин" "трад.тер"
[63] "операция1" "доступ1"
[65] "время.операции1" "Время.опер.11"
[67] "Время.опер.21" "Время.опер.31"
[69] "время.переж.аорты1" "Вр.переж.аорты11"
[71] "Вр.переж.аорты21" "кровопотеря1"
[73] "кровопотеря11" "наруш.ритма00"
[75] "рубц.измен00" "ЧСС00"
[77] "ритм00" "наруш.пров00"
[79] "PQ" "QRS"
[81] "QT" "ST"
[83] "з.Т" "Соколов.Лайон"
[85] "корн..Индекс" "корн..Произв.е"
[87] "минЧСС" "максЧСС"
[89] "средЧСС" "ЖЭС"
[91] "ЖЭС..к.во" "ЖТ"
[93] "НЖЭС..к.во" "НЖТ..к.во"
[95] "депрессия.ST" "АВ.блокады"
[97] "пароксизмы.ФП" "ГЛЖ00"
[99] "X.3" "зоны.гипо.и.акин00"
[101] "КДР..см00" "КСР..см00"
[103] "КДО..мл00" "индекс.КДО..00"
[105] "КСО00" "инд.КСО00"
[107] "ФВ00" "УО00"
[109] "ТМЖП00" "ТЗСТ.ЛЖ00"
[111] "X.4" "ММ.ЛЖ.формула.Devereux"
[113] "ИММ.ЛЖ" "ПЗРВТ.00"
[115] "КДР.ПЖ00" "ЛП00"
[117] "d.аорты00" "ГДС.СДЛА00"
[119] "диаст..Дисфункция00.1" "кальциноз.аорты00"
[121] "наруш.ритма11" "ЧСС11"
[123] "PQ11" "QRS11"
[125] "QT11" "депрессия.ST11"
[127] "з.Т11" "длит.ть.прех.ишемии11"
[129] "очаг.измен11" "мин.ЧСС11"
[131] "макс.ЧСС11" "средняя.ЧСС11"
[133] "ЖЭС.по.Лауну11" "ЖЭС..к.во11"
[135] "парные.ЖЭС11" "ЖТ11"
[137] "НЖЭС.к.во11" "НЖТ.к.во11"
[139] "депрессия.SТ11" "нар.е.пров11"
[141] "пароксизмы.ФП11" "п.о.гипокинезия11"
[143] "КДР11" "КСР11"
[145] "КДО11" "инд.КДО11"
[147] "КСО11" "инд.КСО11"
[149] "ФВ11" "УО11"
[151] "ТМЖП11" "ТЗСТ.ЛЖ11"
[153] "ММ.ЛЖ.формула.Devereux.1" "ИММ.ЛЖ.1"
[155] "ПЗРВТ.11" "КДР.ПЖ11"
[157] "ЛП11" "d.аорты11"
[159] "ГДС.СДЛА11" "бета.блокеры11"
[161] "доза11ББ" "ББкол.во.суток.назначения.пре11"
[163] "антагонисты.кальция11" "АГдоза.суточная11"
[165] "АГкол.во.суток.назн11" "антиагреганты11"
[167] "инг.АПФ11" "ИАПФсуточная.доза11"
[169] "ИАПФкол.во.суток.назн11" "нитраты11"
[171] "дигоксин11" "диуретики11"
[173] "кордарон11" "гепарин11"
[175] "трад.терапия11"
какие номера являются осложнениями? или какие являются предикторами?
вот например я предполагаю что осложнение это:
Код
> (read.csv2("mp3gl.csv")$"постинф.кардиоскл")
[1] 1 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0
[39] 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 1
[77] 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 0
а предикторы это со 2 по 18ю
Код
> names(data[,2:18])
[1] "пол" "возраст"
[3] "ИМТ..кг.м2" "ИМТ"
[5] "S.тела.по.Дюб" "к.во.дней.до.опер"
[7] "к.во.дней.после.опер" "время.уст..я.д.за.анев"
[9] "кардио.жалобы" "длит.кардиожалоб"
[11] "хирург.жалобы" "группы.по.лечению"
[13] "п.о.кард.осложн" "Кард.осл.я"
[15] "летальность" "стресс.ЭхоКГ"
[17] "к.во.зон.гипо.и.акинезии"
поскольку среди предикторов много пропусков перед нами два пути:
1) исключить случаи в которых есть пропуски
Код
> data.na<-na.omit(data[,c(2:18,25)])
> table(data.na$постинф.кардиоскл)
0 1
8 18
> rf<-randomForest(data.na[,-18],factor(data.na$"постинф.кардиоскл"), proximity=TRUE)
> rf
Call:
randomForest(x = data.na[, -18], y = factor(data.na$постинф.кардиоскл), proximity = TRUE)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 4
OOB estimate of error rate: 38.46%
Confusion matrix:
0 1 class.error
0 0 8 1.0000000
1 2 16 0.1111111
> MDSplot(rf, factor(data.na$"постинф.кардиоскл"), k=3)
> varImpPlot(rf)
как видим ничего в таком варианте модель не разделяет ничего.
2) заполним пропущенные случаи прибегнув к множественной импутации
Код
> data.2.18.impute<-rfImpute(data[,2:18],factor(data$"постинф.кардиоскл"), iter=5)
ntree OOB 1 2
300: 26.32% 10.94% 58.06%
ntree OOB 1 2
300: 27.37% 14.06% 54.84%
ntree OOB 1 2
300: 27.37% 15.62% 51.61%
ntree OOB 1 2
300: 26.32% 14.06% 51.61%
ntree OOB 1 2
300: 29.47% 17.19% 54.84%
> rf.impute<-randomForest(data.2.18.impute[,-1],data.2.18.impute[,1], proximity=TRUE)
> rf.impute
Call:
randomForest(x = data.2.18.impute[, -1], y = data.2.18.impute[, 1], proximity = TRUE)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 4
OOB estimate of error rate: 29.47%
Confusion matrix:
0 1 class.error
0 54 10 0.1562500
1 18 13 0.5806452
> MDSplot(rf.impute, data.2.18.impute[,1], k=3)
> varImpPlot(rf.impute)
> plot(importance(rf.impute),varUsed(rf.impute))
> text(importance(rf.impute),varUsed(rf.impute), labels= names(data.2.18.impute[,-1]))
получается имеют влияние предикторы: "ИМТ..кг.м2", "к.во.зон.гипо.и.акинезии", "длит.кардиожалоб", "возраст", "к.во.дней.после.опер".
меньше влияет "к.во.дней.до.опер".
и совсем слабо (но еще влияет) "S.тела.по.Дюб", "кардио.жалобы", "стресс.ЭхоКГ", "хирург.жалобы", "группы.по.лечению".
Естественно эту информацию можно накопить относительно различных осложнений и построить общую картину.
Так какие показатели являются осложнениями? или какие являются предикторами к осложнениям? Скорее всего "группы.по.лечению" я зря в предикторы включал?