2016-09-14 2 views
0

행렬이 M입니다. 행렬 M의 각 행이 주체이고 각 열이 하나의 측정 값이라고 가정 해 봅시다.NaN으로 행 수가 최소가되도록 행렬을 최적화

M=rand(100);    % generate a 100x100 matrix random 
c=randperm(length(M),100); %select randomly 100 measurement indices 
r=randperm(length(M),100); %select randomly 100 subject indices 

for i = 1 : 100 
    M(r(i),c(i))=NaN;  % add randomly NaN. i.e. the subject c(i) does not have measurement c(i) 
end 

지금은 (있는 경우) 모든 주제에 대해

idx_col_all_NAN = find(all(isnan(M)==1)); 
M(:,idx_col_all_NAN)=[]; 

누락 측정을 삭제하고 난 (있는 경우)

idx_row_all_NAN = find(all(isnan(M)==1,2)); 
M(idx_row_all_NAN,:)=[]; 
모든 측정이 누락되는 주제를 삭제

이제 동일한 측정 값을 가진 피사체의 수를 최대화하고 NaN이 포함 된 M의 셀을 최소화하기 위해 측정 값을 제거하고 싶습니다.

도와 주시겠습니까?

+0

그래서 2 명의 피사체 (A와 B)가 같은 값을 가진 측정 값 하나를 가지고 있고 A가 NaN을 가지고 있다면 NaN이 B의 측정 값으로 대체되기를 바랍니다. 모든 측정이 평등을 확인해야합니까? – Finn

+3

'isnan (M)'은'isnan (M) == 1 '과 같은 결과를 줄 것입니다. – obchardon

+0

@Finn 아니,이게 내가 의미하는 바가 아냐 ...저는 어떤 값을 대체하고 싶지 않습니다 ... NaN – gabboshow

답변

0

매트릭스에서 NaN을 계속 제거하려면 적은 데이터와 적은 NaN 간의 절충을 극대화하는 방법에 대한 몇 가지 규칙이 필요합니다. 이미 말했듯이 제한없이 NaN을 계속 제거한다면 매우 적은 양의 데이터 만 남을 수 있습니다. 올바른 규칙이 없으므로, 실제로 당신이 요구하는 것에 달려 있습니다. 다음 제안은 그러한 문제를 다루는 방법에 대한 아이디어 만 줄 것입니다.

그래서 출발점으로, 내가 얼마나 많은 '구멍'의 관점에서, 매트릭스의 '품질'에 인덱스를 정의하면에 있습니다

M_ratio = sum(~isnan(M(:)))/numel(M); % the ratio between numbers to M size 

이 지수는 더 많은 데이터로 커집니다 행렬에 있고 NaN이 없으면 1과 같습니다. 우리는 개선점을 볼 수만 있다면 행렬에서 행/열을 제거 할 수 있지만 NaN이 남아있는 한 행렬이 작아지기 때문에 항상 개선 된 점이 나타날 것이므로 빈 행렬 (또는 매우 작은 하나는 우리가 가진 NaN의 양에 달려 있습니다.)

그래서 우리는 삭제가 일정 금액의 매트릭스를 개선하지 않는 경우 않도록 개선, 일부 임계 값을 정의 할 필요가있다 - 우리는 프로세스를 중지 :

improve = 1-M_old_ratio/M_new_ratio % the relative improvement after deletion 

improve가의 상대적인 이득을 우리의 ' 품질 '색인을 만들고, 충분히 크지 않으면 매트릭스에서 행/열 삭제를 중단합니다. 충분히 큰 무엇입니까? 이것은 말하기 어렵지만, 나는 당신에게 그걸 가지고 놀고, 당신에게보기 흉하지 않은 결과를주는 것을 보게 될 것입니다. 그래서 여기

가에 대한 전체 코드입니다 :

N = 100; 
M = rand(N); % generate a NxN random matrix 
M(randi(numel(M),N^2,1)) = nan; % add NaN to randomly selected N^2 measurements 
M(:,all(isnan(M)))=[]; % delete all NaN columns 
M(all(isnan(M),2),:)=[]; % delete all NaN rows 
threshold = 0.003; % the threshold for stop optimizing the matrix 
while 1 
    M_ratio = sum(~isnan(M(:)))/numel(M); % the ratio between numbers to M size 
    [mincol,indcol] = min(sum(~isnan(M),1)); % find the column with most NaN 
    [minrow,indrow] = min(sum(~isnan(M),2)); % find the row with most NaN 
    [~,dir] = min([minrow;mincol]); % find which has more NaNs 
    Mtry = M; 
    if dir == 1 
     Mtry(indrow,:) = []; % delete row 
    else 
     Mtry(:,indcol) = []; % delete column 
    end 
    Mtry_ratio = sum(~isnan(Mtry(:)))/numel(Mtry); % get the new ratio 
    improve = 1-M_ratio/Mtry_ratio; % the relative improvement after deletion 
    if improve>threshold % if it improves more than the threshold 
     M = Mtry; % replace the matrix 
    else 
     break; % otherwise - quit 
    end 
end 

만 열을 제거 고려한다면, 그리고 행, 그것은 비트 simmpler의 :

threshold = 0.002; % the threshold for stop optimizing the matrix 
while 1 
    M_ratio = sum(~isnan(M(:)))/numel(M); % the ratio between numbers to M size 
    [~,indcol] = min(sum(~isnan(M),1)); % find the column with most NaN 
    Mtry = M; 
    Mtry(:,indcol) = []; % delete column 
    Mtry_ratio = sum(~isnan(Mtry(:)))/numel(Mtry); % get the new ratio 
    improve = 1-M_ratio/Mtry_ratio; % the relative improvement after deletion 
    if improve>threshold % if it improves more than the threshold 
     M = Mtry; % replace the matrix 
    else 
     break; % otherwise - quit 
    end 
end 

당신이 알 수로서 나는 NaN의 소개 보다 간단한 방법으로 행렬에 추가 할 수 있지만 실제 데이터가 있기 때문에 중요하지 않습니다. 또한 필자는 논리적 인 인덱싱을 사용하는데, 이것은 열과 행을 제거하는보다 작고 효율적인 방법입니다.

+0

감사합니다. 행렬 M이 정사각형이 아닌 경우 이것은 바이어스입니까? 예를 들어, 행보다 열이 많은 경우 행을 삭제할 가능성이 가장 높습니다. – gabboshow

+1

@gabboshow 바이어스로 생각합니다. "나노"의 수를 계산하고 모든 테이블에서 데이터/셀 비율을 최대화하려고합니다. 최상의 결과를 가져올 행/열을 삭제합니다. 행이 될 경우 또는 열은 행렬에 'nan'이 어떻게 분포되어 있는지에 따라 달라집니다. 위의 방법은 '사고 방식'의 제안 일 뿐이므로 데이터에 대한 질문부터 시작해야합니다. 일 것이다 e 누락 된 값을 치료하는 가장 좋은 방법. 어쩌면 당신은 그들을 전혀 제거 할 필요가 없을 것입니다 ... – EBH