Форум врачей-аспирантов

Здравствуйте, гость ( Вход | Регистрация )

 
Добавить ответ в эту темуОткрыть тему
> Как выделить сочетания признаков?, Есть девять признаков (поражений) надо выделить самые частые сочетания
Листопадничек
сообщение 19.10.2014 - 20:36
Сообщение #1





Группа: Пользователи
Сообщений: 1
Регистрация: 19.10.2014
Пользователь №: 26750



Здравствуйте, коллеги. Проблема такая: в конце работы возникла потребность выделить наиболее частые сочетания поражений. Имеется девять видов поражений, которые выявлены у определенного процента обследованных пациентов. И было бы неплохо как-то обозначить, какие именно сочетания этих поражений встречаются чаще.
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
anserovtv
сообщение 19.10.2014 - 21:50
Сообщение #2





Группа: Пользователи
Сообщений: 219
Регистрация: 4.06.2013
Из: Тверь
Пользователь №: 24927



Такие задачи можно решать с помощью TURF-анализа. Читайте http://alexwin1961.livejournal.com/86183.html
Программная реализация есть в SPSS версии 22 ( но обновленной!).
Процедура не является очень сложной.
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 19.10.2014 - 21:54
Сообщение #3





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Цитата(Листопадничек @ 19.10.2014 - 20:36) *
Здравствуйте, коллеги. Проблема такая: в конце работы возникла потребность выделить наиболее частые сочетания поражений. Имеется девять видов поражений, которые выявлены у определенного процента обследованных пациентов. И было бы неплохо как-то обозначить, какие именно сочетания этих поражений встречаются чаще.


ну так посчитайте сочетания, что тут трудного?

поскольку данных как всегда нет, эмулируем нашего пациента:

Код
> x<-sample(c(1,0), 9, replace=TRUE)
> x
[1] 0 0 1 0 0 1 0 0 1


все сочетания осложнений у него получаем вот так:

Код
> outer(x, x, FUN=paste0)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] "00" "00" "01" "00" "00" "01" "00" "00" "01"
[2,] "00" "00" "01" "00" "00" "01" "00" "00" "01"
[3,] "10" "10" "11" "10" "10" "11" "10" "10" "11"
[4,] "00" "00" "01" "00" "00" "01" "00" "00" "01"
[5,] "00" "00" "01" "00" "00" "01" "00" "00" "01"
[6,] "10" "10" "11" "10" "10" "11" "10" "10" "11"
[7,] "00" "00" "01" "00" "00" "01" "00" "00" "01"
[8,] "00" "00" "01" "00" "00" "01" "00" "00" "01"
[9,] "10" "10" "11" "10" "10" "11" "10" "10" "11"


но нас интересуют только уникальные "над или под диагональю":

Код
> outer(x, x, FUN=paste0)[upper.tri(matrix(nrow=9, ncol=9))]
[1] "00" "01" "01" "00" "00" "10" "00" "00" "10" "00" "01" "01" "11" "01" "01"
[16] "00" "00" "10" "00" "00" "10" "00" "00" "10" "00" "00" "10" "00" "01" "01"
[31] "11" "01" "01" "11" "01" "01"


объединяем все в функцию позволяющую получить данные одного пациента:

Код
> get.probe <- function(n=9) {x<-sample(c(1,0), n, replace=TRUE); outer(x, x, FUN=paste0)[upper.tri(matrix(nrow=n, ncol=n))]}
> get.probe()
[1] "10" "11" "01" "10" "00" "10" "10" "00" "10" "00" "10" "00" "10" "00" "00"
[16] "10" "00" "10" "00" "00" "00" "11" "01" "11" "01" "01" "01" "01" "11" "01"
[31] "11" "01" "01" "01" "01" "11"


получаем группу пациентов теперь (для компактности вывода они в "столбцах" smile.gif )

Код
> replicate(10, get.probe())
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "01" "10" "11" "11" "01" "10" "00" "10" "00" "10"
[2,] "00" "10" "11" "11" "01" "10" "00" "10" "01" "11"
[3,] "10" "00" "11" "11" "11" "00" "00" "00" "01" "01"
[4,] "01" "11" "10" "10" "00" "10" "01" "10" "00" "10"
[5,] "11" "01" "10" "10" "10" "00" "01" "00" "00" "00"
[6,] "01" "01" "10" "10" "10" "00" "01" "00" "10" "10"
[7,] "01" "10" "11" "10" "00" "11" "00" "10" "01" "11"
[8,] "11" "00" "11" "10" "10" "01" "00" "00" "01" "01"
[9,] "01" "00" "11" "10" "10" "01" "00" "00" "11" "11"
[10,] "11" "10" "01" "00" "00" "01" "10" "00" "01" "01"
[11,] "00" "10" "10" "11" "00" "11" "00" "11" "01" "10"
[12,] "10" "00" "10" "11" "10" "01" "00" "01" "01" "00"
[13,] "00" "00" "10" "11" "10" "01" "00" "01" "11" "10"
[14,] "10" "10" "00" "01" "00" "01" "10" "01" "01" "00"
[15,] "10" "00" "10" "01" "00" "11" "00" "01" "11" "10"
[16,] "01" "11" "11" "10" "01" "10" "00" "11" "00" "10"
[17,] "11" "01" "11" "10" "11" "00" "00" "01" "00" "00"
[18,] "01" "01" "11" "10" "11" "00" "00" "01" "10" "10"
[19,] "11" "11" "01" "00" "01" "00" "10" "01" "00" "00"
[20,] "11" "01" "11" "00" "01" "10" "00" "01" "10" "10"
[21,] "01" "01" "01" "10" "01" "10" "00" "11" "10" "00"
[22,] "01" "10" "11" "10" "01" "10" "01" "10" "00" "10"
[23,] "11" "00" "11" "10" "11" "00" "01" "00" "00" "00"
[24,] "01" "00" "11" "10" "11" "00" "01" "00" "10" "10"
[25,] "11" "10" "01" "00" "01" "00" "11" "00" "00" "00"
[26,] "11" "00" "11" "00" "01" "10" "01" "00" "10" "10"
[27,] "01" "00" "01" "10" "01" "10" "01" "10" "10" "00"
[28,] "11" "10" "11" "00" "11" "00" "01" "10" "00" "00"
[29,] "01" "11" "10" "11" "01" "10" "01" "11" "01" "10"
[30,] "11" "01" "10" "11" "11" "00" "01" "01" "01" "00"
[31,] "01" "01" "10" "11" "11" "00" "01" "01" "11" "10"
[32,] "11" "11" "00" "01" "01" "00" "11" "01" "01" "00"
[33,] "11" "01" "10" "01" "01" "10" "01" "01" "11" "10"
[34,] "01" "01" "00" "11" "01" "10" "01" "11" "11" "00"
[35,] "11" "11" "10" "01" "11" "00" "01" "11" "01" "00"
[36,] "11" "01" "10" "01" "11" "00" "11" "01" "01" "00"


любое сочетание можно оценить применив table():

Код
> table(replicate(100, get.probe())[1,])

00 01 10 11
27 23 29 21


ну или все сочетания одновременно:

Код
> d <- replicate(100, get.probe())
> t(sapply(1:nrow(d), function(i) table(d[i,])))
      00 01 10 11
[1,] 28 22 22 28
[2,] 18 32 21 29
[3,] 22 28 17 33
[4,] 26 24 29 21
[5,] 27 23 28 22
[6,] 23 16 32 29
[7,] 25 25 24 26
[8,] 26 24 23 27
[9,] 18 21 31 30
[10,] 28 27 21 24
[11,] 24 26 25 25
[12,] 23 27 26 24
[13,] 21 18 28 33
[14,] 25 30 24 21
[15,] 24 25 25 26
[16,] 23 27 29 21
[17,] 20 30 32 18
[18,] 18 21 34 27
[19,] 26 29 26 19
[20,] 22 27 30 21
[21,] 27 22 25 26
[22,] 25 25 27 23
[23,] 27 23 25 25
[24,] 20 19 32 29
[25,] 31 24 21 24
[26,] 31 18 21 30
[27,] 28 21 24 27
[28,] 25 27 27 21
[29,] 22 28 24 26
[30,] 22 28 24 26
[31,] 17 22 29 32
[32,] 24 31 22 23
[33,] 25 24 21 30
[34,] 26 23 20 31
[35,] 26 26 20 28
[36,] 25 27 21 27


когда не все уровни в таблице населены, то понадобится их "прибить" гвоздями smile.gif

Код
> d <- replicate(10, get.probe())
> t(sapply(1:nrow(d), function(i) table(factor(d[i,], levels=c("00","01","10","11")))) )
      00 01 10 11
[1,]  2  2  5  1
[2,]  1  3  5  1
[3,]  5  2  1  2
[4,]  0  4  3  3
[5,]  2  5  1  2
[6,]  3  3  0  4
[7,]  3  1  4  2
[8,]  6  1  1  2
[9,]  4  2  3  1
[10,]  2  1  5  2
[11,]  2  2  6  0
[12,]  6  1  2  1
[13,]  6  0  2  2
[14,]  3  0  5  2
[15,]  6  1  2  1
[16,]  2  2  1  5
[17,]  1  6  2  1
[18,]  2  4  1  3
[19,]  1  2  2  5
[20,]  2  5  1  2
[21,]  3  5  0  2
[22,]  2  2  4  2
[23,]  5  2  1  2
[24,]  3  3  3  1
[25,]  1  2  5  2
[26,]  5  2  1  2
[27,]  5  3  1  1
[28,]  1  2  5  2
[29,]  2  2  2  4
[30,]  4  3  0  3
[31,]  2  4  2  2
[32,]  0  3  4  3
[33,]  3  4  1  2
[34,]  3  5  1  1
[35,]  1  2  3  4
[36,]  3  3  1  3


как то так smile.gif


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 19.10.2014 - 22:31
Сообщение #4





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Цитата(anserovtv @ 19.10.2014 - 21:50) *
Такие задачи можно решать с помощью TURF-анализа. Читайте http://alexwin1961.livejournal.com/86183.html
Программная реализация есть в SPSS версии 22 ( но обновленной!).
Процедура не является очень сложной.


ну такое ещё проще, вот 10 пациентов:

Код
> d<-replicate(10, sample(c(1,0), 9, replace=TRUE))
> d
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    0    0    1    1    0    1    1    0     0
[2,]    0    0    1    0    1    0    1    0    1     0
[3,]    0    0    0    0    0    0    1    1    0     1
[4,]    1    1    1    0    0    1    1    0    1     0
[5,]    1    0    1    0    1    0    1    0    0     0
[6,]    0    1    0    0    0    0    1    0    0     0
[7,]    0    0    0    0    0    1    0    0    0     1
[8,]    1    1    1    0    0    0    0    1    0     1
[9,]    1    1    1    1    1    1    1    1    0     0


вот их сочетания "Maximum Group Size: 3." smile.gif

"сырые"

Код
> dd <- sapply(1:10, function(ii) combn(9, 3, FUN=function(i) do.call(paste0,as.list(d[i,ii]))))
      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]  [,10]
[1,] "101" "001" "000" "011" "001" "010" "000" "111" "101" "010"
[2,] "101" "000" "000" "010" "000" "010" "001" "110" "101" "010"
[3,] "100" "000" "000" "011" "001" "011" "000" "111" "101" "011"
[4,] "101" "001" "001" "010" "001" "010" "000" "110" "101" "010"
[5,] "101" "000" "000" "011" "000" "011" "001" "110" "100" "010"
[6,] "100" "000" "001" "011" "001" "010" "001" "110" "101" "011"
[7,] "101" "000" "001" "010" "001" "011" "001" "111" "101" "010"
[8,] "111" "010" "000" "010" "010" "000" "001" "110" "111" "000"
[9,] "110" "010" "000" "011" "011" "001" "000" "111" "111" "001"
[10,] "111" "011" "001" "010" "011" "000" "000" "110" "111" "000"
[11,] "111" "010" "000" "011" "010" "001" "001" "110" "110" "000"
[12,] "110" "010" "001" "011" "011" "000" "001" "110" "111" "001"
[13,] "111" "010" "001" "010" "011" "001" "001" "111" "111" "000"
[14,] "110" "000" "000" "001" "001" "001" "010" "101" "111" "001"
[15,] "111" "001" "001" "000" "001" "000" "010" "100" "111" "000"
[16,] "111" "000" "000" "001" "000" "001" "011" "100" "110" "000"
[17,] "110" "000" "001" "001" "001" "000" "011" "100" "111" "001"
[18,] "111" "000" "001" "000" "001" "001" "011" "101" "111" "000"
[19,] "101" "001" "001" "010" "011" "010" "000" "110" "111" "010"
[20,] "101" "000" "000" "011" "010" "011" "001" "110" "110" "010"
[21,] "100" "000" "001" "011" "011" "010" "001" "110" "111" "011"
[22,] "101" "000" "001" "010" "011" "011" "001" "111" "111" "010"
[23,] "111" "010" "010" "001" "010" "001" "001" "100" "110" "000"
[24,] "110" "010" "011" "001" "011" "000" "001" "100" "111" "001"
[25,] "111" "010" "011" "000" "011" "001" "001" "101" "111" "000"
[26,] "110" "000" "001" "011" "001" "010" "011" "100" "101" "001"
[27,] "111" "000" "001" "010" "001" "011" "011" "101" "101" "000"
[28,] "101" "000" "011" "010" "011" "001" "011" "101" "111" "010"
[29,] "011" "010" "000" "110" "010" "100" "001" "110" "011" "100"
[30,] "010" "010" "000" "111" "011" "101" "000" "111" "011" "101"
[31,] "011" "011" "001" "110" "011" "100" "000" "110" "011" "100"
[32,] "011" "010" "000" "111" "010" "101" "001" "110" "010" "100"
[33,] "010" "010" "001" "111" "011" "100" "001" "110" "011" "101"
[34,] "011" "010" "001" "110" "011" "101" "001" "111" "011" "100"
[35,] "010" "000" "000" "101" "001" "101" "010" "101" "011" "101"
[36,] "011" "001" "001" "100" "001" "100" "010" "100" "011" "100"
[37,] "011" "000" "000" "101" "000" "101" "011" "100" "010" "100"
[38,] "010" "000" "001" "101" "001" "100" "011" "100" "011" "101"
[39,] "011" "000" "001" "100" "001" "101" "011" "101" "011" "100"
[40,] "001" "001" "001" "110" "011" "110" "000" "110" "011" "110"
[41,] "001" "000" "000" "111" "010" "111" "001" "110" "010" "110"
[42,] "000" "000" "001" "111" "011" "110" "001" "110" "011" "111"
[43,] "001" "000" "001" "110" "011" "111" "001" "111" "011" "110"
[44,] "011" "010" "010" "101" "010" "101" "001" "100" "010" "100"
[45,] "010" "010" "011" "101" "011" "100" "001" "100" "011" "101"
[46,] "011" "010" "011" "100" "011" "101" "001" "101" "011" "100"
[47,] "010" "000" "001" "111" "001" "110" "011" "100" "001" "101"
[48,] "011" "000" "001" "110" "001" "111" "011" "101" "001" "100"
[49,] "001" "000" "011" "110" "011" "101" "011" "101" "011" "110"
[50,] "110" "100" "000" "101" "101" "001" "010" "101" "111" "001"
[51,] "111" "101" "001" "100" "101" "000" "010" "100" "111" "000"
[52,] "111" "100" "000" "101" "100" "001" "011" "100" "110" "000"
[53,] "110" "100" "001" "101" "101" "000" "011" "100" "111" "001"
[54,] "111" "100" "001" "100" "101" "001" "011" "101" "111" "000"
[55,] "101" "101" "001" "110" "111" "010" "000" "110" "111" "010"
[56,] "101" "100" "000" "111" "110" "011" "001" "110" "110" "010"
[57,] "100" "100" "001" "111" "111" "010" "001" "110" "111" "011"
[58,] "101" "100" "001" "110" "111" "011" "001" "111" "111" "010"
[59,] "111" "110" "010" "101" "110" "001" "001" "100" "110" "000"
[60,] "110" "110" "011" "101" "111" "000" "001" "100" "111" "001"
[61,] "111" "110" "011" "100" "111" "001" "001" "101" "111" "000"
[62,] "110" "100" "001" "111" "101" "010" "011" "100" "101" "001"
[63,] "111" "100" "001" "110" "101" "011" "011" "101" "101" "000"
[64,] "101" "100" "011" "110" "111" "001" "011" "101" "111" "010"
[65,] "101" "001" "001" "010" "011" "010" "100" "010" "111" "010"
[66,] "101" "000" "000" "011" "010" "011" "101" "010" "110" "010"
[67,] "100" "000" "001" "011" "011" "010" "101" "010" "111" "011"
[68,] "101" "000" "001" "010" "011" "011" "101" "011" "111" "010"
[69,] "111" "010" "010" "001" "010" "001" "101" "000" "110" "000"
[70,] "110" "010" "011" "001" "011" "000" "101" "000" "111" "001"
[71,] "111" "010" "011" "000" "011" "001" "101" "001" "111" "000"
[72,] "110" "000" "001" "011" "001" "010" "111" "000" "101" "001"
[73,] "111" "000" "001" "010" "001" "011" "111" "001" "101" "000"
[74,] "101" "000" "011" "010" "011" "001" "111" "001" "111" "010"
[75,] "011" "010" "010" "101" "110" "101" "001" "100" "110" "100"
[76,] "010" "010" "011" "101" "111" "100" "001" "100" "111" "101"
[77,] "011" "010" "011" "100" "111" "101" "001" "101" "111" "100"
[78,] "010" "000" "001" "111" "101" "110" "011" "100" "101" "101"
[79,] "011" "000" "001" "110" "101" "111" "011" "101" "101" "100"
[80,] "001" "000" "011" "110" "111" "101" "011" "101" "111" "110"
[81,] "110" "100" "101" "011" "101" "010" "011" "000" "101" "001"
[82,] "111" "100" "101" "010" "101" "011" "011" "001" "101" "000"
[83,] "101" "100" "111" "010" "111" "001" "011" "001" "111" "010"
[84,] "101" "000" "011" "110" "011" "101" "111" "001" "011" "010"


и отсортированные в порядке убывания частоты одной комбинации

Код
> head(dd[order(sapply(1:nrow(dd), function(i)max(table(dd[i,]))), decreasing=TRUE),])
     [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]  [,10]
[1,] "101" "001" "001" "101" "101" "011" "101" "101" "000" "010"
[2,] "000" "010" "000" "000" "000" "001" "110" "100" "000" "101"
[3,] "001" "011" "001" "001" "001" "001" "111" "101" "000" "100"
[4,] "001" "001" "001" "001" "001" "011" "101" "101" "000" "110"
[5,] "001" "101" "001" "001" "001" "011" "101" "001" "000" "010"
[6,] "101" "001" "001" "100" "100" "001" "111" "110" "001" "010"


ну и номера "осложнений" этих комбинаций

Код
> head(t(combn(9,3))[order(sapply(1:nrow(dd), function(i)max(table(dd[i,]))), decreasing=TRUE),])
     [,1] [,2] [,3]
[1,]    1    7    9
[2,]    3    6    7
[3,]    3    6    9
[4,]    3    7    9
[5,]    6    7    9
[6,]    1    3    4


можно всё легко объединить в одну функцию.


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
nokh
сообщение 20.10.2014 - 18:46
Сообщение #5





Группа: Пользователи
Сообщений: 1202
Регистрация: 13.01.2008
Из: Челябинск
Пользователь №: 4704



Цитата(Листопадничек @ 19.10.2014 - 23:36) *
Здравствуйте, коллеги. Проблема такая: в конце работы возникла потребность выделить наиболее частые сочетания поражений. Имеется девять видов поражений, которые выявлены у определенного процента обследованных пациентов. И было бы неплохо как-то обозначить, какие именно сочетания этих поражений встречаются чаще.

Самый тупой способ - просто посчитать в лоб все ассоциации smile.gif и выделить наиболее частые. Из программных реализаций здесь вполне подойдёт поиск ассоциативных правил по алгоритму "Apriori", который есть во всех пакетах и/или модулях Data mining. Когда я этим интересовался (лет 10 назад), то делал в Deductor (http://www.basegroup.ru/ в демо-версии Lite было некритичное для моих выборок ограничение на размер базы данных) и Weka (http://www.cs.waikato.ac.nz/ml/weka/ бесплатная на Java). Сейчас наверное ещё много чего добавилось доступного...
Если более осмысленно, то к ассоциациям признаков приводят какие-то сходные процессы. Можно исходя из данных по совстречаемости признаков выйти именно на эти процессы. Для этого используются многомерные статистические методы. Для качественных альтернативных признаков (ваш случай) традиционно используется анализ соответствий или анализ главных координат. Почитайте про эти техники, если понравится - могу подсказать как провести такой анализ в бесплатном пакете PAST. Пусть он не такой крутой как среда R, но имеет графический интерфейс (что очень хорошо для начала пути) и хорошо справляется с такими задачами. Желательно выложить данные или их часть в виде таблицы: в строках - пациенты, в столбцах - поражения, на пересечениях цифры - 0 (нет) или 1 (есть). Названия поражений можете нам не давать, просто "поражение 1", "поражение 2"... Заодно с кодами p2004r попрактикуемся...

Сообщение отредактировал nokh - 20.10.2014 - 18:51
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 

Добавить ответ в эту темуОткрыть тему