Как лучше всего рассчитать трехмерный (или n-D) центроид?

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

centroid = average(x), average(y), average(z)

где x, y и z - массивы чисел с плавающей запятой. Кажется, я припоминаю, что есть способ получить более точный центроид, но я не нашел для этого простого алгоритма. У кого-нибудь есть идеи или предложения? Я использую для этого Python, но могу адаптировать примеры из других языков.

Я считаю, что формулировка вашего вопроса может быть неоптимальной. Вы спрашиваете, как рассчитать центроид (и все говорили вам, что «вы все поняли правильно»), но то, что вы искали, может быть объемной центральной точкой, на которую влияет не количество точек выборки, а их распределение в пробел (как предлагается в ответе @ AlejoHausner).

Chris 13.06.2016 03:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
24
1
32 466
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Нет, это единственная формула для центроида набора точек. См. Википедию: http://en.wikipedia.org/wiki/Centroid

Ты получил это. Вы вычисляете центроид или средний вектор.

«Более точный центроид» Я считаю, что центроид определяется так, как вы его рассчитали, поэтому не может быть «более точного центроида».

вы можете использовать суммирование с повышенной точностью - суммирование Кахана - вы это имели в виду?

Нет, я не хочу получать более точную сумму перед усреднением, если вы это имеете в виду. Мне просто интересно, правильно ли я вычисляю центроид. Но спасибо - я даже не слышал об этом.

Marcel Levy 17.09.2008 03:14

Да, это правильная формула.

Если у вас много точек, вы можете использовать симметрию задачи (будь то цилиндрическая, сферическая, зеркальная). В противном случае вы можете взять статистику и усреднить случайное количество точек и получить небольшую ошибку.

В частности, среднее значение случайного подмножества точек представляет собой несмещенную оценку среднего значения всей группы.

Gregg Lind 22.03.2010 03:19

Потенциально более эффективно: если вы вычисляете это несколько раз, вы можете немного ускорить это, сохранив две постоянные переменные

N  # number of points
sums = dict(x=0,y=0,z=0)  # sums of the locations for each point

затем изменяя N и суммы всякий раз, когда точки создаются или уничтожаются. Это меняет значение с O (N) на O (1) для вычислений за счет увеличения объема работы каждый раз, когда точка создается, перемещается или уничтожается.

Вы неопределенно упоминаете «способ получить более точный центроид». Возможно, вы говорите о центроиде, на который не влияют выбросы. Например, доход домохозяйства средний в США, вероятно, очень высок, потому что небольшое количество богатых людей очень искажает среднее значение; они - «выбросы». По этой причине статистики используют вместо этого медиана. Один из способов получить медиану - отсортировать значения, а затем выбрать значение в середине списка.

Может быть, вы ищете что-то подобное, но для точек 2D или 3D. Проблема в том, что в 2D и выше вы не можете сортировать. Нет естественного порядка. Тем не менее, есть способы избавиться от выбросов.

Один из способов - найти выпуклый корпус точек. Выпуклая оболочка имеет все точки "вне" множества точек. Если вы сделаете это и выбросите точки, которые находятся на корпусе, вы выбросите выбросы, а оставшиеся точки дадут более "репрезентативный" центроид. Вы даже можете повторить этот процесс несколько раз, и результат будет похож на очистку лука. Фактически, это называется «шелушение выпуклой оболочки».

Итак, если я правильно понимаю, если центроид подобен среднему значению линейного набора, дает ли выпуклое отслаивание корпуса вам точку, аналогичную медиане?

Marcel Levy 18.09.2008 03:37

Вы хотите сказать, что нельзя просто отсортировать каждое измерение отдельно и использовать что-то другое, кроме среднего?

Chris 13.06.2016 03:47
Ответ принят как подходящий

Вопреки распространенному здесь рефрену, существуют разные способы определения (и вычисления) центра облака точек. Первое и наиболее распространенное решение уже было предложено вами, и я буду возражать нет, что в этом нет ничего плохого:

centroid = average(x), average(y), average(z)

«Проблема» здесь в том, что он будет «искажать» вашу центральную точку в зависимости от распределения ваших точек. Если, например, вы предполагаете, что все ваши точки находятся внутри кубической рамки или какой-либо другой геометрической формы, но большинство из них находится в верхней половине, ваша центральная точка также сместится в этом направлении.

В качестве альтернативы вы можете использовать математическую середину (среднее значение экстремумов) в каждом измерении, чтобы избежать этого:

middle = middle(x), middle(y), middle(z)

Вы можете использовать это, когда вас не заботит количество точек, а больше - глобальная ограничивающая рамка, потому что это все - центр ограничительной рамки вокруг ваших точек.

Наконец, вы также можете использовать median (элемент посередине) в каждом измерении:

median = median(x), median(y), median(z)

Теперь это будет как бы делать противоположное middle и фактически поможет вам игнорировать выбросы в вашем облаке точек и найти центральную точку на основе распределения ваших точек.

Более надежный способ найти «хорошую» центральную точку может заключаться в игнорировании верхних и нижних 10% в каждом измерении, а затем вычислении average или median. Как видите, центральную точку можно определить по-разному. Ниже я показываю вам примеры двух 2D облаков точек с учетом этих предложений.

Темно-синяя точка - средний (средний) центроид. Медиана показана зеленым цветом. А середина показана красным. На втором изображении вы увидите именно то, о чем я говорил ранее: зеленая точка находится «ближе» к самой плотной части облака точек, а красная точка находится дальше от нее, с учетом самых крайних границ облака точек. облако точек.

Если ваш вектор n-мерный находится в списке [[a0, a1, ..., an], [b0, b1, ..., bn], [c0, c1, ..., cn]], просто преобразуйте список в массив, а затем вычислите центроид следующим образом:

import numpy as np

vectors = np.array(Listv)
centroid = np.mean(vectors, axis=0)

Другие вопросы по теме