MATLAB: usando l'interpolazione per sostituire i valori mancanti (NAN)
-
26-09-2019 - |
Domanda
Ho un array di celle ciascuno contenente una sequenza di valori come vettore di riga. Le sequenze contengono alcuni valori mancanti rappresentati da NaN
.
Vorrei sostituire tutti i NAN usando una sorta di metodo di interpolazione, come posso farlo in Matlab? Sono anche aperto ad altri suggerimenti su come affrontare questi valori mancanti.
Considera questi dati di esempio per illustrare il problema:
seq = {randn(1,10); randn(1,7); randn(1,8)};
for i=1:numel(seq)
%# simulate some missing values
ind = rand( size(seq{i}) ) < 0.2;
seq{i}(ind) = nan;
end
Le sequenze risultanti:
seq{1}
ans =
-0.50782 -0.32058 NaN -3.0292 -0.45701 1.2424 NaN 0.93373 NaN -0.029006
seq{2}
ans =
0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417
seq{3}
ans =
NaN NaN 0.42639 -0.37281 -0.23645 2.0237 -2.2584 2.2294
Modificare:
Sulla base delle risposte, penso che ci sia stata una confusione: ovviamente non sto lavorando con dati casuali, il codice sopra è semplicemente un esempio di come sono strutturati i dati.
I dati effettivi sono una qualche forma di segnali elaborati. Il problema è che durante l'analisi, la mia soluzione fallirebbe se le sequenze contengono valori mancanti, quindi la necessità di filtraggio/interpolazione (ho già pensato di usare la media di ogni sequenza per riempire gli spazi vuoti, ma spero in qualcosa di più potente)
Soluzione
Bene, se stai lavorando con i dati delle serie temporali, puoi utilizzare la funzione di interpolazione integrata di MATLAB.
Qualcosa del genere dovrebbe funzionare per la tua situazione, ma dovrai personalizzare un po '... cioè. Se non hai un campionamento spaziato uguale dovrai modificare il times
linea.
nseq = cell(size(seq))
for i = 1:numel(seq)
times = 1:length(seq{i});
mask = ~isnan(seq{i});
nseq{i} = seq{i};
nseq{i}(~mask) = interp1(times(mask), seq{i}(mask), times(~mask));
end
Dovrai giocare con le opzioni di interp1
Per capire quali funzionano meglio per la tua situazione.
Altri suggerimenti
io userei inpaint_nans, uno strumento progettato per sostituire gli elementi NAN in matrici 1-D o 2-D per interpolazione.
seq{1} = [-0.50782 -0.32058 NaN -3.0292 -0.45701 1.2424 NaN 0.93373 NaN -0.029006];
seq{2} = [0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417];
seq{3} = [NaN NaN 0.42639 -0.37281 -0.23645 2.0237];
for i = 1:3
seq{i} = inpaint_nans(seq{i});
end
seq{:}
ans =
-0.50782 -0.32058 -2.0724 -3.0292 -0.45701 1.2424 1.4528 0.93373 0.44482 -0.029006
ans =
0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417
ans =
2.0248 1.2256 0.42639 -0.37281 -0.23645 2.0237
Se hai accesso al Cassetta degli strumenti di identificazione del sistema, puoi usare il Misdata funzione per stimare i valori mancanti. Secondo il documentazione:
Questo comando interpola linearmente valori mancanti per stimare il primo modello. Quindi, utilizza questo modello per stimare i dati mancanti come parametri minimizzando gli errori di previsione dell'output ottenuti dai dati ricostruiti.
Fondamentalmente l'algoritmo si alterna tra la stima dei dati mancanti e la stima dei modelli, in modo simile all'algoritmo di massimizzazione delle aspettative (EM).
Il modello stimato può essere uno qualsiasi dei modelli lineari idmodel
(AR/ARX/..), o se non fornito, utilizza un modello di spazio di stato di ordine predefinito.
Ecco come applicarlo ai tuoi dati:
for i=1:numel(seq)
dat = misdata( iddata(seq{i}(:)) );
seq{i} = dat.OutputData;
end
Ci sono anche alcune altre funzioni come interp1. Per i grafici curvi, la spline è il metodo migliore per trovare dati mancanti.
Come dice Judowill, devi assumere una sorta di relazione tra i tuoi dati.
Un'opzione banale sarebbe quella di calcolare la media della tua serie totale e utilizzare quelli per i dati mancanti. Un'altra banale opzione sarebbe quella di prendere la media dei valori N precedenti e N precedenti.
Ma stai molto attento a questo: se ti mancano i dati, generalmente sei meglio gestire quei dati mancanti, piuttosto che inventare alcuni dati falsi che potrebbero rovinare la tua analisi.
Considera il seguente esempio
X = un po 'di matrice Nx1 y = f (x) con alcuni NAN
Quindi usa
X1 = x (find (~ isnan (y))); Y1 = y (find (~ isnan (y)));
Ora interpolare su X1 e Y1 per calcolare tutti i valori X.