Форум программистов, компьютерный форум, киберфорум
Python: Решение задач
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 14.12.2021
Сообщений: 9

Метод K-means

27.05.2022, 12:27. Показов 2247. Ответов 8

Студворк — интернет-сервис помощи студентам
Всем привет!
У меня есть реализация алгоритма k-means. Но мне нужно в коде представить сложность алгоритма. Сделал просто расчет времени выполнения проги, но это не оно. В общем видел, что сложность метода k-средних определяется как: О(n) O(n^2) O(logn). И все-таки не могу понять, как мне его посчитать.

Вот сам код алгоритма:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import numpy as np
import math as mt
import matplotlib.pyplot as plt
import random as ran
import time
start_time = time.time()
 
# генерируем точки
mas = []
for q in range(0, 9):
    a = [ran.randint(1, 4) for i in range(0, 2)]
    mas.append(a)
# генерируем центры
k1 = [ran.randint(1, 4) for i in range(0, 2)]
k2 = [ran.randint(1, 4) for i in range(0, 2)]
 
dist = np.empty((15, 4), dtype=object)  # создаем пустой массив
mis = 0  # ошибка
mists = []  # список всех ошибок (пустой)
 
for i in range(5):  # внешний цикл расчетов
    counter1, counter2 = 0, 0
    curr_k1, curr_k2 = [0, 0], [0, 0]
    for j in range(len(mas)):  # внутренний цикл расчетов
        p = mas[j]  # выбираем первую точку
        distance_k1 = round(mt.fabs((k1[0] - p[0]) + (k1[1] - p[1])), 2)  # расстояние от первого цетра
        distance_k2 = round(mt.fabs((k2[0] - p[0]) + (k2[1] - p[1])), 2)  # расстояние от второго цетра
 
        if distance_k1 > distance_k2:  # узнаем к какому цетру точка ближе
            dist[j, 0] = mas[j][0]
            dist[j, 1] = mas[j][1]
            dist[j, 2] = distance_k2
            dist[j, 3] = 2
        else:
            dist[j, 0] = mas[j][0]
            dist[j, 1] = mas[j][1]
            dist[j, 2] = distance_k1
            dist[j, 3] = 1
        mis += dist[j, 2]**2  # находим ошибку
        mis = round(mis, 2)  # округляем ошибку
 
        if dist[j, 3] == 1:  # просматриваем точки и накапливаем нужный "counter"
            curr_k1[0] += dist[j, 0]
            curr_k1[1] += dist[j, 1]
            counter1 += 1
        else:
            curr_k2[0] += dist[j, 0]
            curr_k2[1] += dist[j, 1]
            counter2 += 1
    mists.append(mis)  # записываем ошибки в список
    n = (mists[i] - mists[i - 1]) / mists[0]  # рассчитываем ошибку на текущей итерации
    if n < 0.1 and i > 1:  # если ошибка менялась незначительно - перестаем перемещать центры
        break
    if counter1 == 0:
        counter1 = 1
    if counter2 == 0:
        counter2 = 1
    # изменяем координаты центров, исходя из точек, которые пренадлежат данному кластеру
    k1[0] = curr_k1[0] / counter1
    k1[1] = curr_k1[1] / counter1
    k2[0] = curr_k2[0] / counter2
    k2[1] = curr_k2[1] / counter2
 
 
# создаем график
x = []
y = []
for p in range(len(mas)):  # цикл наполнения списков координатами точек
    pointx = mas[p][0]
    pointy = mas[p][1]
    x.append(pointx)
    y.append(pointy)
 
# изменяем внешний вид графика
fig = plt.figure()
ax = fig.add_subplot(111)
ax.patch.set_facecolor('black')
ax.set_title('Кластеризация (k-means)', fontsize=16, fontweight="bold")
for m in range(len(mas)):  # цикл вывода точек
    if dist[m][3] == 1:
        point1 = plt.scatter(x[m], y[m], c='g')
    else:
        point2 = plt.scatter(x[m], y[m], c='y')
# центры кластеров
plt.scatter(k1[0], k1[1], c='g', marker='*')
plt.scatter(k2[0], k2[1], c='y', marker='*')
plt.xlabel("Ось X", fontsize=14)
plt.ylabel("Ось Y", fontsize=14)
plt.legend((point1, point2), ['Первый кластер', 'Второй кластер'], bbox_to_anchor=(1.4, 1), facecolor='lightblue', shadow=True)
plt.text(k1[0]-0.2, k1[1]-0.2, "Центр 1", color = 'white')
plt.text(k2[0]-0.2, k2[1]-0.2, "Центр 2", color = 'white')
plt.show()
 
 
print('Первый центр= ', k1)
print('Второй центр= ', k2)
 
print("--- %s seconds ---" % (time.time() - start_time))
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.05.2022, 12:27
Ответы с готовыми решениями:

Кластеризация k-means
Здравствуйте, у меня есть задание, где нужно дописать код. Строки которые я дописал отмечены соответственно. Но у меня программа...

Кластеризация k-means
Помогите сделать так, чтобы сначала определялись центры кластеров,а затем рандомное создание точек вокруг этих кластеров. Вот так примерно...

Проблемы с реализацией алгоритма кластеризации k-means
При выполнении следующего кода выводится ошибка: IndexError: index 4708 is out of bounds for axis 0 with size 15 При этом индекс каждый...

8
Эксперт Python
 Аватар для Red white socks
4523 / 1899 / 336
Регистрация: 18.01.2021
Сообщений: 3,489
27.05.2022, 12:58
Цитата Сообщение от aandrew1 Посмотреть сообщение
В общем видел, что сложность метода k-средних определяется как: О(n) O(n^2) O(logn).
Где вы, интересно, это видели? Возможно сама запись этого выражения и не является неправильной , но точно безграмотной.
Да и по смыслу оно явно ошибочно.
0
0 / 0 / 0
Регистрация: 14.12.2021
Сообщений: 9
27.05.2022, 14:34  [ТС]
Хорошо, а есть ли у вас какие-то предложения?
0
2739 / 1665 / 267
Регистрация: 19.02.2010
Сообщений: 4,405
27.05.2022, 15:12
Лучший ответ Сообщение было отмечено aandrew1 как решение

Решение

aandrew1, O(NDkm), где N - число векторов данных (точек выборки), D - размерность векторов данных, k - число кластеров, m - число итераций алгоритма по всей выборке данных.

Значение m может на практике оказываться меньше, чем задаваемое юзером число (если, например, юзер задал m=100 в качестве верхнего предела числа итераций, а положения кластеров перестали меняться после десятой итерации - то прога может прекратить расчёт, ибо дальнейшая работа будет бесполезной (не будет изменять положений кластеров и распределений точек данных по кластерам)).

Цитата Сообщение от aandrew1 Посмотреть сообщение
У меня есть реализация алгоритма k-means.
Выброси эту хрень.
Там, например, в строках 26-27 вычисляемое "расстояние" между точками - не является каким-либо из известных/классических расстояний (евклидово, манхэттенское,..), да и не является метрикой вообще.
1
0 / 0 / 0
Регистрация: 14.12.2021
Сообщений: 9
27.05.2022, 17:32  [ТС]
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
O(NDkm), где N - число векторов данных (точек выборки), D - размерность векторов данных, k - число кластеров, m - число итераций алгоритма по всей выборке данных.
Спасибо за инфу, полезно!

Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
не является каким-либо из известных/классических расстояний (евклидово, манхэттенское,..)
Как это не является? Я же ее не с воздуха взял)) Это и есть метрика Манхэттена: Название: изображение_2022-05-27_173044829.png
Просмотров: 72

Размер: 2.3 Кб
0
2739 / 1665 / 267
Регистрация: 19.02.2010
Сообщений: 4,405
27.05.2022, 19:04
Цитата Сообщение от aandrew1 Посмотреть сообщение
Как это не является?
Именно не является. Код не соответствует формуле.
Конкретно - операцию взятия модуля нельзя выносить за знак суммы.
0
0 / 0 / 0
Регистрация: 14.12.2021
Сообщений: 9
28.05.2022, 19:47  [ТС]
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
O(NDkm), где N - число векторов данных (точек выборки), D - размерность векторов данных, k - число кластеров, m - число итераций алгоритма по всей выборке данных.
Значение m может на практике оказываться меньше, чем задаваемое юзером число (если, например, юзер задал m=100 в качестве верхнего предела числа итераций, а положения кластеров перестали меняться после десятой итерации - то прога может прекратить расчёт, ибо дальнейшая работа будет бесполезной (не будет изменять положений кластеров и распределений точек данных по кластерам)).
Кстати, немного поискав, нашел еще вот такую вот формулу сложности, что скажете?
0
2739 / 1665 / 267
Регистрация: 19.02.2010
Сообщений: 4,405
29.05.2022, 00:49
Цитата Сообщение от aandrew1 Посмотреть сообщение
еще вот такую вот формулу сложности
"Верить в наше время нельзя никому, даже себе. Мне - можно." (С) группенфюрер Мюллер
0
0 / 0 / 0
Регистрация: 14.12.2021
Сообщений: 9
29.05.2022, 11:05  [ТС]
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
"Верить в наше время нельзя никому, даже себе. Мне - можно." (С) группенфюрер Мюллер
"Полное доверие граничит с безумием." Нелюбимый (Loveless)

Спасибо большое за ваши ответы!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.05.2022, 11:05
Помогаю со студенческими работами здесь

Метод k-means на языке R
Добрый день! Делаю кластеризацию, но метод k-means не работает с незаполненными полями в данных. При вызове этой команды summ.1 =...

Кластерный анализ. Метод k-means.
Доброе время суток! Помогите пожалуйста найти рабочую программную реализацию метода k-средних (для любых входных данных). Очень срочно...

C# С-MEANS
Привет Всем! Существует ли готовая библиотека С# с реализованным алгоритмом С-MEANS?

K-Means кластерация
Здравствуйте, уважаемые форумчане. Сам с Матлабом абсолютно незнаком, но срочно нужно сдать курсач. Смотрел программу - там все выполнено...

Fuzzy c-means
Необходимо выполнить кластеризацию картинки на 2 кластера с использованием алгоритма fuzzy c-means. Только начал работать в matlab. Можете...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru