Как выделить сочетания признаков?, Есть девять признаков (поражений) надо выделить самые частые сочетания |
Здравствуйте, гость ( Вход | Регистрация )
Как выделить сочетания признаков?, Есть девять признаков (поражений) надо выделить самые частые сочетания |
19.10.2014 - 20:36
Сообщение
#1
|
|
Группа: Пользователи Сообщений: 1 Регистрация: 19.10.2014 Пользователь №: 26750 |
Здравствуйте, коллеги. Проблема такая: в конце работы возникла потребность выделить наиболее частые сочетания поражений. Имеется девять видов поражений, которые выявлены у определенного процента обследованных пациентов. И было бы неплохо как-то обозначить, какие именно сочетания этих поражений встречаются чаще.
|
|
19.10.2014 - 21:50
Сообщение
#2
|
|
Группа: Пользователи Сообщений: 219 Регистрация: 4.06.2013 Из: Тверь Пользователь №: 24927 |
Такие задачи можно решать с помощью TURF-анализа. Читайте http://alexwin1961.livejournal.com/86183.html
Программная реализация есть в SPSS версии 22 ( но обновленной!). Процедура не является очень сложной. |
|
19.10.2014 - 21:54
Сообщение
#3
|
|
Группа: Пользователи Сообщений: 1091 Регистрация: 26.08.2010 Пользователь №: 22699 |
Здравствуйте, коллеги. Проблема такая: в конце работы возникла потребность выделить наиболее частые сочетания поражений. Имеется девять видов поражений, которые выявлены у определенного процента обследованных пациентов. И было бы неплохо как-то обозначить, какие именно сочетания этих поражений встречаются чаще. ну так посчитайте сочетания, что тут трудного? поскольку данных как всегда нет, эмулируем нашего пациента: Код > 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" получаем группу пациентов теперь (для компактности вывода они в "столбцах" ) Код > 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 когда не все уровни в таблице населены, то понадобится их "прибить" гвоздями Код > 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 как то так |
|
19.10.2014 - 22:31
Сообщение
#4
|
|
Группа: Пользователи Сообщений: 1091 Регистрация: 26.08.2010 Пользователь №: 22699 |
Такие задачи можно решать с помощью 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." "сырые" Код > 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 можно всё легко объединить в одну функцию. |
|
20.10.2014 - 18:46
Сообщение
#5
|
|
Группа: Пользователи Сообщений: 1202 Регистрация: 13.01.2008 Из: Челябинск Пользователь №: 4704 |
Здравствуйте, коллеги. Проблема такая: в конце работы возникла потребность выделить наиболее частые сочетания поражений. Имеется девять видов поражений, которые выявлены у определенного процента обследованных пациентов. И было бы неплохо как-то обозначить, какие именно сочетания этих поражений встречаются чаще. Самый тупой способ - просто посчитать в лоб все ассоциации и выделить наиболее частые. Из программных реализаций здесь вполне подойдёт поиск ассоциативных правил по алгоритму "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 |
|