Eines der häufig gelösten Probleme bei der Durchführung von Überprüfungen mithilfe von Modellen für maschinelles Lernen ist das Clustering-Problem. Beispielsweise ist es erforderlich, Kundenbewertungen einer mobilen Anwendung in mehrere Cluster aufzuteilen (thematische Modellierungsaufgabe). Das k-means-Modell wird häufig für Clustering-Aufgaben verwendet. Dies liegt an seiner Einfachheit und Klarheit. Dieser Algorithmus hat jedoch einen großen Nachteil - die Notwendigkeit, zunächst die Anzahl der Cluster festzulegen. Dieses Problem wird durch die Expansion von Neuralgas perfekt gelöst.
, . — . :
.
, ,
:
s1 s2.
:
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()
Trotz des Fehlens strukturierter Daten und impliziter Grenzen zwischen ihnen konnte das expandierende neuronale Gas die Verteilung korrekt approximieren und die Anzahl der Cluster bestimmen.
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))))