2012-05-16 6 views
0

J'ai un ensemble de données organisé en une structure. J'avoir un grand nombre de capteurs, et chacun a quatre lectures par ad, de sorte que la structure D contient D.sensorID, D.a, D.b, D.c et D.d. Je cherche les valeurs aberrantes dans la distribution des lectures. J'ai tracé les données et choisi les limites et écrit un script qui identifie des années sensorID avec des lectures en dehors de ces limites et les enregistre dans un tableau:Identification des données aberrantes

aMax = 5; 
    aHighIndices = find(D.a>aMax); 
    aMin = 0; 
    aLowIndices = find(D.a<aMin); 
    aHighLength = size(aHighIndices); 
    for i = 1:aHighLength 
    A_hi(i) = D.sensorID(aHighIndices(i)); 
    end 

Cette opération est répétée: a_Hi, a_Low, b_Hi, etc .. . puis patcher les résultats ensemble:

outliers = [A_hi; A_low; B_low; B_hi; C_low; C_hi; D_low; D_hi];

y at-il une façon plus concise de le faire?

+0

Votre méthodologie semble correcte. Si vous cherchez d'autres façons de trouver des valeurs aberrantes, voici une autre méthode: Pensez à un Gaussien 2D centré sur les lectures moyennes pour chaque capteur. Quand une lecture de capteur donnée présente deux écarts-types, vous pourriez peut-être la considérer comme une valeur aberrante. Maintenant, au lieu d'avoir à définir un seuil haut/bas autour de chaque capteur, il suffit d'ajuster les normales à chaque capteur, et de définir un seuil, c'est-à-dire, combien d'écart-type doit être avant d'être considéré une valeur aberrante. – kitchenette

Répondre

3

1. Vous itérer sur chaque réseau (à savoir vecteur) de lecture deux fois avec find: une fois pour trouver toutes les valeurs aberrantes élevées et une fois pour trouver des valeurs aberrantes faibles. Vous pouvez le faire dans une itération simplement par:

a_outlier_indices = find(D.a < aMin | D.a > aMax); 

2. Une autre chose: en général for dans Matlab est assez cher, essayez d'utiliser les capacités intégrées de la syntaxe Matlab pour produire les mêmes résultats . Plus précisément, vous Matlab permet d'extraire un sous-vecteur sur un autre vecteur en utilisant un vecteur d'indices:

a_outliers = D.sensorID(a_outlier_indices); 

alimentation simplement D.a avec un vecteur d'indices donne le vecteur souhaité des valeurs aberrantes.

3. En outre, un conseil pour une bonne pratique: pensez à stocker des tableaux a par d dans un réseau de cellules de vecteurs au lieu de tableaux distincts, quelque chose comme: D.readings = {a, b, c, d}, et la définition de réseau de cellules de seuils correspondants (thr dans mon exemple), vous pouvez donc enregistrer un code en utilisant une boucle:

thr = {[aMin, aMax]; [bMin, bMax]; [cMin, cMax]; [dMin, dMax]} 
outliers = cell(4, 1); 
for i = 1:4 
    outlier_indices = find(D.readings{i} < thr{i}(1) | D.readings{i} > thr{i}(2)); 
    outliers{i} = D.sensorID(outlier_indices); 
end 

maintenant, vous aurez tout le réseau de cellules outliers. Pour accéder au une aberrantes utilisent outliers{1}, pour accéder au b valeurs aberrantes utilisent outliers{2}, et ainsi de suite ...

Vous pouvez bien sûr patch tout ensemble (comme dans la question) dans un vecteur par concaténation simple à l'intérieur la boucle for:

outliers = [outliers, D.sensorID(outlier_indices)];

au lieu de la déclaration outliers{i} = ....

P.S

Je suppose que l'utilisation de seuils min/max est ce que vous voulez utiliser pour trouver des valeurs aberrantes. Il existe d'autres méthodes pour trouver des valeurs aberrantes, mais celles-ci donnent des résultats différents.

Questions connexes