
Ao escrever um artigo sobre o desenvolvimento de um detector de anomalia, implementei um dos algoritmos chamado Gás Neural Crescente Incremental.
Em Literatura soviética No segmento russo da Internet, esse tópico é abordado de maneira bastante ruim, e havia apenas um artigo e, mesmo assim, com a aplicação desse algoritmo.
Então, o que exatamente é um algoritmo de gás neural em crescimento incremental?
1. Introdução
IGNG, como o GNG , é um algoritmo de agrupamento adaptável.
O algoritmo em si é descrito em um artigo de Prudent e Ennadji para 2005 .
Como o GNG, existem muitos vetores de dados X ou função geradora f(t) , que fornece vetores de dados distribuídos aleatoriamente (parâmetro t - hora ou número da amostra).
O algoritmo não impõe restrições adicionais a esses dados.
Mas por dentro é muito diferente do GNG.
Esse algoritmo também é interessante, pois é um pouco mais preciso que a neurogênese dos modelos GNG.
Descrição do algoritmo
O algoritmo divide muitos dados em clusters.
Comparado ao GNG, sua vantagem é uma maior taxa de convergência.
Ideias nas quais o algoritmo se baseia:
- Teoria da ressonância adaptativa : Primeiro, o neurônio mais próximo é pesquisado e, se a diferença não exceder o limite (o "parâmetro de vigilância"), os pesos são ajustados ou, caso contrário, as coordenadas do neurônio no espaço de dados são alteradas. Se o limite não for superado, novos neurônios são criados para aproximar melhor o valor da amostra de dados.
- As conexões e os neurônios têm um parâmetro de idade (o GNG tem apenas conexões), que no início é zero, mas aumenta à medida que você aprende.
- Um neurônio não aparece imediatamente: primeiro um embrião (ou neurônio germinal) aparece, cuja idade aumenta a cada iteração até amadurecer. Após o treinamento, apenas neurônios maduros participam da classificação .
Ciclo principal
O trabalho começa com um gráfico vazio. Parâmetro sigma inicializado pelo desvio padrão da amostra de treinamento:
sigma= sqrt frac1N soma limitesNi=1 left(xi− barx right)2
Onde: barx - a média entre as coordenadas da amostra.
O loop principal em cada etapa diminui o valor sigma , que é o limite de proximidade e calcula a diferença entre o nível anterior de qualidade de cluster e o nível obtido após o cluster pelo procedimento IGNG .

Código do gráfico.@startuml start :TrainIGNG(S); :<latex>\sigma = \sigma_S,x,y \in S</latex>; :<latex>IGNG(1, \sigma, age_{mature}, S)</latex>; :<latex>old = 0</latex>; :<latex>calin = CHI()</latex>; while (<latex>old - calin \leq 0</latex>) :<latex>\sigma=\sigma - \sigma / 10</latex>; :<latex>IGNG(1, \sigma, age_{mature}, S)</latex>; :<latex>old = calin</latex>; :<latex>calin = CHI()</latex>; endwhile stop @enduml
CHI é o índice Kalinsky-Kharabaz, mostrando a qualidade do agrupamento:
CHI= fracB/(c−1)W/(n−c)
Onde:
- n - o número de amostras de dados.
- c - o número de aglomerados (neste caso, o número de neurônios).
- B - matriz de dispersão interna (a soma das distâncias ao quadrado entre as coordenadas dos neurônios e a média de todos os dados).
- W - matriz de dispersão externa (a soma das distâncias ao quadrado entre todos os dados e o neurônio mais próximo).
Quanto maior o valor do índice, melhor, porque, se a diferença entre os índices após o agrupamento e antes de ser negativa, é possível assumir que o índice se tornou positivo e excedeu o anterior, ou seja, armazenamento em cluster concluído com êxito.
Procedimento de IGNG
Este é o procedimento básico do algoritmo.
É dividido em três estágios mutuamente exclusivos:
- Nenhum neurônio encontrado.
- Um neurônio satisfatório foi encontrado.
- Encontrou dois que satisfazem as condições do neurônio.
Se uma das condições passar, as outras etapas não serão executadas.
Primeiro, um neurônio é pesquisado para obter a melhor amostra de dados aproximada:
c1=min(dist( xi, omegac))
Aqui dist(x omega,x xi) - função de cálculo da distância, que geralmente é uma métrica euclidiana .
Se o neurônio não for encontrado ou estiver muito longe dos dados, ou seja, não satisfaz o critério de proximidade dist( xi, omegac) leq sigma , um novo neurônio embrionário é criado com coordenadas iguais às coordenadas da amostra no espaço de dados.

Se a verificação de proximidade tiver passado, um segundo neurônio é pesquisado da mesma maneira e verificado a proximidade da amostra de dados.
Se o segundo neurônio não for encontrado, ele será criado.

Se foram encontrados dois neurônios que satisfazem a condição de proximidade com a amostra de dados, suas coordenadas são corrigidas de acordo com a seguinte fórmula:
epsilon(t)hc,ci= begincases epsilonb, ifc=ci epsilonn, ifexisteaconexão entrec=ci0,emoutrocase endcases
Delta omegac= epsilon(t)hc,c1 paralela xi− omegac paralela omegac= omegac+ Delta omegac
Onde:
- epsilon(t) - etapa de adaptação.
- ci É o número do neurônio.
- hc,c1 - Função de vizinhança de neurônios c com o neurônio vencedor (nesse caso, ele retornará 1 para vizinhos diretos, 0 caso contrário, porque a etapa de adaptação, para cálculo omega será diferente de zero apenas para vizinhos diretos).
Em outras palavras, a coordenada (peso) do neurônio vencedor é alterada para epsilonb∗ Delta omegai , e todos os seus vizinhos diretos (aqueles conectados a ele por uma borda do gráfico) em epsilonn∗ Delta omegai onde omegai - a coordenada do neurônio correspondente antes da alteração.
Em seguida, é criada uma conexão entre os dois neurônios vencedores e, se já foi criada, sua idade é redefinida.
A idade de todos os outros relacionamentos está aumentando.
Todas as comunicações cuja idade excedeu a constante agemax são excluídos.
Depois disso, todos os neurônios maduros isolados (aqueles que não têm conexão com outros) são removidos.
A idade dos neurônios imediatos vizinhos ao neurônio vencedor está aumentando.
Se a idade de qualquer neurônio da linha germinativa exceder agemature Ele se torna um neurônio maduro.
O gráfico final contém apenas neurônios maduros.
Uma condição para concluir o procedimento IGNG abaixo pode ser considerada um número fixo de ciclos.
O algoritmo é mostrado abaixo (a imagem é clicável):

Código do gráfico. @startuml skinparam nodesep 10 skinparam ranksep 20 start :IGNG(age, sigma, <latex>a_{mature}</latex>, S); while ( ) is () -[#blue]-> : e S; : c<sub>1</sub>; if ( \n<latex>dist(\xi, \omega_{c_1}) \leq \sigma</latex>) then () : <latex>\omega_{new} = \xi</latex>; else () -[#blue]-> : ; if ( \n <latex>dist(\xi, \omega_{c_2}) \leq \sigma</latex>) then () : <latex>\omega_{new} = \xi</latex>; : <latex>c_1</latex> <latex>c_2</latex>; note , end note else () -[#blue]-> : ,\n <latex>c_1</latex>; :<latex>\omega_{c_1} = \omega_c + \epsilon_b(\xi - \omega_{c_1})</latex>; :<latex>\omega_n = \omega_n + \epsilon_n(\xi - \omega_n)</latex>; note n - <latex>c_1</latex> (.. ) end note if (c<sub>1</sub> c<sub>2</sub> ) then () : : <latex>age_{c_1 -> c_2} = 0</latex>; else () -[#blue]-> : c<sub>1</sub> c<sub>2</sub>; endif : \n c<sub>1</sub>; note , , . end note endif repeat if (<latex>age(c) \geq a_{mature}</latex>) then () : $$ ; else () -[#blue]-> endif repeat while ( ?) endif : , ; : ; note IGNG, , GNG. . endnote endwhile () stop @enduml
Implementação
A rede foi implementada em Python usando a biblioteca de gráficos NetworkX . Cortar o código do protótipo no artigo anterior é dado abaixo. Também há breves explicações para o código.
Se alguém estiver interessado no código completo, aqui está um link para o repositório .
Um exemplo do algoritmo:

A maior parte do código class NeuralGas(): __metaclass__ = ABCMeta def __init__(self, data, surface_graph=None, output_images_dir='images'): self._graph = nx.Graph() self._data = data self._surface_graph = surface_graph