Algoritmo de agrupamento espacial incremental

8

Estou em busca de um algoritmo de agrupamento espacial incremental . Aqui está o meu caso de uso:

  • os usuários criam entradas com uma posição inicial
  • os usuários podem alterar as posições das entradas existentes

Agora eu quero implementar um serviço dissociado que forneça informações de cluster desses dados. O serviço será notificado sempre que uma nova entrada for adicionada ou uma entrada existente for movida. O que é um bom algoritmo de clustering, portanto? Idealmente, ele deve escalar até grandes quantidades de dados e, se houver uma troca entre a qualidade do cluster e a complexidade do tempo de execução, eu concordo com resultados degradantes e, eventualmente, resultados consistentes (resultados obsoletos por algum tempo).

Para resumir meus requisitos:

  • agrupamento espacial com base em posições
  • modificações incrementais nas mudanças
  • adicionar novas posições
  • alterar posições existentes
  • bom desempenho em tempo de execução

Desde já, obrigado!

b_erb
fonte
1
Para que os clusters serão usados? O que eles significam ? (As respostas a estes fornecem as formas mais básicas para selecionar um algoritmo de agrupamento.)
whuber
os eventos também são raros ou comuns? relacionado a uma população em risco? ou simplesmente destacar áreas em que as pessoas vivem ficará bem?
Ian Turton
@ whuber: Os clusters serão usados ​​para tornar os itens mais exploráveis ​​em um mapa (portanto, pode haver clusters diferentes em diferentes níveis de zoom); Eles significam uma concentração de itens disponíveis nas áreas especificadas.
b_erb
@iant: A criação de novos itens acontecerá com muita frequência, a mudança de posição dos itens existentes raramente acontecerá. Não há padrões detalhados a serem esperados como os eventos ocorrem. No entanto, a criação simultânea de vários itens ao mesmo tempo é menos provável.
b_erb
@PartlyCloudy Entendi a idéia, mas ainda não entendo como o clustering ajudará. OK, suponha que você identifique internamente determinados grupos de pontos. Como isso afetará a interface do usuário (ou, de maneira mais geral, a "explorabilidade" dos dados)? Dependendo de como você responde, pode haver soluções que são (a) extremamente rápidas e fáceis de implementar, mas que (b) geralmente não são consideradas algoritmos de "agrupamento".
whuber

Respostas:

4

O objetivo desse agrupamento é simplificar a exibição dos símbolos de pontos: quando muitos estiverem próximos no mapa, eles serão substituídos por um único símbolo para indicar um grupo.

Os requisitos apontam para a necessidade de uma solução simples e adaptável : os símbolos dos pontos podem ser atualizados e, à medida que o usuário aproxima o zoom, símbolos diferentes aparecerão em diferentes locais na extensão do mapa (ou tela).

Um excelente candidato é claramente um quadtree da região .

Existe um método mais simples que funcionará como um quadtree da região. Requer menos codificação, nenhuma criação antecipada de uma estrutura de dados, mas você paga um preço (pequeno) por precisar realizar alguns cálculos dinâmicos durante o zoom e o panorama. Apenas faça uma grade do mapa . Especificamente, suponha que n símbolos de ponto sejam desenhados na extensão atual do mapa, que possua um comprimento de dx e uma altura de dy . Em relação à origem do mapa, os símbolos precisam ser desenhados nas coordenadas ( x [i] , y [i] ), i = 1, 2, ..., n . A seleção de um tamanho de célula de grade de c particiona o mapa em uma grade de células. A célula na qual o local (x , y ) pertence está na linha j ( y ) = Piso [ y / c ] e coluna j ( x ) (contando de 0, com linhas indo de baixo para cima e colunas da esquerda para a direita). Você pode considerar qualquer célula que recebe dois ou mais pontos como um "cluster". O símbolo do cluster pode ser desenhado no centro da célula, que possui coordenadas ( j + c / 2, k + c / 2).

Isso leva à seguinte solução, apresentada no pseudocódigo:

m = Floor(dy/c)+1
n = Floor(dx/c)+1
Dimension a[m,n] = 0
For each (x[i], y[i]) to be displayed:
    Increment( a[ j(y[i]), j(x[i]) ] )
End for
For each (x[i], y[i]) to be displayed:
    row = j(y[i])
    col = j(x[i])
    If  a[row, col] > 1:
        Draw a symbol for a cluster of k points at (c*(col+0.5), c*(row+0.5))
        a[row, col] = 0
    Else
        Draw a point symbol at (x[i], y[i])
    End if
End for

Claramente, a carga computacional do algoritmo é O (número de pontos) no tempo e O (dx * dy / c ^ 2) no armazenamento. Os trade-offs envolvidos na seleção do tamanho da célula c são:

  1. c deve ser o maior possível: o armazenamento é inversamente proporcional a c ^ 2: valores pequenos de c significam grandes quantidades de RAM. (O armazenamento pode ser reduzido para O (número de pontos) usando matrizes ou dicionários esparsos.)

  2. c deve ser o maior possível: dois símbolos (pontos ou aglomerados) nunca estarão mais próximos que c / 2.

  3. c deve ser o menor possível: todo símbolo de cluster representa locais a não mais que c / sqrt (2) dele.

  4. c deve ser o menor possível: valores grandes de c tendem a criar muitos clusters e permitem que poucos pontos individuais apareçam.

Vamos fazer uma análise rápida de (4). Como ponto de partida, suponha que os locais a serem mapeados ocorram uniformemente aleatoriamente e independentemente um do outro. O número de células é N ( c ) = (Piso ( dx / c ) +1) * (Piso ( dy / c ) +1), que - pelo menos para valores maiores de c - é diretamente proporcional a c ^ 2) A distribuição das contagens de células seguirá aproximadamente uma lei de Poisson com intensidade lambda = n / N ( c ) = n * c ^ 2 / ( dx * dy) O número esperado de clusters é igual a

e ( c ) = n (1 - exp (- lambda ) (1 + lambda )).

Isso fica menor à medida que o lambda diminui para 0; isto é, à medida que o tamanho da célula c fica cada vez menor. O ponto desta análise é que a fórmula anterior permite prever quantos clusters podem existir, para que você possa selecionar um valor inicial de c para o qual e ( c ) esteja abaixo de um valor aceitável (enquanto ainda é grande o suficiente para limitar a RAM) requisitos). Não existe uma solução de forma fechada, mas algumas etapas de Newton-Raphson convergirão para uma rapidamente.

Essa abordagem é tão dinâmica - é rápida o suficiente para que a grade e o agrupamento conseqüente possam ser computados com cada zoom e pan e não requer estruturas de dados pré-computadas - que as "modificações incrementais" desejadas à medida que os dados são atualizados acontecem automaticamente.

whuber
fonte
E se visualmente você tiver um grupo de pontos agrupados perto da área dos 4 cantos. Você não acabaria com 4 grupos?
precisa saber é o seguinte
@Kirk Na verdade, essa situação pode dividir um grande cluster em dois a quatro grupos ou pontos individuais; não criará clusters artificiais. Isso também pode ocorrer com um quadtree da região. Existem várias soluções. Uma é compensar a origem da grade por uma quantidade aleatória entre 0 e -c (em ambas as coordenadas), para que essas condições não permaneçam permanentemente. Outra é criar um quadtree dinamicamente, adaptando-o aos pontos (em vez de usar pontos de corte fixos). Claramente, isso requer mais codificação. Uma boa solução é ignorar a situação: é realmente um problema?
whuber