#r #cluster-analysis #k-means #confusion-matrix
#r #кластерный анализ #k- означает #путаница-матрица
Вопрос:
Я просмотрел StackOverflow и другие форумы в поисках решения, но мне еще предстоит найти решение, которое просто использует Base-R — это то, что мне нужно использовать для этого.
Я пытаюсь максимизировать диагональ в матрице NxN по строкам, поэтому максимальное значение из этой строки находится по диагонали (я надеюсь, что это имеет смысл — особенно в контексте кластерного анализа)
До сих пор я пытался это кодировать, но это кажется контрпродуктивным — это было сделано путем попытки создать функцию ‘swap’, используя цикл for по столбцам и меняя местами необходимые записи. т.е. в строке 1: 1,3,4,7 -> 7,3,4,1 строка 2: 4,10,14,22 -> 4,22,14,10 и т.д.
Вот пример матрицы, которую я бы попытался использовать:
CM <- table(expected, predicted)
CM
1 2 3 4
A 11 1 0 66
B 0 22 77 18
C 10 49 34 48
D 0 46 31 49
#Desired:
CM
1 2 3 4
A 66 1 0 11 #max 66
B 0 77 22 18 #max 77
C 10 34 49 48 #max 49
D 0 46 31 49 #max 49
Вот выдержка из (ужасной) функции подкачки, которая не сработала.
swap <- function(x,y){
a = c() #create an empty vector
a <- x #assign x value to a (where x = diagonal location)
x <- y #assign y to x (where y = maximum value
y <- a #re-assign a value back to y
}
выше показано, как я ожидал бы результатов — я надеялся, что кто-нибудь может предоставить мне какой-нибудь полезный псевдокод или сообщить мне, если я что-то упустил.
Извините, если это простой или очевидный вопрос!
Ответ №1:
Итак, глядя на это, кажется, что вы хотите перебирать матрицу строка за строкой и изменять каждую строку, меняя местами максимальный элемент с элементом по диагонали. Моя идея о том, как это сделать, состоит в том, чтобы использовать эту функцию подкачки:
swap <- function(matrixRow,x,y){
#x is diagonal index
#y is max of the row
indexY <- which(matrixRow == y)
valX <- matrixRow[x]
matrixRow[x] <- y
matrixRow[indexY] <- valX
return(matrixRow)
}
Это вернет измененную версию строки. Затем вы могли бы назначить эту новую версию строки текущей строке. Например,
vals <- c(11,0,10,0, 1,22,49,46, 0, 77, 34, 31, 66, 18, 48, 49)
mat <- matrix(vals, nrow = 4)
Редактировать: woops нажал не ту клавишу, и она опубликована слишком рано. вот остальное:
for(i in 1:nrow(mat)){
rowI <- mat[i,]
y <- max(rowI)
mat[i,] <- swap(rowI, i, y)
}
Комментарии:
1. прекрасный метод, работал, как ожидалось, и без проблем.
Ответ №2:
Предыдущий способ сделать это — реализовать венгерский алгоритм.
Простой выбор максимума в каждой строке не обязательно максимизирует диагональ, потому что максимум в одной строке может быть незначительно лучше, чем второй по величине, в то время как выбор второго по величине позволит вам получить гораздо большее значение в другой строке.
Комментарии:
1. Да, я понял, что мой вопрос на самом деле не касался того, что я хотел сделать. Позорное кодирование венгерского метода без пакетов очень сложно.
Ответ №3:
Чтобы добавить к предложению венгерского алгоритма для тех, кто использует Python (я нашел этот комментарий в поиске решения на Python.)
Вот фрагмент кода самой высокой переупорядоченной матрицы, так что диагональ имеет все лучшие «кластеризации».
y — вектор истинных меток.
pred — вектор меток кластера.
linear_sum_assignment — это венгерский алгоритм.
-cm — максимизировать, cm — минимизировать.
conditionency_matrix — это не самый высокий диагональный порядок кластеров, фактический или прогнозируемый.
Выходные данные показывают диагональ кластеризации наилучшего случая точно так же, как диагональ матрицы путаницы показывает «правильные» прогнозы.
from sklearn.metrics.cluster import contingency_matrix as CM
from scipy.optimize import linear_sum_assignment
cm = CM(y,pred)
row_idx, col_idx = linear_sum_assignment(-cm) #-cm to maximize, o/w it minimizes
print(cm[row_idx,col_idx])