У меня очень большая разреженная матрица в Octave, и я хочу получить дисперсию каждой строки. Если я использую std(A,1);
, он падает, потому что память исчерпана. Почему это? Отклонение должно быть очень легко вычислить для разреженной матрицы, не так ли? Как я могу сделать эту работу?Октава: std на разреженной матрице, слишком интенсивной памяти
ответ
Если вы хотите, стандартное отклонение только ненулевых элементов в каждом столбце, то вы можете сделать:
[nrows, ncols] = size(A);
counts = sum(spones(A),1);
means = sum(A,1) ./ max(counts, 1);
[i,j,v] = find(A);
v = means(j);
placedmeans = sparse(i,j,v,nrows,ncols);
vars = sum((A - placedmeans).^2, 1) ./ max(counts, 1);
stds = sqrt(vars);
Я не могу представить себе ситуацию, в которой вы хотели бы принять стандартные отклонения всех члены в каждой колонке разреженной матрицы (включая нули), но если да, то вам нужно только подсчитать количество нулей в каждом столбце и включить их в расчетах:
[nrows,ncols] = size(A);
zerocounts = nrows - sum(spones(A),1);
means = sum(A,1) ./ nrows;
[i,j,v] = find(A);
v = means(j);
placedmeans = sparse(i,j,v,nrows,ncols);
vars = (sum((A - placedmeans).^2, 1) + zerocounts .* means.^2) ./ nrows;
stds = sqrt(vars);
Кроме того, я не знаю, если вы хотите вычесть один из знаменателя vars (counts и nrows respe ctively).
EDIT: исправлена ошибка, которая восстанавливает помещенную матрицу неправильного размера, когда A заканчивается в строке или столбце всех нулей. Кроме того, первый случай теперь возвращает среднее значение/var/std нуля всякий раз, когда столбец имеет все нули (тогда как раньше он был бы NaN)
Это почти работает, но, похоже, есть ошибка. Мне нужна вторая версия, которая также учитывает нули. К сожалению, он не работает, если в матрице содержится целая строка с нулями в конце. Это дает исключение из измерений в этом случае. Вы знаете, почему это так? –
Хорошо, это был глупый комментарий. Вы не можете принять дисперсию строки, полной нулей. Знаете ли вы, как я мог бы изменить вышеуказанный код, чтобы те, у кого нет записей, получили 0 как дисперсию? –
Вы можете абсолютно принять дисперсию строки, полной нулей. Он равен нулю. (Однако вы не можете принять дисперсию пустого списка, поэтому я изменил первую версию, чтобы дать 0 в этом случае). Однако предоставленный код принимает стандартное отклонение каждого столбца (как и std (A, 1)), а не каждой строки. Кроме того, я сделал редактирование, чтобы исправить ошибку, о которой вы говорили. Теперь он должен работать с любой (непустой) матрицей. – dspyz
Да, алгоритм вычисления дисперсий на разреженной матрице может быть довольно простым (в зависимости от в формате), но он должен быть реализован. –
Как это можно эффективно реализовать? Есть ли способ циклически перебирать записи разреженной матрицы? –