2010-05-31 10 views
6

Estoy intentando agrupar una Matriz (tamaño: 20057x2) .:Fuera de error de memoria al utilizar clusterdata en MATLAB

T = clusterdata(X,cutoff); 

pero me sale este error:

 
??? 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); 

Alguien me puede ayudar . Tengo 4 GB de RAM, pero creo que el problema es de otro lado ...

Respuesta

10

Según lo mencionado por otros, la agrupación jerárquica necesita calcular la matriz de distancia pairwise que es demasiado grande para caber en la memoria en su caso.

intente utilizar el algoritmo K-medias en su lugar:

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

alternativa, puede seleccionar un subconjunto aleatorio de sus datos y utilizar como entrada para el algoritmo de agrupamiento. A continuación, calcula los centros del clúster como media/mediana de cada grupo de clústeres. Finalmente, para cada instancia que no fue seleccionada en el subconjunto, simplemente calcula su distancia a cada centroides y la asigna a la más cercana.

Aquí hay un código de ejemplo para ilustrar la idea anterior:

%# 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

solución de Niza, me gusta. – Donnie

+0

Gracias por su respuesta integral, La razón por la que estoy usando la agrupación jerárquica es que no sé cuántos clústeres necesito de antemano. En kmeans tengo que definir desde el principio, y debido a la naturaleza de mi proyecto no me es posible usar Kmeans. Gracias de todos modos ... – Hossein

+0

@Hossein: Cambié el código para usar un valor 'cutoff' para encontrar el mejor número de clusters sin especificarlo de antemano ... – Amro

2

X es demasiado grande para hacer en una máquina de 32 bits. pdist está tratando de hacer un vector de fila 201.131.596 (clusterdata usa pdist) de dobles, que usaría aproximadamente 1609MB (double es 8 bytes) ... si lo ejecuta bajo Windows con el modificador/3GB está limitado a un máximo tamaño de la matriz de 1536MB (ver here).

Tendrá que dividir los datos de alguna manera en lugar de agruparlos directamente de una vez.

1

PDIST calcula las distancias entre todos los posibles pares de filas. Si sus datos contienen N = 20057 filas, entonces el número de pares será N * (N-1)/2, que es 201131596 en su caso. Podría ser demasiado para su máquina.

Cuestiones relacionadas