2017-07-25 1 views
1

J'ai une très grande dataframe nommée 'data' avec 350000 lignes et 138 colonnes que je voudrais utiliser pour un k clustering -medoids. J'utilise le code de cette page: http://dpmartin42.github.io/blogposts/r/cluster-mixed-typesProblèmes de mémoire: Analyse de cluster avec de très grandes données multi-échelles dans R utilisant la distance de Gower et k-medoids

Ceci est mon code:

packages <- c("dplyr", "ISLR", "cluster", "Rtsne", "ggplot2") 


if (length(setdiff(packages, rownames(installed.packages()))) > 0) { 
install.packages(setdiff(packages, rownames(installed.packages()))) 
} 

rm(packages) 

library(dplyr) # for data cleaning 
library(ISLR) # for college dataset 
library(cluster) # for gower similarity and pam 
library(Rtsne) # for t-SNE plot 
library(ggplot2) # for visualization 

data <- read.csv("data.csv", sep = ";") 


## creation of dissimilarity matrix using "Gower distance" for mixed data 
##types 
gower_dist <- daisy(data, 
       metric = "gower", 
       type = list()) 
gower_mat <- as.matrix(gower_dist) 
#write.table(gower_mat, file = "dissimilarity.csv") 
#summary(gower_dist) 


sil_width <- c(NA) 
for(l in 2:8){ 

pam_fit <- pam(gower_dist, 
      diss = TRUE, 
      k = l) 

sil_width[l] <- pam_fit$silinfo$avg.width 
} 

nclust <- which.max(sil_width) # identify index of highest value 
opt.value <- max(sil_width, na.rm = TRUE) # identify highest value 
ncluster <- round(mean(nclust)) 
valcluster <- max(opt.value) 

## start PAM clustering with n clusters 
pam_fit <- pam(gower_dist, diss = TRUE, k = ncluster) 

pam_results <- data.sample %>% 
mutate(cluster = pam_fit$clustering) %>% 
group_by(cluster) %>% 
do(the_summary = summary(.)) 


#pam_results$the_summary 

#data.sample[pam_fit$medoids, ] 


tsne_obj <- Rtsne(gower_dist, is_distance = TRUE) 

tsne_data <- tsne_obj$Y %>% 
    data.frame() %>% 
    setNames(c("X", "Y")) %>% 
    mutate(cluster = factor(pam_fit$clustering)) 

ggplot(aes(x = X, y = Y), data = tsne_data) + 
geom_point(aes(color = cluster)) 

Les étapes que je veux réaliser sont:

1) Créer matrice dissemblance en utilisant la distance Gower pour le multi-échelle données

2) Cherchez nombre optimal de grappes

3) Effectuez-medoids regroupement k

4) Visualiser le regroupement en utilisant Rtsne pour la visualisation de données multidimensionnelles

Le code fonctionne très bien pour un sous-ensemble de données allant jusqu'à 10000 lignes.

Si j'essaie d'exécuter le code sur plusieurs lignes, j'ai des problèmes de mémoire. Avec l'ensemble dataframe je reçois l'erreur: « erreur: ne peut pas attribuer vecteur de taille 506,9 Go » qui est créé à l'étape

gower_dist <- daisy(data.sample, 
       metric = "gower", 
       type = list(), 
       warnType = FALSE) # suppress warning regarding data type 

Je sais que la création de la matrice de dissemblance a besoin de beaucoup de RAM. Donc, ma question ne concerne pas le codage mais la méthodologie: y a-t-il un moyen significatif de créer la matrice de dissimilarité et d'effectuer le regroupement sur l'ensemble de la base de données? Je pensais à deux alternatives:

OPTION 1: Créer la matrice de dissimilarité itérative par pas de 1000 lignes. Je ne suis pas sûr si cela a du sens car la matrice montre chaque ligne par chaque rangée. OPTION 2: Créer une boucle for avec toutes les étapes où les sous-ensembles de données de 1000 lignes sont sélectionnés de manière aléatoire et toutes les étapes sont répétées plusieurs fois jusqu'à ce qu'un clustering représentatif soit atteint. Je ne suis pas sûr que cela ait du sens.

Est-il possible d'effectuer le code ci-dessus sur de très grands ensembles de données dans R?

+0

Combien de lignes dupliquées avez-vous? –

+0

Kmedoids échelles vraiment mal. Les 500 Go semblent plausibles pour moi. N'utilisez pas d'algorithme basé sur une matrice de distance sur ces données. –

+0

J'ai environ 3000 lignes en double. Merci pour votre conseil. Je voulais utiliser kmedoids en raison de sa capacité à utiliser la distance de Gower pour les données multi-échelles.Avez-vous une recommandation, quel algorithme peut être utilisé pour de grandes données multi-échelles sans utiliser de matrice de distance? Tout indice serait utile. – Elena

Répondre

2

SLINK ne nécessitera qu'une mémoire linéaire. DBSCAN et OPTICS, aussi.

DBSCAN sera un peu difficile à paramétrer (quelle valeur d'epsilon?), Mais OPTICS vaut la peine d'être essayé. Je ne sais pas si Gower peut être indexé, pour accélérer l'algorithme.

Mais vous rencontrerez le même problème plus tard dans tSNE!

Ce que je considère est de travailler d'abord avec un sous-ensemble gérable seulement. Ensuite, une fois que vous savez ce qui fonctionne, vous pouvez soit utiliser toutes les données (avec DBSCAN, vous pouvez essayer d'utiliser le même epsilon, mais en augmentant minPts pour la plus grande taille de données). Ou vous ajoutez simplement les points restants au même groupe que leur plus proche voisin dans l'échantillon.