2010-05-31 19 views
6

Je suis en train de regrouper une matrice (taille: 20057x2) .:erreur de dépassement de mémoire lors de l'utilisation clusterdata dans Matlab

T = clusterdata(X,cutoff); 

mais je reçois cette erreur:

 
??? Error using ==> pdistmex 
Out of memory. Type HELP MEMORY for your options. 

Error in ==> pdist at 211 
    Y = pdistmex(X',dist,additionalArg); 

Error in ==> linkage at 139 
     Z = linkagemex(Y,method,pdistArg); 

Error in ==> clusterdata at 88 
Z = linkage(X,linkageargs{1},pdistargs); 

Error in ==> kmeansTest at 2 
T = clusterdata(X,1); 

quelqu'un peut me aider . J'ai 4 Go de ram, mais pense que le problème vient d'ailleurs.

Répondre

10

Comme mentionné par d'autres, le clustering hiérarchique doit calculer la matrice de distance par paire qui est trop grande pour tenir dans la mémoire dans votre cas.

Essayez d'utiliser l'algorithme K-Means à la place:

numClusters = 4; 
T = kmeans(X, numClusters); 

Vous pouvez également sélectionner un sous-ensemble aléatoire de vos données et utiliser comme entrée pour l'algorithme de clustering. Ensuite, vous calculez les centres de cluster en tant que moyenne/médiane de chaque groupe de cluster. Enfin, pour chaque instance qui n'a pas été sélectionnée dans le sous-ensemble, vous calculez simplement sa distance à chacun des centroïdes et vous l'attribuez à la plus proche.

Voici un exemple de code pour illustrer l'idée ci-dessus:

%# random data 
X = rand(25000, 2); 

%# pick a subset 
SUBSET_SIZE = 1000;   %# subset size 
ind = randperm(size(X,1)); 
data = X(ind(1:SUBSET_SIZE), :); 

%# cluster the subset data 
D = pdist(data, 'euclid'); 
T = linkage(D, 'ward'); 
CUTOFF = 0.6*max(T(:,3));  %# CUTOFF = 5; 
C = cluster(T, 'criterion','distance', 'cutoff',CUTOFF); 
K = length(unique(C));  %# number of clusters found 

%# visualize the hierarchy of clusters 
figure(1) 
h = dendrogram(T, 0, 'colorthreshold',CUTOFF); 
set(h, 'LineWidth',2) 
set(gca, 'XTickLabel',[], 'XTick',[]) 

%# plot the subset data colored by clusters 
figure(2) 
subplot(121), gscatter(data(:,1), data(:,2), C), axis tight 

%# compute cluster centers 
centers = zeros(K, size(data,2)); 
for i=1:size(data,2) 
    centers(:,i) = accumarray(C, data(:,i), [], @mean); 
end 

%# calculate distance of each instance to all cluster centers 
D = zeros(size(X,1), K); 
for k=1:K 
    D(:,k) = sum(bsxfun(@minus, X, centers(k,:)).^2, 2); 
end 
%# assign each instance to the closest cluster 
[~,clustIDX] = min(D, [], 2); 

%#clustIDX(ind(1:SUBSET_SIZE)) = C; 

%# plot the entire data colored by clusters 
subplot(122), gscatter(X(:,1), X(:,2), clustIDX), axis tight 

dendrogram clusters

+1

solution Nice, je l'aime. – Donnie

+0

Merci pour votre réponse complète, La raison pour laquelle j'utilise la classification hiérarchique est que je ne sais pas combien de groupes dont j'ai besoin à l'avance. En kmeans, je dois le définir depuis le début, et à cause de la nature de mon projet, il m'est impossible d'utiliser des Kmeans. Merci quand même ... – Hossein

+0

@Hossein: J'ai changé le code pour utiliser une valeur 'cutoff' pour trouver le meilleur nombre de clusters sans le spécifier au préalable ... – Amro

2

X est trop grand pour faire sur une machine 32 bits. pdist essaie de faire un vecteur 201.113.596 ligne (utilise pdist) de doubles, ce qui utiliserait environ 1609MB (double est de 8 octets) ... si vous l'exécutez sous windows avec le commutateur/3GB vous êtes limité à un maximum taille de la matrice de 1536 Mo (voir here).

Vous allez devoir diviser les données au lieu de les regrouper directement en une seule fois.

1

PDIST calcule les distances entre toutes les paires de lignes possibles. Si vos données contiennent N = 20057 lignes, alors le nombre de paires sera N * (N-1)/2, ce qui correspond à 201131596 dans votre cas. Peut-être trop pour votre machine.