Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import pandas
- from math import sqrt
- from sklearn.datasets import load_iris
- import matplotlib.pyplot as plt
- import random
- np.seterr(divide='ignore', invalid='ignore')
- # расстояние между двумя точками
- def dist(p1, p2):
- dist = 0
- for i in range(0, 4):
- dist += pow(p2[i] - p1[i], 2)
- return sqrt(dist)
- # получить индекс центра к которому ближе всего находится point
- def find_nearest_center(centers, point):
- mn_index = 0
- mn = -1
- i = 0
- for row in centers:
- if dist(row, point) < mn or mn == -1:
- mn = dist(row, point)
- mn_index = i
- i += 1
- return mn_index
- def is_unique(arr, index):
- for i in range(index):
- if arr[i] == arr[index]:
- return False
- return True
- # получить массив из n различных случайных чисел от mn до mx (включительно)
- def get_n_random_numbers(n, mn, mx):
- arr = np.zeros(n)
- for i in range(n):
- arr[i] = random.randint(mn, mx)
- while not is_unique(arr, i):
- arr[i] = random.randint(mn, mx)
- return arr
- # произвести деление на cluster_count кластеров, перерасчитать центры
- # iteration_count раз, перебрать roll_count случайных начальных значений
- # и вернуть Q наилучшего выбора
- # (Q - среднее средних расстояний внутри кластеров)
- def clusterize(cluster_count, iteration_count, roll_count = 1):
- x = np.ndarray(roll_count)
- y = np.ndarray(roll_count)
- color = np.zeros(roll_count)
- cluster_ids = np.zeros(150)
- data = load_iris()
- centers = np.ndarray((cluster_count, 4))
- best_centers = np.ndarray((cluster_count, 4))
- best_Q = -1
- for i in range(best_centers.shape[0]):
- for j in range(best_centers.shape[1]):
- best_centers[i][j] = -1
- for roll in range(0, roll_count):
- # получение случайных центров для кластеров
- centers_indices = get_n_random_numbers(cluster_count, 0, data.data.shape[0] - 1)
- for i in range(0, cluster_count):
- centers[i] = data.data[int(centers_indices[i])]
- for iteration in range(0, iteration_count):
- # распределение точек по кластерам
- clusters = list()
- for i in range(0, cluster_count):
- clusters.append(list())
- for row in data.data:
- nearest_cluster = find_nearest_center(centers, row)
- clusters[nearest_cluster].append(row)
- #print(clusters)
- # пересчёт центров кластеров
- for cl in range(0, cluster_count):
- sums = np.zeros(4)
- n = 0
- for row in clusters[cl]:
- for i in range(0, 4):
- sums[i] += row[i]
- n += 1
- for i in range(0, 4):
- centers[cl] = sums / n
- # вычисление среднего
- Q = 0
- for cluster_index in range(len(clusters)):
- if len(clusters[cluster_index]) == 0:
- continue
- s = 0.0
- for point in clusters[cluster_index]:
- s += dist(point, centers[cluster_index])
- Q += s / len(clusters[cluster_index])
- x[roll] = roll + 1
- y[roll] = Q
- color[roll] = Q
- if Q < best_Q or best_Q == -1:
- best_centers = centers
- best_Q = Q
- print(f"The best Q for {cluster_count} clusters = {best_Q}")
- for i in range(len(color)):
- if color[i] != best_Q:
- color[i] = 0
- else:
- color[i] = 1
- plt.scatter(x, y, c=color)
- plt.show()
- data_x = np.zeros(150)
- data_y = np.zeros(150)
- for i in range(150):
- cluster_ids[i] = find_nearest_center(best_centers, data.data[i])
- data_x[i] = data.data[i][1]
- data_y[i] = data.data[i][3]
- plt.scatter(data_x, data_y, c=cluster_ids)
- plt.show()
- print("------------------------------------------------------------")
- #return best_Q
- for i in range(4):
- clusterize(2 + i, 50, 25)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement