Expansion du gaz neuronal

Lors de l'exécution de vérifications à l'aide de modèles d'apprentissage automatique, l'un des problèmes fréquemment résolus est le problème de clustering. Par exemple, il est nécessaire de scinder les avis clients d'une application mobile en plusieurs clusters (tâche de modélisation thématique). Le modèle k-means est souvent utilisé pour les tâches de clustering. Cela est dû à sa simplicité et sa clarté. Cependant, cet algorithme présente un gros inconvénient: la nécessité de définir initialement le nombre de clusters. Ce problème est parfaitement géré par l'expansion du gaz neuronal.





, . — . :









  1. .









  2. , ,





:





s1 s2.





:





  1. v1.





2. . r1 r2 , r1 > r2.





3. s2 , s1. s2 , s3 s2 s1. s1 s2 .





4. 3 s1 . . s3,





5. 3 , 3 s4. s2-s3-s4,





, . k-means.





.





sklearn c :





from sklearn.datasets import make_moons
data, _ = make_moons(10000, noise=0.06, random_state=0)
plt.scatter(*data.T)
plt.show()
      
      



:





import copy
from neupy import algorithms, utils

def draw_image(graph, show=True):
    		for node_1, node_2 in graph.edges:
        			weights = np.concatenate([node_1.weight, node_2.weight])
        			line, = plt.plot(*weights.T, color='black')
        			plt.setp(line, linewidth=0.2, color='black')

    		plt.xticks([], [])
    		plt.yticks([], [])
    
    		if show:
       			plt.show()

def create_gng(max_nodes, step=0.2, n_start_nodes=2, max_edge_age=50):
    		return algorithms.GrowingNeuralGas(
        			n_inputs=2,
        			n_start_nodes=n_start_nodes,

        			shuffle_data=True,
        			verbose=True,

        			step=step,
        			neighbour_step=0.005,

        			max_edge_age=max_edge_age,
        			max_nodes=max_nodes,

        			n_iter_before_neuron_added=100,
        			after_split_error_decay_rate=0.5,
        			error_decay_rate=0.995,
        			min_distance_for_update=0.01,
    		)

def extract_subgraphs(graph):
    		subgraphs = []
    		edges_per_node = copy.deepcopy(graph.edges_per_node)
    
    		while edges_per_node:
        			nodes_left = list(edges_per_node.keys())
        			nodes_to_check = [nodes_left[0]]
        			subgraph = []
        
        			while nodes_to_check:
           				node = nodes_to_check.pop()
            			subgraph.append(node)

            			if node in edges_per_node:
                				nodes_to_check.extend(edges_per_node[node])
                				del edges_per_node[node]
            
        			subgraphs.append(subgraph)
        
    		return subgraphs
      
      



500 , 10000, , .





utils.reproducible()
gng = create_gng(max_nodes=500)

for epoch in range(20):
    		gng.train(data, epochs=1)

	draw_image(gng.graph)    
print("Found {} clusters".format(len(extract_subgraphs(gng.graph))))
      
      



, .





3 :





X = -0.7 - 2.5 * np.random.rand(900,2)
X1 = 0.7 + 2.5 * np.random.rand(375,2)
X2 = -0.5 + 1.7 * np.random.rand(50,2)
X[475:850, :] = X1
X[850:900, :] = X2
plt.scatter(X[ : , 0], X[ :, 1])
plt.show()
      
      



Malgré le manque de données structurées et de frontières implicites entre eux, le gaz neuronal en expansion a pu correctement approximer la distribution et déterminer le nombre de clusters.





utils.reproducible()
gng = create_gng(max_nodes=300)

for epoch in range(40):
    		gng.train(X, epochs=1)
    	
draw_image(gng.graph)    
print("Found {} clusters".format(len(extract_subgraphs(gng.graph))))
      
      






All Articles