Sunday 29 October 2017

Opções binárias de vegdist


Ive escrito alguns Rcpp código e código R que trabalha para fora o binário / Jaccard distância de uma matriz binária aprox. 80x mais rápido do que dist (x, método binário). Converte a matriz de entrada em uma matriz bruta que é a transposta da entrada (de modo que os padrões de bits estejam na ordem correta internamente). Isso é então usado em algum código C que manipula os dados como inteiros não assinados de 64 bits para velocidade. A distância Jaccard de dois vetores x e y é igual a x y / (x y) onde é o operador xor. O cálculo Hamming Weight é usado para contar o número de bits definidos se o resultado do xor ou ou não for zero. Ive juntar o código em github em https: // github / NikNakk / binaryDist / e reproduzido os dois arquivos abaixo. Ive confirmou que os resultados são os mesmos que dist (x, método binário) para alguns conjuntos de dados aleatórios. Em um conjunto de dados de 39000 linhas por 14000 colunas com 1-5 unidades por linha, demorou cerca de 11 minutos. A matriz de distância de saída foi de 5,7 GB. BDist. cpp R source De resposta original: Outras coisas a considerar seria fazer algum prefiltering de comparações entre duas linhas com únicas uma vez que a distância será de 0 para duplicatas ou 1 para qualquer outra possibilidade. Algumas opções relativamente simples que podem ser mais rápidas sem precisar de muito código são a função vegdist do pacote vegan ea função Dist do pacote amap. O último provavelmente só será mais rápido se você tiver vários núcleos e tirar proveito do fato de que suporta paralelização. A razão que leva tanto tempo para computar é que a chamada para dist está computando e armazenando mais de 760 milhões de distâncias pairwise. Se seus dados são armazenados escassamente, isso levará muito tempo e uma enorme quantidade de armazenamento. Se seus dados não são armazenados escassamente, então cada computação de distância requer pelo menos 14.000 operações, para uma contagem de operação total superior a 1 quatrimônio. Uma abordagem que será muito mais rápida é k-significa agrupamento, uma vez que não requer pré-computação uma matriz de distância em Cada iteração você precisará apenas 39000k cálculos de distância, onde k é o número de clusters. Para obter as distâncias pairwise que são semelhantes ao índice de Jaccard (0 se idêntico, 1 se nenhum índice coincide, entre se alguns, mas não todos os índices coincidem), você poderia dividir cada linha x por sqrt (2sum (x2)). Por exemplo, se você tivesse a seguinte matriz de entrada: a versão normalizada seria (assumindo valores binários somente na matriz se não fosse o caso você usaria rowSums (mat2)): Estas duas observações (que não têm índices em comum) , Têm distância Euclidiana 1, coincidindo com a distância de Jaccard para este caso. Adicionalmente, observações idênticas terão claramente a distância euclidiana 0, novamente correspondendo à distância de Jaccard. Você tem linhas duplicadas Não há necessidade de calcular suas distâncias duas vezes. Todas as linhas com um único 1 serão 100 diferentes de todas as linhas com um único em um lugar diferente. Assim, não faz sentido executar clustering em tais dados. A saída é bastante previsível, e se resume a encontrar o 1. Tente restringir o conjunto de dados para os objetos que têm mais de um 1 apenas. A menos que você pode obter resultados interessantes sobre estes apenas, não há necessidade de continuar mais. Os dados binários têm pouca informação. Respondeu Jun 20 15 em 9:06

No comments:

Post a Comment